Skip to content

Commit

Permalink
[Duplex] Add composited bottom toolbar
Browse files Browse the repository at this point in the history
This change adds a composited version of the bottom toolbar. The layer
is not specific to the bottom sheet and can be used for any bottom UI.
The layer is not added to the hierarchy in this patch.

BUG=815324

Change-Id: I309f392c975ed7099aaf7562461625bd7c886a2d
Reviewed-on: https://chromium-review.googlesource.com/935742
Commit-Queue: Matthew Jones <mdjones@chromium.org>
Reviewed-by: Theresa <twellington@chromium.org>
Reviewed-by: David Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543153}
  • Loading branch information
iotitan authored and Commit Bot committed Mar 14, 2018
1 parent cf1d64f commit d598527
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 0 deletions.
1 change: 1 addition & 0 deletions chrome/android/java/res/layout/bottom_sheet.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
android:visibility="invisible" />

<FrameLayout
android:id="@+id/bottom_sheet_control_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/bottom_control_container_height" >
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.compositor.scene_layer;

import android.graphics.RectF;

import org.chromium.base.annotations.JNINamespace;
import org.chromium.chrome.browser.compositor.LayerTitleCache;
import org.chromium.chrome.browser.compositor.layouts.components.VirtualView;
import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter;
import org.chromium.chrome.browser.compositor.overlays.SceneOverlay;
import org.chromium.chrome.browser.widget.ViewResourceFrameLayout;
import org.chromium.ui.resources.ResourceManager;

import java.util.List;

