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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/document/DocumentActivity.java

Issue 2011433003: [Hera] Excise a bunch of document mode code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Deprecate histograms, clean up another unused one. Created 4 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.document; 5 package org.chromium.chrome.browser.document;
6 6
7 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
8 import android.content.Intent; 8 import android.content.Intent;
9 import android.graphics.Color;
10 import android.os.Build; 9 import android.os.Build;
11 import android.text.TextUtils; 10 import android.text.TextUtils;
12 import android.view.KeyEvent;
13 import android.view.Menu;
14 import android.view.View;
15 import android.view.View.OnClickListener;
16 import android.view.ViewGroup;
17 import android.view.Window;
18 11
19 import org.chromium.base.ActivityState;
20 import org.chromium.base.ApiCompatibilityUtils;
21 import org.chromium.base.ApplicationStatus;
22 import org.chromium.base.Log; 12 import org.chromium.base.Log;
23 import org.chromium.base.SysUtils;
24 import org.chromium.base.library_loader.LibraryLoader;
25 import org.chromium.base.metrics.RecordUserAction;
26 import org.chromium.chrome.R;
27 import org.chromium.chrome.browser.ActivityTabTaskDescriptionHelper;
28 import org.chromium.chrome.browser.ChromeActivity; 13 import org.chromium.chrome.browser.ChromeActivity;
29 import org.chromium.chrome.browser.ChromeApplication;
30 import org.chromium.chrome.browser.IntentHandler;
31 import org.chromium.chrome.browser.KeyboardShortcuts;
32 import org.chromium.chrome.browser.TabState;
33 import org.chromium.chrome.browser.UrlConstants;
34 import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
35 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChange Reason;
36 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerDocument;
37 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerDocumentTabSw itcher;
38 import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
39 import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.Overv iewModeObserver;
40 import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor;
41 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
42 import org.chromium.chrome.browser.metrics.StartupMetrics;
43 import org.chromium.chrome.browser.metrics.UmaUtils;
44 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
45 import org.chromium.chrome.browser.ntp.NewTabPage;
46 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
47 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
48 import org.chromium.chrome.browser.preferences.datareduction.DataReductionPromoS creen;
49 import org.chromium.chrome.browser.signin.SigninPromoUtil;
50 import org.chromium.chrome.browser.tab.EmptyTabObserver;
51 import org.chromium.chrome.browser.tab.Tab; 14 import org.chromium.chrome.browser.tab.Tab;
52 import org.chromium.chrome.browser.tab.TabUma.TabCreationState;
53 import org.chromium.chrome.browser.tabmodel.AsyncTabParams;
54 import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
55 import org.chromium.chrome.browser.tabmodel.SingleTabModelSelector;
56 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
57 import org.chromium.chrome.browser.tabmodel.TabReparentingParams;
58 import org.chromium.chrome.browser.tabmodel.document.ActivityDelegate; 15 import org.chromium.chrome.browser.tabmodel.document.ActivityDelegate;
59 import org.chromium.chrome.browser.tabmodel.document.AsyncTabCreationParams;
60 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModel;
61 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModel.Initializa tionObserver;
62 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelImpl;
63 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelSelector;
64 import org.chromium.chrome.browser.tabmodel.document.TabDelegate;
65 import org.chromium.chrome.browser.toolbar.ToolbarControlContainer;
66 import org.chromium.chrome.browser.util.FeatureUtilities;
67 import org.chromium.chrome.browser.util.IntentUtils;
68 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager;
69 import org.chromium.components.service_tab_launcher.ServiceTabLauncher;
70 import org.chromium.content_public.browser.LoadUrlParams;
71 import org.chromium.content_public.browser.NavigationEntry;
72 import org.chromium.content_public.browser.WebContents;
73 import org.chromium.ui.base.PageTransition;
74 16
75 /** 17 /**
76 * This is the main activity for Chrome while running in document mode. Each ac tivity 18 * Deprected class for running Chrome in document mode. Kept around to force us ers into the correct
77 * instance represents a single web page at a time while providing Chrome functi onality. 19 * {@link Activity}.
78 *
79 * <p>
80 * Tab switching is handled via the system wide Android task management system.
81 */ 20 */
82 @TargetApi(Build.VERSION_CODES.LOLLIPOP) 21 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
83 public class DocumentActivity extends ChromeActivity { 22 public class DocumentActivity extends ChromeActivity {
84 // Legacy class names to match Chrome pre-44 activity names. See crbug.com/5 03807 23 // Legacy class names to match Chrome pre-44 activity names. See crbug.com/5 03807
85 public static final String LEGACY_CLASS_NAME = 24 public static final String LEGACY_CLASS_NAME =
86 "com.google.android.apps.chrome.document.DocumentActivity"; 25 "com.google.android.apps.chrome.document.DocumentActivity";
87 public static final String LEGACY_INCOGNITO_CLASS_NAME = 26 public static final String LEGACY_INCOGNITO_CLASS_NAME =
88 "com.google.android.apps.chrome.document.IncognitoDocumentActivity"; 27 "com.google.android.apps.chrome.document.IncognitoDocumentActivity";
89 28
90 protected static final String KEY_INITIAL_URL = "DocumentActivity.KEY_INITIA L_URL";
91
92 private static final String TAG = "DocumentActivity"; 29 private static final String TAG = "DocumentActivity";
93 30
94 // Animation exit duration defined in chrome/android/java/res/anim/menu_exit .xml as 150ms,
95 // plus add another 20ms for a re-layout.
96 private static final int MENU_EXIT_ANIMATION_WAIT_MS = 170;
97
98 private class DocumentTabObserver extends EmptyTabObserver {
99 @Override
100 public void onPageLoadStarted(Tab tab, String url) {
101 // Discard startup navigation measurements when the user interfered and started the
102 // 2nd navigation (in activity lifetime) in parallel.
103 if (!sIsFirstPageLoadStart) {
104 UmaUtils.setRunningApplicationStart(false);
105 } else {
106 sIsFirstPageLoadStart = false;
107 }
108 }
109
110 @Override
111 public void onUrlUpdated(Tab tab) {
112 assert mTab == tab;
113 mTabModel.updateEntry(getIntent(), mTab);
114 }
115
116 @Override
117 public void onLoadStopped(Tab tab, boolean toDifferentDocument) {
118 assert mTab == tab;
119 mTabModel.updateEntry(getIntent(), mTab);
120 }
121
122 @Override
123 public void onCrash(Tab tab, boolean sadTabShown) {
124 int currentState = ApplicationStatus.getStateForActivity(DocumentAct ivity.this);
125 if (currentState != ActivityState.STOPPED) return;
126
127 if (!isTaskRoot() || IntentUtils.safeGetBooleanExtra(getIntent(),
128 IntentHandler.EXTRA_APPEND_TASK, false)) {
129 return;
130 }
131
132 // Finishing backgrounded Activities whose renderers have crashed al lows us to
133 // destroy them and return resources sooner than if we wait for Andr oid to destroy
134 // the Activities themselves. Problematically, this also removes
135 // IncognitoDocumentActivity instances from Android's Recents menu a nd auto-closes
136 // the tab. Instead, take a hit and keep the Activities alive -- An droid will
137 // eventually destroy the Activities, anyway (crbug.com/450292).
138 if (!isIncognito()) finish();
139 }
140 }
141 private DocumentTabModel mTabModel;
142 private InitializationObserver mTabInitializationObserver;
143
144 private ActivityTabTaskDescriptionHelper mTaskDescriptionHelper;
145
146 private Tab mTab;
147 private FindToolbarManager mFindToolbarManager;
148 private boolean mRecordedStartupUma;
149
150 // Whether the page has started loading in this (browser) process once alrea dy. Must only be
151 // used from the UI thread.
152 private static boolean sIsFirstPageLoadStart = true;
153
154 /** Whether the Tab has already been added to the TabModel. */
155 private boolean mNeedsToBeAddedToTabModel;
156
157 @Override 31 @Override
158 protected boolean isStartedUpCorrectly(Intent intent) { 32 protected boolean isStartedUpCorrectly(Intent intent) {
159 boolean isDocumentMode = FeatureUtilities.isDocumentMode(this);
160 int tabId = ActivityDelegate.getTabIdFromIntent(getIntent()); 33 int tabId = ActivityDelegate.getTabIdFromIntent(getIntent());
161 34
162 if (!isDocumentMode) { 35 // Fire a MAIN Intent to send the user back through ChromeLauncherActivi ty.
163 // Fire a MAIN Intent to send the user back through ChromeLauncherAc tivity. 36 Log.e(TAG, "User shouldn't be here. Sending back to ChromeLauncherActiv ity.");
164 Log.e(TAG, "User is not in document mode. Sending back to ChromeLau ncherActivity.");
165 37
166 // Try to bring this tab forward after migration. 38 // Try to bring this tab forward after migration.
167 Intent tabbedIntent = null; 39 Intent tabbedIntent = null;
168 if (tabId != Tab.INVALID_TAB_ID) tabbedIntent = Tab.createBringTabTo FrontIntent(tabId); 40 if (tabId != Tab.INVALID_TAB_ID) tabbedIntent = Tab.createBringTabToFron tIntent(tabId);
169 41
170 if (tabbedIntent == null) { 42 if (tabbedIntent == null) {
171 tabbedIntent = new Intent(Intent.ACTION_MAIN); 43 tabbedIntent = new Intent(Intent.ACTION_MAIN);
172 tabbedIntent.setPackage(getPackageName()); 44 tabbedIntent.setPackage(getPackageName());
173 }
174
175 // Launch the other Activity in its own task so it stays when this o ne finishes.
176 tabbedIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
177 tabbedIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
178
179 startActivity(tabbedIntent);
180 overridePendingTransition(android.R.anim.fade_in, android.R.anim.fad e_out);
181 } 45 }
182 46
183 boolean isStartedUpCorrectly = tabId != Tab.INVALID_TAB_ID && isDocument Mode; 47 // Launch the other Activity in its own task so it stays when this one f inishes.
184 if (!isStartedUpCorrectly) { 48 tabbedIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
185 Log.e(TAG, "Discarding Intent: Tab = " + tabId + ", Document mode = " + isDocumentMode); 49 tabbedIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
186 } 50
187 return isStartedUpCorrectly; 51 startActivity(tabbedIntent);
52 overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_ou t);
53
54 Log.e(TAG, "Discarding Intent: Tab = " + tabId);
55 return false;
188 } 56 }
189 57
190 @Override 58 @Override
191 public void preInflationStartup() { 59 protected boolean handleBackPressed() {
192 // Decide whether to record startup UMA histograms. This is done early in the main
193 // Activity.onCreate() to avoid recording navigation delays when they re quire user input to
194 // proceed. See more details in ChromeTabbedActivity.preInflationStartup ().
195 if (!LibraryLoader.isInitialized()) {
196 UmaUtils.setRunningApplicationStart(true);
197 }
198
199 DocumentTabModelSelector.setPrioritizedTabId(
200 ActivityDelegate.getTabIdFromIntent(getIntent()));
201
202 mTabModel = ChromeApplication.getDocumentTabModelSelector().getModel(isI ncognito());
203 mTabModel.startTabStateLoad();
204 updateLastTabId();
205
206 SingleTabModelSelector selector = new SingleTabModelSelector(this, isInc ognito(), false) {
207 @Override
208 public Tab openNewTab(LoadUrlParams loadUrlParams, TabLaunchType typ e, Tab parent,
209 boolean incognito) {
210 // Triggered via open in new tab context menu on NTP.
211 return ChromeApplication.getDocumentTabModelSelector().openNewTa b(
212 loadUrlParams, type, parent, incognito);
213 }
214 };
215 setTabModelSelector(selector);
216 setTabCreators(ChromeApplication.getDocumentTabModelSelector().getTabCre ator(false),
217 ChromeApplication.getDocumentTabModelSelector().getTabCreator(tr ue));
218
219 super.preInflationStartup();
220
221 supportRequestWindowFeature(Window.FEATURE_ACTION_MODE_OVERLAY);
222 }
223
224 @Override
225 protected int getControlContainerLayoutId() {
226 return R.layout.control_container;
227 }
228
229 @Override
230 public void postInflationStartup() {
231 super.postInflationStartup();
232
233 final int tabId = ActivityDelegate.getTabIdFromIntent(getIntent());
234 mTabInitializationObserver = new InitializationObserver(mTabModel) {
235 @Override
236 public boolean isSatisfied(int currentState) {
237 return currentState >= DocumentTabModelImpl.STATE_LOAD_TAB_S TATE_BG_END
238 || mTabModel.isTabStateReady(tabId);
239 }
240
241 @Override
242 public boolean isCanceled() {
243 return isDestroyed() || isFinishing();
244 }
245
246 @Override
247 public void runImmediately() {
248 initializeUI();
249 }
250 };
251 }
252
253 @Override
254 public void prepareMenu(Menu menu) {
255 if (isNewTabPage() && !isIncognito()) {
256 menu.findItem(R.id.new_tab_menu_id).setVisible(false);
257 }
258 }
259
260 @Override
261 public void finishNativeInitialization() {
262 ChromePreferenceManager preferenceManager =
263 ChromePreferenceManager.getInstance(this);
264 if (isNewTabPage() && FirstRunStatus.getFirstRunFlowComplete(this)) {
265 // Only show promos on second NTP.
266 if (preferenceManager.getPromosSkippedOnFirstStart()) {
267 // Data reduction promo should be temporarily suppressed if the sign in promo is
268 // shown to avoid nagging users too much.
269 if (!SigninPromoUtil.launchSigninPromoIfNeeded(this)) {
270 DataReductionPromoScreen.launchDataReductionPromo(this);
271 }
272 } else {
273 preferenceManager.setPromosSkippedOnFirstStart(true);
274 }
275 }
276
277 FirstRunSignInProcessor.start(this);
278
279 getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
280 Window.PROGRESS_VISIBILITY_OFF);
281
282 // Initialize the native-side TabModels so that the Profile is available when necessary.
283 ChromeApplication.getDocumentTabModelSelector().onNativeLibraryReady();
284 mTabInitializationObserver.runWhenReady();
285
286 if (mNeedsToBeAddedToTabModel) {
287 mNeedsToBeAddedToTabModel = false;
288 mTabModel.addTab(getIntent(), mTab);
289 getTabModelSelector().setTab(mTab);
290 }
291
292 super.finishNativeInitialization();
293 }
294
295 /**
296 * @return The ID of the Tab.
297 */
298 protected final int determineTabId() {
299 int tabId = ActivityDelegate.getTabIdFromIntent(getIntent());
300 if (tabId == Tab.INVALID_TAB_ID && mTab != null) tabId = mTab.getId();
301 return tabId;
302 }
303
304 /**
305 * Determine the last known URL that this Document was displaying when it wa s stopped.
306 * @return URL that the user was last known to have seen, or null if one cou ldn't be found.
307 */
308 private String determineLastKnownUrl() {
309 int tabId = determineTabId();
310 String url = mTabModel.getCurrentUrlForDocument(tabId);
311 if (TextUtils.isEmpty(url)) url = determineInitialUrl(tabId);
312 return url;
313 }
314
315 /**
316 * Determine the URL that this Document was initially opened for. It can be stashed in multiple
317 * locations because IncognitoDocumentActivities are disallowed from passing URLs in the Intent.
318 * @param tabId ID of the Tab owned by this Activity.
319 * @return Initial URL, or null if it couldn't be determined.
320 */
321 protected String determineInitialUrl(int tabId) {
322 String initialUrl = null;
323
324 // Check if the TabModel has it.
325 if (mTabModel != null) {
326 initialUrl = mTabModel.getInitialUrlForDocument(tabId);
327 }
328
329 // Check if the URL was passed through the Intent.
330 if (TextUtils.isEmpty(initialUrl) && getIntent() != null) {
331 initialUrl = IntentHandler.getUrlFromIntent(getIntent());
332 }
333
334 // Check the Tab's history.
335 if (TextUtils.isEmpty(initialUrl) && mTab != null
336 && mTab.getWebContents() != null) {
337 NavigationEntry entry =
338 mTab.getWebContents().getNavigationController().getEntryAtIn dex(0);
339 if (entry != null) initialUrl = entry.getOriginalUrl();
340 }
341
342 return initialUrl;
343 }
344
345 @Override
346 public CharSequence onCreateDescription() {
347 return mTab != null ? mTab.getTitle() : "";
348 }
349
350 @Override
351 public final Tab getActivityTab() {
352 return mTab;
353 }
354
355 @Override
356 public void onStartWithNative() {
357 super.onStartWithNative();
358 handleDocumentUma();
359 }
360
361 @Override
362 public void onStopWithNative() {
363 super.onStopWithNative();
364 StartupMetrics.getInstance().recordHistogram(true);
365 }
366
367 @Override
368 protected void onDestroyInternal() {
369 super.onDestroyInternal();
370
371 if (mTaskDescriptionHelper != null) mTaskDescriptionHelper.destroy();
372 }
373
374 private void handleDocumentUma() {
375 if (mRecordedStartupUma) {
376 DocumentUma.recordStartedBy(
377 DocumentMetricIds.STARTED_BY_ACTIVITY_BROUGHT_TO_FOREGROUND) ;
378 } else {
379 mRecordedStartupUma = true;
380
381 if (getSavedInstanceState() == null) {
382 DocumentUma.recordStartedBy(getPackageName(), getIntent());
383 } else {
384 DocumentUma.recordStartedBy(DocumentMetricIds.STARTED_BY_ACTIVIT Y_RESTARTED);
385 }
386 }
387 DocumentUma.recordInDocumentMode(true);
388 }
389
390 @Override
391 public void onPause() {
392 // If finishing, release all the active media players as we don't know w hen onStop()
393 // will get called.
394 super.onPause();
395 if (isFinishing() && mTab != null && mTab.getWebContents() != null) {
396 mTab.getWebContents().suspendAllMediaPlayers();
397 mTab.getWebContents().setAudioMuted(true);
398 }
399 }
400
401 @Override
402 public void onWindowFocusChanged(boolean hasWindowFocus) {
403 super.onWindowFocusChanged(hasWindowFocus);
404 if (hasWindowFocus) updateLastTabId();
405 }
406
407 @Override
408 public void onResume() {
409 super.onResume();
410
411 if (getIntent() != null) {
412 DocumentUtils.finishOtherTasksWithTabID(
413 ActivityDelegate.getTabIdFromIntent(getIntent()), getTaskId( ));
414 }
415 }
416
417 @Override
418 public void onResumeWithNative() {
419 super.onResumeWithNative();
420
421 if (mTab != null) {
422 AsyncTabParams asyncParams = AsyncTabParamsManager.remove(
423 ActivityDelegate.getTabIdFromIntent(getIntent()));
424 if (asyncParams != null && asyncParams.getLoadUrlParams().getUrl() ! = null) {
425 loadLastKnownUrl(asyncParams);
426 }
427 }
428 StartupMetrics.getInstance().recordHistogram(false);
429 }
430
431 @Override
432 public SingleTabModelSelector getTabModelSelector() {
433 return (SingleTabModelSelector) super.getTabModelSelector();
434 }
435
436 private void loadLastKnownUrl(AsyncTabParams asyncParams) {
437 Intent intent = getIntent();
438 if (asyncParams != null && asyncParams.getOriginalIntent() != null) {
439 intent = asyncParams.getOriginalIntent();
440 }
441
442 boolean isIntentChromeOrFirstParty = IntentHandler.isIntentChromeOrFirst Party(intent,
443 getApplicationContext());
444 int transitionType = intent == null ? PageTransition.LINK
445 : IntentUtils.safeGetIntExtra(intent, IntentHandler.EXTRA_PAGE_T RANSITION_TYPE,
446 PageTransition.LINK);
447 if ((transitionType != PageTransition.TYPED)
448 && (transitionType != PageTransition.LINK)
449 && !isIntentChromeOrFirstParty) {
450 // Only 1st party authenticated applications can set the transition type to be
451 // anything other than TYPED for security reasons.
452 transitionType = PageTransition.LINK;
453 }
454 if (transitionType == PageTransition.LINK) {
455 transitionType |= PageTransition.FROM_API;
456 }
457
458 String url = (asyncParams != null && asyncParams.getLoadUrlParams().getU rl() != null)
459 ? asyncParams.getLoadUrlParams().getUrl() : determineLastKnownUr l();
460
461 LoadUrlParams loadUrlParams =
462 asyncParams == null ? new LoadUrlParams(url) : asyncParams.getLo adUrlParams();
463 loadUrlParams.setTransitionType(transitionType);
464 if (getIntent() != null) {
465 loadUrlParams.setIntentReceivedTimestamp(getOnCreateTimestampUptimeM s());
466 }
467
468 if (intent != null) {
469 IntentHandler.addReferrerAndHeaders(loadUrlParams, intent, this);
470 }
471
472 if (asyncParams != null && asyncParams.getOriginalIntent() != null) {
473 mTab.getTabRedirectHandler().updateIntent(asyncParams.getOriginalInt ent());
474 } else {
475 if (getIntent() != null) {
476 try {
477 intent = IntentUtils.safeGetParcelableExtra(getIntent(),
478 IntentHandler.EXTRA_ORIGINAL_INTENT);
479 } catch (Throwable t) {
480 // Ignore exception.
481 }
482 }
483 mTab.getTabRedirectHandler().updateIntent(intent);
484 }
485
486 mTab.loadUrl(loadUrlParams);
487 if (asyncParams != null && asyncParams.getRequestId() != null
488 && asyncParams.getRequestId() > 0) {
489 ServiceTabLauncher.onWebContentsForRequestAvailable(
490 asyncParams.getRequestId(), mTab.getWebContents());
491 }
492 }
493
494 @Override
495 public void terminateIncognitoSession() {
496 ChromeApplication.getDocumentTabModelSelector().getModel(true).closeAllT abs();
497 }
498
499 private void initializeUI() {
500 int defaultThemeColor = isIncognito()
501 ? ApiCompatibilityUtils.getColor(getResources(), R.color.incogni to_primary_color)
502 : ApiCompatibilityUtils.getColor(getResources(), R.color.default _primary_color);
503 mTaskDescriptionHelper = new ActivityTabTaskDescriptionHelper(this, defa ultThemeColor);
504
505 AsyncTabParams params = AsyncTabParamsManager.remove(
506 ActivityDelegate.getTabIdFromIntent(getIntent()));
507
508 AsyncTabCreationParams asyncParams = params instanceof AsyncTabCreationP arams
509 ? (AsyncTabCreationParams) params : null;
510 boolean isAffiliated = asyncParams != null ? asyncParams.isAffiliated() : false;
511 boolean isCreatedWithWebContents = asyncParams != null
512 && asyncParams.getWebContents() != null;
513
514 // URL modification must happen before the Tab is created.
515 if (!isIncognito() && asyncParams != null) {
516 LoadUrlParams loadUrlParams = asyncParams.getLoadUrlParams();
517 if (loadUrlParams != null && loadUrlParams.getUrl() != null) {
518 loadUrlParams.setUrl(DataReductionProxySettings.getInstance()
519 .maybeRewriteWebliteUrl(loadUrlParams.getUrl()));
520 }
521 }
522
523 if (params != null && params.getTabToReparent() != null) {
524 mTab = params.getTabToReparent();
525 mTab.attachAndFinishReparenting(this, new DocumentTabDelegateFactory (),
526 (TabReparentingParams) params);
527 } else {
528 mTab = createActivityTab(asyncParams);
529 }
530
531 if (asyncParams != null && asyncParams.getWebContents() != null) {
532 Intent parentIntent = IntentUtils.safeGetParcelableExtra(getIntent() ,
533 IntentHandler.EXTRA_PARENT_INTENT);
534 mTab.setParentIntent(parentIntent);
535 }
536
537 if (mTabModel.isNativeInitialized()) {
538 mTabModel.addTab(getIntent(), mTab);
539 } else {
540 mNeedsToBeAddedToTabModel = true;
541 }
542
543 getTabModelSelector().setTab(mTab);
544
545 if (mTab.didFailToRestore()
546 || (asyncParams != null && asyncParams.getLoadUrlParams().getUrl () != null)) {
547 if (!isCreatedWithWebContents) {
548 // Don't load tabs in the background on low end devices. We will call
549 // loadLastKnownUrl() in onResumeWithNative() next time activity is resumed.
550 if (SysUtils.isLowEndDevice() && isAffiliated) {
551 // onResumeWithNative() wants asyncParams's URL to be non-nu ll.
552 LoadUrlParams loadUrlParams = asyncParams.getLoadUrlParams() ;
553 if (loadUrlParams.getUrl() == null) {
554 loadUrlParams.setUrl(determineLastKnownUrl());
555 }
556
557 AsyncTabParamsManager.add(
558 ActivityDelegate.getTabIdFromIntent(getIntent()), as yncParams);
559
560 // Use the URL as the document title until tab is loaded.
561 mTaskDescriptionHelper.updateTaskDescription(loadUrlParams.g etUrl(), null);
562 } else {
563 loadLastKnownUrl(asyncParams);
564 }
565 }
566 mTab.setShouldPreserve(IntentUtils.safeGetBooleanExtra(getIntent(),
567 IntentHandler.EXTRA_PRESERVE_TASK, false));
568 }
569
570 ToolbarControlContainer controlContainer =
571 (ToolbarControlContainer) findViewById(R.id.control_container);
572 LayoutManagerDocument layoutDriver = null;
573 OverviewModeBehavior overviewModeBehavior = null;
574 OnClickListener tabSwitcherClickHandler = null;
575 if (FeatureUtilities.isTabSwitchingEnabledInDocumentMode(getApplicationC ontext())) {
576 LayoutManagerDocumentTabSwitcher layoutDriverTabSwitcher =
577 new LayoutManagerDocumentTabSwitcher(getCompositorViewHolder ());
578 layoutDriverTabSwitcher.addOverviewModeObserver(new OverviewModeObse rver() {
579 @Override
580 public void onOverviewModeStartedShowing(boolean showToolbar) {
581 if (mFindToolbarManager != null) mFindToolbarManager.hideToo lbar();
582 if (getAssistStatusHandler() != null) {
583 getAssistStatusHandler().updateAssistState();
584 }
585 ApiCompatibilityUtils.setStatusBarColor(getWindow(), Color.B LACK);
586 StartupMetrics.getInstance().recordOpenedTabSwitcher();
587 }
588
589 @Override
590 public void onOverviewModeFinishedShowing() {}
591
592 @Override
593 public void onOverviewModeStartedHiding(
594 boolean showToolbar, boolean delayAnimation) {}
595
596 @Override
597 public void onOverviewModeFinishedHiding() {
598 if (getAssistStatusHandler() != null) {
599 getAssistStatusHandler().updateAssistState();
600 }
601 if (getActivityTab() != null) {
602 LayoutManagerDocumentTabSwitcher manager =
603 (LayoutManagerDocumentTabSwitcher) getCompositor ViewHolder()
604 .getLayoutManager();
605 boolean isInOverviewMode = manager != null && manager.ov erviewVisible();
606 setStatusBarColor(getActivityTab(),
607 isInOverviewMode ? Color.BLACK : getActivityTab( ).getThemeColor());
608 }
609 }
610 });
611 layoutDriver = layoutDriverTabSwitcher;
612 overviewModeBehavior = layoutDriverTabSwitcher;
613
614 tabSwitcherClickHandler = new OnClickListener() {
615 @Override
616 public void onClick(View v) {
617 if (getFullscreenManager() != null
618 && getFullscreenManager().getPersistentFullscreenMod e()) {
619 return;
620 }
621 LayoutManagerDocumentTabSwitcher manager =
622 (LayoutManagerDocumentTabSwitcher) getCompositorView Holder()
623 .getLayoutManager();
624 manager.toggleOverview();
625 }
626 };
627 } else {
628 layoutDriver = new LayoutManagerDocument(getCompositorViewHolder());
629 }
630 initializeCompositorContent(layoutDriver, findViewById(R.id.url_bar),
631 (ViewGroup) findViewById(android.R.id.content), controlContainer );
632
633 mFindToolbarManager = new FindToolbarManager(this,
634 getToolbarManager().getActionModeController().getActionModeCallb ack());
635
636 if (getContextualSearchManager() != null) {
637 getContextualSearchManager().setFindToolbarManager(mFindToolbarManag er);
638 }
639
640 getToolbarManager().initializeWithNative(getTabModelSelector(), getFulls creenManager(),
641 mFindToolbarManager, overviewModeBehavior, layoutDriver, tabSwit cherClickHandler,
642 null, null, null);
643
644 mTab.setFullscreenManager(getFullscreenManager());
645
646 mTab.addObserver(new DocumentTabObserver());
647
648 removeWindowBackground();
649 }
650
651 private void updateLastTabId() {
652 ChromeApplication.getDocumentTabModelSelector().selectModel(isIncognito( ));
653 int tabId = mTab == null
654 ? ActivityDelegate.getTabIdFromIntent(getIntent()) : mTab.getId ();
655 mTabModel.setLastShownId(tabId);
656 }
657
658 @Override
659 public boolean handleBackPressed() {
660 if (mTab == null) return false;
661
662 if (exitFullscreenIfShowing()) return true;
663
664 if (mTab.canGoBack()) {
665 mTab.goBack();
666 } else if (!mTab.shouldPreserve()) {
667 finishAndRemoveTask();
668 } else {
669 moveTaskToBack(true);
670 }
671 return true;
672 }
673
674
675 @Override
676 public TabDelegate getTabCreator(boolean incognito) {
677 return (TabDelegate) super.getTabCreator(incognito);
678 }
679
680 private Tab createActivityTab(AsyncTabCreationParams asyncParams) {
681 boolean isAffiliated = asyncParams != null ? asyncParams.isAffiliated() : false;
682 boolean isCreatedWithWebContents = asyncParams != null
683 && asyncParams.getWebContents() != null;
684 int tabId = determineTabId();
685 int parentTabId = getIntent().getIntExtra(
686 IntentHandler.EXTRA_PARENT_TAB_ID, Tab.INVALID_TAB_ID);
687 TabState tabState = mTabModel.getTabStateForDocument(tabId);
688 boolean hasTabState = tabState != null;
689 String url = determineLastKnownUrl();
690
691 Tab tab = new Tab(tabId, parentTabId, isIncognito(), this, getWindowAndr oid(),
692 getTabLaunchType(url, hasTabState, isAffiliated),
693 getTabCreationState(hasTabState, isAffiliated), tabState);
694
695 // Initialize tab and web contents.
696 WebContents webContents = isCreatedWithWebContents ? asyncParams.getWebC ontents() : null;
697 tab.initialize(webContents, getTabContentManager(),
698 new DocumentTabDelegateFactory(), isAffiliated, hasTabState);
699 tab.getView().requestFocus();
700 if (isCreatedWithWebContents) webContents.resumeLoadingCreatedWebContent s();
701
702 return tab;
703 }
704
705 /**
706 * This cannot return {@link TabCreationState#FROZEN_ON_RESTORE_FAILED} sinc e the Tab has
707 * to be created first to even attempt restore.
708 */
709 private TabCreationState getTabCreationState(boolean hasTabState, boolean is Affiliated) {
710 if (hasTabState) return TabCreationState.FROZEN_ON_RESTORE;
711 if (isAffiliated) {
712 if (SysUtils.isLowEndDevice()) return TabCreationState.FROZEN_FOR_LA ZY_LOAD;
713 return TabCreationState.LIVE_IN_BACKGROUND;
714 }
715 return TabCreationState.LIVE_IN_FOREGROUND;
716 }
717
718 private TabLaunchType getTabLaunchType(
719 String url, boolean hasTabState, boolean isAffiliated) {
720 if (hasTabState) return TabLaunchType.FROM_RESTORE;
721 if (isAffiliated) return TabLaunchType.FROM_LONGPRESS_BACKGROUND;
722 if (!TextUtils.isEmpty(url) && url.equals(UrlConstants.NTP_URL)) {
723 return TabLaunchType.FROM_CHROME_UI;
724 }
725 return TabLaunchType.FROM_EXTERNAL_APP;
726 }
727
728 @Override
729 public void createContextualSearchTab(String searchUrl) {
730 AsyncTabCreationParams asyncParams =
731 new AsyncTabCreationParams(new LoadUrlParams(searchUrl, PageTran sition.LINK));
732 asyncParams.setDocumentStartedBy(DocumentMetricIds.STARTED_BY_CONTEXTUAL _SEARCH);
733 getTabCreator(false).createNewTab(
734 asyncParams, TabLaunchType.FROM_CHROME_UI, getActivityTab().getI d());
735 }
736
737 @Override
738 public boolean onMenuOrKeyboardAction(int id, boolean fromMenu) {
739 if (id == R.id.new_tab_menu_id) {
740 mHandler.postDelayed(new Runnable() {
741 @Override
742 public void run() {
743 launchNtp(false);
744 }
745 }, MENU_EXIT_ANIMATION_WAIT_MS);
746 RecordUserAction.record("MobileMenuNewTab");
747 RecordUserAction.record("MobileNewTabOpened");
748 } else if (id == R.id.new_incognito_tab_menu_id) {
749 // This action must be recorded before opening the incognito tab sin ce UMA actions
750 // are dropped when an incognito tab is open.
751 RecordUserAction.record("MobileMenuNewIncognitoTab");
752 RecordUserAction.record("MobileNewTabOpened");
753 mHandler.postDelayed(new Runnable() {
754 @Override
755 public void run() {
756 launchNtp(true);
757 }
758 }, MENU_EXIT_ANIMATION_WAIT_MS);
759 } else if (id == R.id.all_bookmarks_menu_id) {
760 StartupMetrics.getInstance().recordOpenedBookmarks();
761 BookmarkUtils.showBookmarkManager(this);
762 RecordUserAction.record("MobileMenuAllBookmarks");
763 } else if (id == R.id.recent_tabs_menu_id) {
764 NewTabPage.launchRecentTabsDialog(this, mTab);
765 RecordUserAction.record("MobileMenuOpenTabs");
766 } else if (id == R.id.find_in_page_id) {
767 mFindToolbarManager.showToolbar();
768 if (getContextualSearchManager() != null) {
769 getContextualSearchManager().hideContextualSearch(StateChangeRea son.UNKNOWN);
770 }
771 if (fromMenu) {
772 RecordUserAction.record("MobileMenuFindInPage");
773 } else {
774 RecordUserAction.record("MobileShortcutFindInPage");
775 }
776 } else if (id == R.id.focus_url_bar) {
777 if (getToolbarManager().isInitialized()) getToolbarManager().setUrlB arFocus(true);
778 } else {
779 return super.onMenuOrKeyboardAction(id, fromMenu);
780 }
781 return true;
782 }
783
784 @Override
785 public boolean dispatchKeyEvent(KeyEvent event) {
786 Boolean result = KeyboardShortcuts.dispatchKeyEvent(event, this,
787 getToolbarManager().isInitialized());
788 return result != null ? result : super.dispatchKeyEvent(event);
789 }
790
791 @Override
792 public boolean onKeyDown(int keyCode, KeyEvent event) {
793 if (!getToolbarManager().isInitialized()) {
794 return super.onKeyDown(keyCode, event);
795 }
796 return KeyboardShortcuts.onKeyDown(event, this, true, false)
797 || super.onKeyDown(keyCode, event);
798 }
799
800 @Override
801 public boolean shouldShowAppMenu() {
802 if (mTab == null || !getToolbarManager().isInitialized()) {
803 return false;
804 }
805
806 return super.shouldShowAppMenu();
807 }
808
809 @Override
810 protected void showAppMenuForKeyboardEvent() {
811 if (!getToolbarManager().isInitialized()) return;
812 super.showAppMenuForKeyboardEvent();
813 }
814
815 /**
816 * @return Whether the {@link DocumentTab} this activity uses is incognito.
817 */
818 protected boolean isIncognito() {
819 return false; 60 return false;
820 } 61 }
821 62
822 /** 63 /**
823 * @return Whether this activity contains a tab that is showing the new tab page.
824 */
825 boolean isNewTabPage() {
826 String url;
827 if (mTab == null) {
828 // If the Tab hasn't been created yet, then we're really early in in itialization.
829 // Use a combination of the original URL from the Intent and whether or not the Tab is
830 // retargetable to know whether or not the user navigated away from the NTP.
831 // If the Entry doesn't exist, then the DocumentActivity never got a chance to add
832 // itself to the TabList and is likely to be retargetable.
833 int tabId = ActivityDelegate.getTabIdFromIntent(getIntent());
834 url = IntentHandler.getUrlFromIntent(getIntent());
835 if (mTabModel.hasEntryForTabId(tabId) && !mTabModel.isRetargetable(t abId)) return false;
836 } else {
837 url = mTab.getUrl();
838 }
839 return NewTabPage.isNTPUrl(url);
840 }
841
842 /**
843 * Determines whether the given class can be classified as a DocumentActivit y (this includes 64 * Determines whether the given class can be classified as a DocumentActivit y (this includes
844 * both regular document activity and incognito document activity). 65 * both regular document activity and incognito document activity).
845 * @param className The class name to inspect. 66 * @param className The class name to inspect.
846 * @return Whether the className is that of a document activity. 67 * @return Whether the className is that of a document activity.
847 */ 68 */
848 public static boolean isDocumentActivity(String className) { 69 public static boolean isDocumentActivity(String className) {
849 return TextUtils.equals(className, IncognitoDocumentActivity.class.getNa me()) 70 return TextUtils.equals(className, IncognitoDocumentActivity.class.getNa me())
850 || TextUtils.equals(className, DocumentActivity.class.getName()) 71 || TextUtils.equals(className, DocumentActivity.class.getName())
851 || TextUtils.equals(className, LEGACY_CLASS_NAME) 72 || TextUtils.equals(className, LEGACY_CLASS_NAME)
852 || TextUtils.equals(className, LEGACY_INCOGNITO_CLASS_NAME); 73 || TextUtils.equals(className, LEGACY_INCOGNITO_CLASS_NAME);
853 } 74 }
854
855 /**
856 * Launch a new DocumentActivity showing the new tab page.
857 * @param incognito Whether the new NTP should be in incognito mode.
858 */
859 private void launchNtp(boolean incognito) {
860 if (incognito && !PrefServiceBridge.getInstance().isIncognitoModeEnabled ()) return;
861 getTabCreator(incognito).launchNTP();
862 }
863 } 75 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698