Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(639)

Side by Side Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerDocument.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.compositor.layouts;
6
7 import android.annotation.TargetApi;
8 import android.content.Context;
9 import android.graphics.RectF;
10 import android.os.Build;
11 import android.util.SparseArray;
12 import android.view.MotionEvent;
13 import android.view.ViewGroup;
14
15 import org.chromium.chrome.browser.ChromeMobileApplication;
16 import org.chromium.chrome.browser.Tab;
17 import org.chromium.chrome.browser.UrlConstants;
18 import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.Context ualSearchPanel;
19 import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
20 import org.chromium.chrome.browser.compositor.layouts.components.VirtualView;
21 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
22 import org.chromium.chrome.browser.compositor.layouts.eventfilter.CascadeEventFi lter;
23 import org.chromium.chrome.browser.compositor.layouts.eventfilter.ContextualSear chEventFilter;
24 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeEvent Filter;
25 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeEvent Filter.ScrollDirection;
26 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandl er;
27 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EmptyEdgeSwipe Handler;
28 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter;
29 import org.chromium.chrome.browser.compositor.layouts.eventfilter.GestureHandler ;
30 import org.chromium.chrome.browser.compositor.layouts.phone.ContextualSearchLayo ut;
31 import org.chromium.chrome.browser.compositor.overlays.SceneOverlay;
32 import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDe legate;
33 import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager.Cont extualSearchContentViewDelegate;
34 import org.chromium.chrome.browser.contextualsearch.ContextualSearchStaticEventF ilter;
35 import org.chromium.chrome.browser.contextualsearch.ContextualSearchStaticEventF ilter.ContextualSearchTapHandler;
36 import org.chromium.chrome.browser.device.DeviceClassManager;
37 import org.chromium.chrome.browser.dom_distiller.ReaderModeEdgeSwipeHandler;
38 import org.chromium.chrome.browser.dom_distiller.ReaderModePanel;
39 import org.chromium.chrome.browser.dom_distiller.ReaderModeStaticEventFilter;
40 import org.chromium.chrome.browser.dom_distiller.ReaderModeStaticEventFilter.Rea derModePanelSelector;
41 import org.chromium.chrome.browser.dom_distiller.ReaderModeStaticEventFilter.Rea derModeTapHandler;
42 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
43 import org.chromium.chrome.browser.tab.ChromeTab;
44 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
45 import org.chromium.chrome.browser.tabmodel.TabModel;
46 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
47 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
48 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
49 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelSelector;
50 import org.chromium.chrome.browser.util.FeatureUtilities;
51 import org.chromium.content.browser.ContentViewCore;
52 import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
53
54 import java.util.List;
55
56 /**
57 * A {@link Layout} controller for a simple document use case. This class is re sponsible for
58 * driving all {@link Layout}s that get shown via the {@link LayoutManager}.
59 */
60 public class LayoutManagerDocument extends LayoutManager
61 implements ContextualSearchTapHandler, ContextualSearchContentViewDelega te,
62 ReaderModeTapHandler {
63 // Layouts
64 /** A {@link Layout} used for showing a normal web page. */
65 protected final StaticLayout mStaticLayout;
66 /** A {@link Layout} used for when the contextual search panel is up. */
67 protected final ContextualSearchLayout mContextualSearchLayout;
68
69 // Event Filters
70 private final EdgeSwipeEventFilter mStaticEdgeEventFilter;
71 private final ContextualSearchEventFilter mContextualSearchEventFilter;
72 private final EdgeSwipeHandler mToolbarSwipeHandler;
73
74 // Event Filter Handlers
75 /** A {@link GestureHandler} that will delegate all events to {@link #getAct iveLayout()}. */
76 protected final GestureHandler mGestureHandler;
77 private final EdgeSwipeHandler mContextualSearchEdgeSwipeHandler;
78 private final EdgeSwipeHandler mReaderModeEdgeSwipeHandler;
79
80 // Internal State
81 private final SparseArray<LayoutTab> mTabCache = new SparseArray<LayoutTab>( );
82 private final ContextualSearchPanel mContextualSearchPanel;
83 /** A delegate for interacting with the Contextual Search manager. */
84 protected ContextualSearchManagementDelegate mContextualSearchDelegate;
85
86 @SuppressWarnings("unused") private TabModelSelectorTabObserver mTabModelSel ectorTabObserver;
87 private final ReaderModePanelSelector mReaderModePanelSelector;
88
89 /**
90 * Creates a {@link LayoutManagerDocument} instance.
91 * @param host A {@link LayoutManagerHost} instance.
92 */
93 public LayoutManagerDocument(LayoutManagerHost host) {
94 super(host);
95 Context context = host.getContext();
96 LayoutRenderHost renderHost = host.getLayoutRenderHost();
97
98 mContextualSearchPanel = new ContextualSearchPanel(context, this);
99
100 mReaderModePanelSelector = new ReaderModePanelSelector() {
101 @Override
102 public ReaderModePanel getActiveReaderModePanel() {
103 if (mStaticLayout == null || !mStaticLayout.isActive()) return n ull;
104 return mStaticLayout.getReaderModePanel();
105 }
106 };
107
108 // Build Event Filter Handlers
109 mContextualSearchEdgeSwipeHandler = new ContextualSearchEdgeSwipeHandler (this);
110 mReaderModeEdgeSwipeHandler = new ReaderModeEdgeSwipeHandler(
111 mReaderModePanelSelector, this);
112 mGestureHandler = new GestureHandlerLayoutDelegate(this);
113 mToolbarSwipeHandler = new ToolbarSwipeHandler(this);
114
115 // Build Event Filters
116 mStaticEdgeEventFilter =
117 new EdgeSwipeEventFilter(context, this, new StaticEdgeSwipeHandl er());
118 mContextualSearchEventFilter = new ContextualSearchEventFilter(
119 context, this, mGestureHandler, mContextualSearchPanel);
120 EventFilter contextualSearchStaticEventFilter = new ContextualSearchStat icEventFilter(
121 context, this, mContextualSearchPanel, mContextualSearchEdgeSwip eHandler, this);
122 EventFilter readerModeStaticEventFilter = new ReaderModeStaticEventFilte r(
123 context, this, mReaderModePanelSelector, mReaderModeEdgeSwipeHan dler, this);
124 EventFilter staticCascadeEventFilter = new CascadeEventFilter(context, t his,
125 new EventFilter[] {readerModeStaticEventFilter, contextualSearch StaticEventFilter,
126 mStaticEdgeEventFilter});
127
128 // Build Layouts
129 mStaticLayout = new StaticLayout(
130 context, this, renderHost, staticCascadeEventFilter, mContextual SearchPanel);
131 mContextualSearchLayout = new ContextualSearchLayout(
132 context, this, renderHost, mContextualSearchEventFilter, mContex tualSearchPanel);
133
134 // Set up layout parameters
135 mStaticLayout.setLayoutHandlesTabLifecycles(true);
136
137 setNextLayout(null);
138 }
139
140 @Override
141 public void init(TabModelSelector selector, TabCreatorManager creator,
142 TabContentManager content, ViewGroup androidContentContainer,
143 ContextualSearchManagementDelegate contextualSearchDelegate,
144 DynamicResourceLoader dynamicResourceLoader) {
145 // Save state
146 mContextualSearchDelegate = contextualSearchDelegate;
147
148 // Initialize Event Filters
149 mStaticEdgeEventFilter.setTabModelSelector(selector);
150 mContextualSearchEventFilter.setManagementDelegate(contextualSearchDeleg ate);
151
152 // Initialize Layouts
153 mStaticLayout.setTabModelSelector(selector, content);
154 mContextualSearchLayout.setTabModelSelector(selector, content);
155
156 // Initialize Contextual Search Panel
157 mContextualSearchPanel.setManagementDelegate(contextualSearchDelegate);
158 mContextualSearchPanel.setDynamicResourceLoader(dynamicResourceLoader);
159
160 // Set back flow communication
161 if (contextualSearchDelegate != null) {
162 contextualSearchDelegate.setContextualSearchPanelDelegate(mContextua lSearchPanel);
163 }
164
165 mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(selector) {
166 @Override
167 public void onContentChanged(Tab tab) {
168 initLayoutTabFromHost(tab.getId());
169 }
170
171 @Override
172 public void onBackgroundColorChanged(Tab tab, int color) {
173 initLayoutTabFromHost(tab.getId());
174 }
175 };
176
177 super.init(selector, creator, content, androidContentContainer, contextu alSearchDelegate,
178 dynamicResourceLoader);
179 }
180
181 @Override
182 public void destroy() {
183 super.destroy();
184
185 if (mStaticLayout != null) mStaticLayout.destroy();
186 if (mContextualSearchLayout != null) mContextualSearchLayout.destroy();
187 if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.d estroy();
188 }
189
190 @Override
191 public void getVirtualViews(List<VirtualView> views) {
192 // Nothing to do here yet.
193 }
194
195 @Override
196 protected void onViewportChanged(RectF viewportDp) {
197 super.onViewportChanged(viewportDp);
198 for (int i = 0; i < mTabCache.size(); i++) {
199 // This assumes that the content width/height is always the size of the host.
200 mTabCache.valueAt(i).setContentSize(viewportDp.width(), viewportDp.h eight());
201 }
202 }
203
204 /**
205 * @return The {@link EdgeSwipeHandler} responsible for processing swipe eve nts for the toolbar.
206 */
207 @Override
208 public EdgeSwipeHandler getTopSwipeHandler() {
209 return mToolbarSwipeHandler;
210 }
211
212 /**
213 * Clears all content associated with {@code tabId} from the internal caches .
214 * @param tabId The id of the tab to clear.
215 */
216 protected void emptyCachesExcept(int tabId) {
217 LayoutTab tab = mTabCache.get(tabId);
218 mTabCache.clear();
219 if (tab != null) mTabCache.put(tabId, tab);
220 }
221
222 /**
223 * Adds the {@link SceneOverlay} across all {@link Layout}s owned by this cl ass.
224 * @param helper A {@link SceneOverlay} instance.
225 */
226 protected void addGlobalSceneOverlay(SceneOverlay helper) {
227 mStaticLayout.addSceneOverlay(helper);
228 mContextualSearchLayout.addSceneOverlay(helper);
229 }
230
231 /**
232 * @param tabId The id of the tab represented by a {@link LayoutTab}.
233 * @return A {@link LayoutTab} if one exists or {@code null} if none ca n be found.
234 */
235 protected LayoutTab getExistingLayoutTab(int tabId) {
236 return mTabCache.get(tabId);
237 }
238
239 @Override
240 protected Layout getDefaultLayout() {
241 return mStaticLayout;
242 }
243
244 @Override
245 public void initLayoutTabFromHost(final int tabId) {
246 if (getTabModelSelector() == null || getActiveLayout() == null) return;
247
248 TabModelSelector selector = getTabModelSelector();
249 ChromeTab tab = ChromeTab.fromTab(selector.getTabById(tabId));
250 if (tab == null) return;
251
252 LayoutTab layoutTab = mTabCache.get(tabId);
253 if (layoutTab == null) return;
254
255 String url = tab.getUrl();
256 boolean isNativePage = url != null && url.startsWith(UrlConstants.CHROME _NATIVE_SCHEME);
257 boolean canUseLiveTexture =
258 tab.getContentViewCore() != null && !tab.isShowingSadTab() && !i sNativePage;
259 layoutTab.initFromHost(tab.getBackgroundColor(), tab.getFallbackTextureI d(),
260 tab.shouldStall(), canUseLiveTexture);
261
262 mHost.requestRender();
263 }
264
265 @Override
266 public LayoutTab createLayoutTab(int id, boolean incognito, boolean showClos eButton,
267 boolean isTitleNeeded, float maxContentWidth, float maxContentHeight ) {
268 LayoutTab tab = mTabCache.get(id);
269 if (tab == null) {
270 tab = new LayoutTab(id, incognito, mLastContentWidthDp, mLastContent HeightDp,
271 showCloseButton, isTitleNeeded);
272 mTabCache.put(id, tab);
273 } else {
274 tab.init(mLastContentWidthDp, mLastContentHeightDp, showCloseButton, isTitleNeeded);
275 }
276 if (maxContentWidth > 0.f) tab.setMaxContentWidth(maxContentWidth);
277 if (maxContentHeight > 0.f) tab.setMaxContentHeight(maxContentHeight);
278
279 return tab;
280 }
281
282 @Override
283 public void releaseTabLayout(int id) {
284 mTabCache.remove(id);
285 }
286
287 @Override
288 public boolean onInterceptTouchEvent(MotionEvent e, boolean isKeyboardShowin g) {
289 boolean intercepted = super.onInterceptTouchEvent(e, isKeyboardShowing);
290 if (intercepted) getActiveLayout().unstallImmediately();
291 return intercepted;
292 }
293
294 /**
295 * Should be called when the user presses the back button on the phone.
296 * @return Whether or not the back button was consumed by the active {@link Layout}.
297 */
298 @Override
299 public boolean onBackPressed() {
300 return getActiveLayout() != null && getActiveLayout().onBackPressed();
301 }
302
303 @Override
304 public void handleTapContextualSearchBar(long time, float x, float y) {
305 if (getActiveLayout() == mContextualSearchLayout) return;
306 if (mContextualSearchDelegate == null) return;
307
308 // When not in compatibility mode, tapping on the Search Bar will expand the Panel,
309 // therefore we must start showing the ContextualSearchLayout.
310 // TODO(pedrosimonetti): once we implement the close button, a tap in th e Panel might
311 // trigger the Panel to close, not expand, so in that case we don't want to show the
312 // ContextualSearchLayout. Coordinate with dtrainor@ to solve this. It m ight be
313 // necessary for the ContextualSearchPanel to be able to trigger the dis play of the
314 // ContextualSearchLayout.
315 if (!mContextualSearchDelegate.isRunningInCompatibilityMode()) {
316 showContextualSearchLayout(true);
317 }
318
319 mContextualSearchPanel.handleClick(time, x, y);
320 }
321
322 @Override
323 public void setContextualSearchContentViewCore(ContentViewCore contentViewCo re) {
324 mHost.onContentViewCoreAdded(contentViewCore);
325 }
326
327 @Override
328 public void releaseContextualSearchContentViewCore() {
329 if (getTabModelSelector() == null) return;
330 Tab tab = getTabModelSelector().getCurrentTab();
331 if (tab != null) tab.updateFullscreenEnabledState();
332 }
333
334 private void showContextualSearchLayout(boolean animate) {
335 mContextualSearchDelegate.preserveBasePageSelectionOnNextLossOfFocus();
336 startShowing(mContextualSearchLayout, animate);
337 }
338
339 private class StaticEdgeSwipeHandler extends EmptyEdgeSwipeHandler {
340 @Override
341 public void swipeStarted(ScrollDirection direction, float x, float y) {
342 }
343
344 @Override
345 public boolean isSwipeEnabled(ScrollDirection direction) {
346 FullscreenManager fullscreenManager = mHost.getFullscreenManager();
347 return direction == ScrollDirection.DOWN && fullscreenManager != nul l
348 && fullscreenManager.getPersistentFullscreenMode();
349 }
350 }
351
352 private class ContextualSearchEdgeSwipeHandler extends EdgeSwipeHandlerLayou tDelegate {
353 public ContextualSearchEdgeSwipeHandler(LayoutProvider provider) {
354 super(provider);
355 }
356
357 @Override
358 public void swipeStarted(ScrollDirection direction, float x, float y) {
359 if (isCompatabilityMode()) {
360 mContextualSearchDelegate.openResolvedSearchUrlInNewTab();
361 return;
362 }
363
364 if (getActiveLayout() != mContextualSearchLayout) {
365 showContextualSearchLayout(false);
366 }
367
368 super.swipeStarted(direction, x, y);
369 }
370
371 @Override
372 public boolean isSwipeEnabled(ScrollDirection direction) {
373 return direction == ScrollDirection.UP && mContextualSearchDelegate != null;
374 }
375
376 private boolean isCompatabilityMode() {
377 return mContextualSearchDelegate != null
378 && mContextualSearchDelegate.isRunningInCompatibilityMode();
379 }
380 }
381
382 /**
383 * A {@link EdgeSwipeHandler} meant to respond to edge events for the toolba r.
384 */
385 private class ToolbarSwipeHandler extends EdgeSwipeHandlerLayoutDelegate {
386 private ScrollDirection mLastScroll;
387
388 /**
389 * Creates an instance of the {@link ToolbarSwipeHandler}.
390 * @param provider A {@link LayoutProvider} instance.
391 */
392 public ToolbarSwipeHandler(LayoutProvider provider) {
393 super(provider);
394 }
395
396 @Override
397 public void swipeStarted(ScrollDirection direction, float x, float y) {
398 super.swipeStarted(direction, x, y);
399 mLastScroll = direction;
400 }
401
402 @Override
403 public void swipeFinished() {
404 super.swipeFinished();
405 changeTabs();
406 }
407
408 @Override
409 public void swipeFlingOccurred(float x, float y, float tx, float ty, flo at vx, float vy) {
410 super.swipeFlingOccurred(x, y, tx, ty, vx, vy);
411 changeTabs();
412 }
413
414 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
415 private void changeTabs() {
416 DocumentTabModelSelector selector =
417 ChromeMobileApplication.getDocumentTabModelSelector();
418 TabModel tabModel = selector.getCurrentModel();
419 int currentIndex = tabModel.index();
420 if (mLastScroll == ScrollDirection.LEFT) {
421 if (currentIndex < tabModel.getCount() - 1) {
422 TabModelUtils.setIndex(tabModel, currentIndex + 1);
423 }
424 } else {
425 if (currentIndex > 0) {
426 TabModelUtils.setIndex(tabModel, currentIndex - 1);
427 }
428 }
429 }
430
431 @Override
432 public boolean isSwipeEnabled(ScrollDirection direction) {
433 FullscreenManager manager = mHost.getFullscreenManager();
434 if (getActiveLayout() != mStaticLayout
435 || !DeviceClassManager.enableToolbarSwipe(
436 FeatureUtilities.isDocumentMode(mHost.getContext( )))
437 || (manager != null && manager.getPersistentFullscreenMode() )) {
438 return false;
439 }
440
441 return direction == ScrollDirection.LEFT || direction == ScrollDirec tion.RIGHT;
442 }
443 }
444
445 @Override
446 public void handleTapReaderModeBar(long time, float x, float y) {
447 ReaderModePanel activePanel = mReaderModePanelSelector.getActiveReaderMo dePanel();
448 if (activePanel != null) activePanel.handleClick(time, x, y);
449 }
450 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698