/**
* A composited view that sits at the bottom of the screen and listens to changes in the browser
* controls. When visible, the view will mimic the behavior of the top browser controls when
* scrolling.
*/
@JNINamespace("android")
public class ScrollingBottomViewSceneLayer extends SceneOverlayLayer implements SceneOverlay {
/** Handle to the native side of this class. */
private long mNativePtr;

/** The resource ID used to reference the view bitmap in native. */
private int mResourceId;

/** The height of the view's top shadow. */
private int mTopShadowHeightPx;

/** The current offset of the bottom view in px. */
private int mCurrentOffsetPx;

/**
* Build a composited bottom view layer.
* @param resourceManager A resource manager for dynamic resource creation.
* @param bottomView The view used to generate the composited version.
* @param topShadowHeightPx The height of the shadow on the top of the view in px if it exists.
*/
public ScrollingBottomViewSceneLayer(ResourceManager resourceManager,
ViewResourceFrameLayout bottomView, int topShadowHeightPx) {
mResourceId = bottomView.getId();
mTopShadowHeightPx = topShadowHeightPx;
resourceManager.getDynamicResourceLoader().registerResource(
mResourceId, bottomView.getResourceAdapter());
}

/**
* Set the view's offset from the bottom of the screen in px. An offset of 0 means the view is
* completely visible. An increasing offset will move the view down.
* @param offsetPx The view's offset in px.
*/
public void setYOffset(int offsetPx) {
mCurrentOffsetPx = offsetPx;
}

@Override
protected void initializeNative() {
if (mNativePtr == 0) {
mNativePtr = nativeInit();
}
assert mNativePtr != 0;
}

@Override
public void setContentTree(SceneLayer contentTree) {
nativeSetContentTree(mNativePtr, contentTree);
}

@Override
public SceneOverlayLayer getUpdatedSceneOverlayTree(RectF viewport, RectF visibleViewport,
LayerTitleCache layerTitleCache, ResourceManager resourceManager, float yOffset) {
nativeUpdateScrollingBottomViewLayer(mNativePtr, resourceManager, mResourceId,
mTopShadowHeightPx, viewport.height() + mCurrentOffsetPx, mCurrentOffsetPx > 0);

return this;
}

@Override
public boolean isSceneOverlayTreeShowing() {
return true;
}

@Override
public EventFilter getEventFilter() {
return null;
}

@Override
public boolean shouldHideAndroidBrowserControls() {
return false;
}

@Override
public boolean updateOverlay(long time, long dt) {
return false;
}

@Override
public boolean onBackPressed() {
return false;
}

@Override
public boolean handlesTabCreating() {
return false;
}

@Override
public void onSizeChanged(
float width, float height, float visibleViewportOffsetY, int orientation) {}

@Override
public void onHideLayout() {}

@Override
public void getVirtualViews(List<VirtualView> views) {}

@Override
public void tabTitleChanged(int tabId, String title) {}

@Override
public void tabStateInitialized() {}

@Override
public void tabModelSwitched(boolean incognito) {}

@Override
public void tabSelected(long time, boolean incognito, int id, int prevId) {}

@Override
public void tabMoved(long time, boolean incognito, int id, int oldIndex, int newIndex) {}

@Override
public void tabClosed(long time, boolean incognito, int id) {}

@Override
public void tabClosureCancelled(long time, boolean incognito, int id) {}

@Override
public void tabCreated(long time, boolean incognito, int id, int prevId, boolean selected) {}

@Override
public void tabPageLoadStarted(int id, boolean incognito) {}

@Override
public void tabPageLoadFinished(int id, boolean incognito) {}

@Override
public void tabLoadStarted(int id, boolean incognito) {}

@Override
public void tabLoadFinished(int id, boolean incognito) {}

private native long nativeInit();
private native void nativeSetContentTree(
long nativeScrollingBottomViewSceneLayer, SceneLayer contentTree);
private native void nativeUpdateScrollingBottomViewLayer(
long nativeScrollingBottomViewSceneLayer, ResourceManager resourceManager,
int viewResourceId, int shadowHeightPx, float yOffset, boolean showShadow);
}
1 change: 1 addition & 0 deletions chrome/android/java_sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/SceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/SceneOverlayLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java",
Expand Down
3 changes: 3 additions & 0 deletions chrome/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1898,6 +1898,8 @@ jumbo_split_static_library("browser") {
"android/compositor/scene_layer/contextual_search_scene_layer.h",
"android/compositor/scene_layer/scene_layer.cc",
"android/compositor/scene_layer/scene_layer.h",
"android/compositor/scene_layer/scrolling_bottom_view_scene_layer.cc",
"android/compositor/scene_layer/scrolling_bottom_view_scene_layer.h",
"android/compositor/scene_layer/static_tab_scene_layer.cc",
"android/compositor/scene_layer/static_tab_scene_layer.h",
"android/compositor/scene_layer/tab_list_scene_layer.cc",
Expand Down Expand Up @@ -4222,6 +4224,7 @@ if (is_android) {
"../android/java/src/org/chromium/chrome/browser/compositor/resources/ResourceFactory.java",
"../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java",
"../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/SceneLayer.java",
"../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java",
"../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java",
"../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java",
"../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// 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/scrolling_bottom_view_scene_layer.h"

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "cc/layers/ui_resource_layer.h"
#include "content/public/browser/android/compositor.h"
#include "jni/ScrollingBottomViewSceneLayer_jni.h"
#include "ui/android/resources/resource_manager_impl.h"

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

namespace android {

ScrollingBottomViewSceneLayer::ScrollingBottomViewSceneLayer(
JNIEnv* env,
const JavaRef<jobject>& jobj)
: SceneLayer(env, jobj),
view_container_(cc::Layer::Create()),
view_layer_(cc::UIResourceLayer::Create()) {
layer()->SetIsDrawable(true);

view_container_->SetIsDrawable(true);
view_container_->SetMasksToBounds(true);

view_layer_->SetIsDrawable(true);
view_container_->AddChild(view_layer_);
}

ScrollingBottomViewSceneLayer::~ScrollingBottomViewSceneLayer() = default;

void ScrollingBottomViewSceneLayer::UpdateScrollingBottomViewLayer(
JNIEnv* env,
const JavaParamRef<jobject>& object,
const JavaParamRef<jobject>& jresource_manager,
jint view_resource_id,
jint shadow_height,
jfloat y_offset,
bool show_shadow) {
ui::ResourceManager* resource_manager =
ui::ResourceManagerImpl::FromJavaObject(jresource_manager);
ui::Resource* bottom_view_resource = resource_manager->GetResource(
ui::ANDROID_RESOURCE_TYPE_DYNAMIC, view_resource_id);

// If the resource isn't available, don't bother doing anything else.
if (!bottom_view_resource)
return;

view_layer_->SetUIResourceId(bottom_view_resource->ui_resource()->id());

int container_height = bottom_view_resource->size().height();
int texture_y_offset = 0;

// The view container layer's height depends on whether the shadow is
// showing. If the shadow should be clipped, reduce the height of the
// container.
if (!show_shadow) {
container_height -= shadow_height;
texture_y_offset -= shadow_height;
}

view_container_->SetBounds(
gfx::Size(bottom_view_resource->size().width(), container_height));
view_container_->SetPosition(gfx::PointF(0, y_offset - container_height));

// The view's layer should be the same size as the texture.
view_layer_->SetBounds(gfx::Size(bottom_view_resource->size().width(),
bottom_view_resource->size().height()));
view_layer_->SetPosition(gfx::PointF(0, texture_y_offset));
}

void ScrollingBottomViewSceneLayer::SetContentTree(
JNIEnv* env,
const JavaParamRef<jobject>& jobj,
const JavaParamRef<jobject>& jcontent_tree) {
SceneLayer* content_tree = FromJavaObject(env, jcontent_tree);
if (!content_tree || !content_tree->layer())
return;

if (!content_tree->layer()->parent() ||
(content_tree->layer()->parent()->id() != layer_->id())) {
layer_->AddChild(content_tree->layer());
layer_->AddChild(view_container_);
}
}

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

} // namespace android
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_SCROLLING_BOTTOM_VIEW_SCENE_LAYER_H_
#define CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_SCROLLING_BOTTOM_VIEW_SCENE_LAYER_H_

#include <memory>
#include <vector>

#include "base/android/jni_android.h"
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
#include "chrome/browser/android/compositor/scene_layer/scene_layer.h"
#include "ui/android/resources/resource_manager_impl.h"

namespace cc {
class Layer;
class UIResourceLayer;
} // namespace cc

namespace android {

class ScrollingBottomViewSceneLayer : public SceneLayer {
public:
ScrollingBottomViewSceneLayer(JNIEnv* env,
const base::android::JavaRef<jobject>& jobj);
~ScrollingBottomViewSceneLayer() override;

// Update the compositor version of the view.
void UpdateScrollingBottomViewLayer(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& object,
const base::android::JavaParamRef<jobject>& jresource_manager,
jint view_resource_id,
jint shadow_height,
jfloat y_offset,
bool show_shadow);

void SetContentTree(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj,
const base::android::JavaParamRef<jobject>& jcontent_tree);

private:
scoped_refptr<cc::Layer> view_container_;
scoped_refptr<cc::UIResourceLayer> view_layer_;

DISALLOW_COPY_AND_ASSIGN(ScrollingBottomViewSceneLayer);
};

} // namespace android

#endif // CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_SCROLLING_BOTTOM_VIEW_SCENE_LAYER_H_

0 comments on commit d598527

Please sign in to comment.