chromium/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.h"

#include <vector>

#include "cc/input/android/offset_tag_android.h"
#include "cc/slim/filter.h"
#include "cc/slim/layer.h"
#include "chrome/browser/android/compositor/layer/content_layer.h"
#include "chrome/browser/android/compositor/layer_title_cache.h"
#include "chrome/browser/android/compositor/tab_content_manager.h"
#include "components/viz/common/quads/offset_tag.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/android/resources/resource_manager_impl.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "chrome/android/chrome_jni_headers/StaticTabSceneLayer_jni.h"

using base::android::JavaParamRef;
using base::android::JavaRef;

namespace android {
namespace {

static bool LayerDraws(scoped_refptr<cc::slim::Layer> layer) {
  if (!layer.get() || layer->opacity() == 0.0f ||
      layer->hide_layer_and_subtree()) {
    return false;
  }

  if (layer->draws_content()) {
    return true;
  }

  for (const auto& child : layer->children()) {
    if (LayerDraws(child)) {
      return true;
    }
  }
  return false;
}

}  // namespace

StaticTabSceneLayer::StaticTabSceneLayer(JNIEnv* env,
                                         const JavaRef<jobject>& jobj)
    : SceneLayer(env, jobj),
      tab_content_manager_(nullptr),
      background_color_(SK_ColorWHITE) {}

StaticTabSceneLayer::~StaticTabSceneLayer() = default;

bool StaticTabSceneLayer::ShouldShowBackground() {
  scoped_refptr<cc::slim::Layer> root = layer_->RootLayer();
  return root && root->bounds() != layer_->bounds();
}

SkColor StaticTabSceneLayer::GetBackgroundColor() {
  return background_color_;
}

void StaticTabSceneLayer::UpdateTabLayer(
    JNIEnv* env,
    const JavaParamRef<jobject>& jobj,
    jint id,
    jboolean can_use_live_layer,
    jint default_background_color,
    jfloat x,
    jfloat y,
    jfloat static_to_view_blend,
    jfloat saturation,
    const JavaParamRef<jobject>& joffset_tag) {
  DCHECK(tab_content_manager_)
      << "TabContentManager must be set before updating the layer";

  background_color_ = default_background_color;
  if (!content_layer_.get()) {
    content_layer_ = android::ContentLayer::Create(tab_content_manager_);
    layer_->AddChild(content_layer_->layer());
  }
  if (id != -1 && can_use_live_layer) {
    // StaticLayout may not know that the live layer cannot draw. Ensure it gets
    // a thumbnail if needed.
    auto live_layer = tab_content_manager_->GetLiveLayer(id);
    if (live_layer) {
      live_layer->SetHideLayerAndSubtree(!can_use_live_layer);
      if (!LayerDraws(live_layer)) {
        std::vector<int> tab_ids = {id};
        tab_content_manager_->UpdateVisibleIds(tab_ids, id);
      }
    }
  }

  content_layer_->SetProperties(id, can_use_live_layer, static_to_view_blend,
                                false, 1.f, saturation, false, gfx::Rect());

  content_layer_->layer()->SetPosition(gfx::PointF(x, y));
  content_layer_->layer()->SetIsDrawable(true);

  viz::OffsetTag tag = cc::android::FromJavaOffsetTag(env, joffset_tag);
  content_layer_->layer()->SetOffsetTag(tag);
}

void StaticTabSceneLayer::SetTabContentManager(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& jobj,
    const base::android::JavaParamRef<jobject>& jtab_content_manager) {
  if (!tab_content_manager_) {
    tab_content_manager_ =
        TabContentManager::FromJavaObject(jtab_content_manager);
  }
}

static jlong JNI_StaticTabSceneLayer_Init(JNIEnv* env,
                                          const JavaParamRef<jobject>& jobj) {
  // This will automatically bind to the Java object and pass ownership there.
  StaticTabSceneLayer* scene_layer = new StaticTabSceneLayer(env, jobj);
  return reinterpret_cast<intptr_t>(scene_layer);
}

}  // namespace android