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

Side by Side Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/ChromeActivity.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;
6
7 import android.annotation.SuppressLint;
8 import android.app.Activity;
9 import android.app.SearchManager;
10 import android.content.Context;
11 import android.content.Intent;
12 import android.content.SharedPreferences;
13 import android.graphics.Bitmap;
14 import android.graphics.Rect;
15 import android.os.Build;
16 import android.os.Looper;
17 import android.os.MessageQueue;
18 import android.os.SystemClock;
19 import android.preference.PreferenceManager;
20 import android.provider.Settings;
21 import android.provider.Settings.SettingNotFoundException;
22 import android.util.DisplayMetrics;
23 import android.view.Display;
24 import android.view.Menu;
25 import android.view.MenuItem;
26 import android.view.Surface;
27 import android.view.View;
28 import android.view.Window;
29 import android.view.WindowManager;
30 import android.view.accessibility.AccessibilityManager;
31 import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeL istener;
32 import android.view.accessibility.AccessibilityManager.TouchExplorationStateChan geListener;
33
34 import com.google.android.apps.chrome.R;
35
36 import org.chromium.base.BaseSwitches;
37 import org.chromium.base.CommandLine;
38 import org.chromium.base.metrics.RecordUserAction;
39 import org.chromium.chrome.browser.IntentHandler.IntentHandlerDelegate;
40 import org.chromium.chrome.browser.IntentHandler.TabOpenType;
41 import org.chromium.chrome.browser.compositor.layouts.content.ContentOffsetProvi der;
42 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
43 import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager;
44 import org.chromium.chrome.browser.device.DeviceClassManager;
45 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
46 import org.chromium.chrome.browser.gsa.ContextReporter;
47 import org.chromium.chrome.browser.gsa.GSAServiceClient;
48 import org.chromium.chrome.browser.gsa.GSAState;
49 import org.chromium.chrome.browser.infobar.InfoBarContainer;
50 import org.chromium.chrome.browser.init.AsyncInitializationActivity;
51 import org.chromium.chrome.browser.metrics.LaunchMetrics;
52 import org.chromium.chrome.browser.metrics.UmaSessionStats;
53 import org.chromium.chrome.browser.nfc.BeamController;
54 import org.chromium.chrome.browser.nfc.BeamProvider;
55 import org.chromium.chrome.browser.omaha.OmahaClient;
56 import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomiza tions;
57 import org.chromium.chrome.browser.policy.PolicyManager.PolicyChangeListener;
58 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
59 import org.chromium.chrome.browser.share.ShareHelper;
60 import org.chromium.chrome.browser.sync.ProfileSyncService;
61 import org.chromium.chrome.browser.tabmodel.ChromeTabCreator;
62 import org.chromium.chrome.browser.tabmodel.EmptyTabModel;
63 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
64 import org.chromium.chrome.browser.tabmodel.TabModel;
65 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
66 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
67 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
68 import org.chromium.chrome.browser.tabmodel.TabWindowManager;
69 import org.chromium.chrome.browser.util.FeatureUtilities;
70 import org.chromium.content.browser.ContentReadbackHandler;
71 import org.chromium.content.browser.ContentViewCore;
72 import org.chromium.content.common.ContentSwitches;
73 import org.chromium.content_public.browser.readback_types.ReadbackResponse;
74 import org.chromium.ui.base.DeviceFormFactor;
75 import org.chromium.ui.base.WindowAndroid;
76
77 import java.lang.reflect.Field;
78
79 /**
80 * The main Chrome activity. This exposes extra methods that relate to the {@li nk TabModelSelector}
81 * and lists of tabs.
82 */
83 public abstract class ChromeActivity extends AsyncInitializationActivity impleme nts
84 TabCreatorManager, AccessibilityStateChangeListener, PolicyChangeListene r {
85
86 private static final String SNAPSHOT_DATABASE_REMOVED = "snapshot_database_r emoved";
87 private static final String SNAPSHOT_DATABASE_NAME = "snapshots.db";
88
89 /** Delay in ms after first page load finishes before we initiate deferred s tartup actions. */
90 private static final int DEFERRED_STARTUP_DELAY_MS = 1000;
91
92 /**
93 * Timeout in ms for reading PartnerBrowserCustomizations provider.
94 */
95 private static final int PARTNER_BROWSER_CUSTOMIZATIONS_TIMEOUT_MS = 10000;
96
97 private TabModelSelector mTabModelSelector;
98 private TabModelSelectorTabObserver mTabModelSelectorTabObserver;
99 private ChromeTabCreator mRegularTabCreator;
100 private ChromeTabCreator mIncognitoTabCreator;
101 private TabContentManager mTabContentManager;
102 private UmaSessionStats mUmaSessionStats;
103 private ContextReporter mContextReporter;
104 protected GSAServiceClient mGSAServiceClient;
105
106 private int mCurrentOrientation = Surface.ROTATION_0;
107 private boolean mPartnerBrowserRefreshNeeded = false;
108
109 protected IntentHandler mIntentHandler;
110 protected boolean mIsTablet = false;
111 private long mLastUserInteractionTime;
112
113 /** Whether onDeferredStartup() has been run. */
114 private boolean mDeferredStartupNotified;
115
116 // The class cannot implement TouchExplorationStateChangeListener,
117 // because it is only available for Build.VERSION_CODES.KITKAT and later.
118 // We have to instantiate the TouchExplorationStateChangeListner object in t he code.
119 private TouchExplorationStateChangeListener mTouchExplorationStateChangeList ener;
120
121 // Observes when sync becomes ready to create the mContextReporter.
122 private ProfileSyncService.SyncStateChangedListener mSyncStateChangedListene r;
123
124 @SuppressLint("NewApi")
125 @Override
126 protected void onDestroy() {
127 getChromeApplication().removePolicyChangeListener(this);
128 if (mTabContentManager != null) mTabContentManager.destroy();
129 if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.d estroy();
130
131 AccessibilityManager manager = (AccessibilityManager)
132 getBaseContext().getSystemService(Context.ACCESSIBILITY_SERVICE) ;
133 manager.removeAccessibilityStateChangeListener(this);
134 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
135 manager.removeTouchExplorationStateChangeListener(mTouchExplorationS tateChangeListener);
136 }
137
138 super.onDestroy();
139 }
140
141 /**
142 * {@link TabModelSelector} no longer implements TabModel. Use getTabModelS elector() or
143 * getCurrentTabModel() depending on your needs.
144 * @return The {@link TabModelSelector}, possibly null.
145 */
146 public TabModelSelector getTabModelSelector() {
147 return mTabModelSelector;
148 }
149
150 /**
151 * Sets the {@link TabModelSelector} owned by this {@link ChromeActivity}.
152 * @param tabModelSelector A {@link TabModelSelector} instance.
153 */
154 protected void setTabModelSelector(TabModelSelector tabModelSelector) {
155 mTabModelSelector = tabModelSelector;
156
157 if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.d estroy();
158 mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(tabModelS elector) {
159 @Override
160 public void onLoadStopped(Tab tab) {
161 postDeferredStartupIfNeeded();
162 showUpdateInfoBarIfNecessary();
163 }
164
165 @Override
166 public void onPageLoadFinished(Tab tab) {
167 postDeferredStartupIfNeeded();
168 showUpdateInfoBarIfNecessary();
169 }
170
171 @Override
172 public void onCrash(Tab tab, boolean sadTabShown) {
173 postDeferredStartupIfNeeded();
174 }
175 };
176 }
177
178 @Override
179 public ChromeTabCreator getTabCreator(boolean incognito) {
180 return incognito ? mIncognitoTabCreator : mRegularTabCreator;
181 }
182
183 /**
184 * Sets the {@link ChromeTabCreator}s owned by this {@link ChromeActivity}.
185 * @param regularTabCreator A {@link ChromeTabCreator} instance.
186 */
187 public void setTabCreators(ChromeTabCreator regularTabCreator,
188 ChromeTabCreator incognitoTabCreator) {
189 mRegularTabCreator = regularTabCreator;
190 mIncognitoTabCreator = incognitoTabCreator;
191 }
192
193 /**
194 * Convenience method that returns a tab creator for the currently selected {@link TabModel}.
195 * @return A tab creator for the currently selected {@link TabModel}.
196 */
197 public ChromeTabCreator getCurrentTabCreator() {
198 return getTabCreator(getTabModelSelector().isIncognitoSelected());
199 }
200
201 /**
202 * Gets the {@link TabContentManager} instance which holds snapshots of the tabs in this model.
203 * @return The thumbnail cache, possibly null.
204 */
205 public TabContentManager getTabContentManager() {
206 return mTabContentManager;
207 }
208
209 /**
210 * Sets the {@link TabContentManager} owned by this {@link ChromeActivity}.
211 * @param tabContentManager A {@link TabContentManager} instance.
212 */
213 protected void setTabContentManager(TabContentManager tabContentManager) {
214 mTabContentManager = tabContentManager;
215 }
216
217 /**
218 * Gets the current (inner) TabModel. This is a convenience function for
219 * getModelSelector().getCurrentModel(). It is *not* equivalent to the form er getModel()
220 * @return Never null, if modelSelector or its field is uninstantiated retur ns a
221 * {@link EmptyTabModel} singleton
222 */
223 public TabModel getCurrentTabModel() {
224 TabModelSelector modelSelector = getTabModelSelector();
225 if (modelSelector == null) return EmptyTabModel.getInstance();
226 return modelSelector.getCurrentModel();
227 }
228
229 /**
230 * Returns the tab being displayed by this ChromeActivity instance. This all ows differentiation
231 * between ChromeActivity subclasses that swap between multiple tabs (e.g. C hromeTabbedActivity)
232 * and subclasses that only display one Tab (e.g. FullScreenActivity and Doc umentActivity).
233 *
234 * The default implementation grabs the tab currently selected by the TabMod el, which may be
235 * null if the Tab does not exist or the system is not initialized.
236 */
237 public Tab getActivityTab() {
238 return TabModelUtils.getCurrentTab(getCurrentTabModel());
239 }
240
241 /**
242 * @return The current ContentViewCore, or null if the tab does not exist or is not showing a
243 * ContentViewCore.
244 */
245 public ContentViewCore getCurrentContentViewCore() {
246 return TabModelUtils.getCurrentContentViewCore(getCurrentTabModel());
247 }
248
249 /**
250 * Gets the full screen manager.
251 * @return The fullscreen manager, possibly null
252 */
253 public FullscreenManager getFullscreenManager() {
254 return null;
255 }
256
257 /**
258 * @return The content offset provider, may be null.
259 */
260 public ContentOffsetProvider getContentOffsetProvider() {
261 return null;
262 }
263
264 /**
265 * @return The content readback handler, may be null.
266 */
267 public ContentReadbackHandler getContentReadbackHandler() {
268 return null;
269 }
270
271 @Override
272 public void preInflationStartup() {
273 super.preInflationStartup();
274 ApplicationInitialization.enableFullscreenFlags(
275 getResources(), this, getControlContainerHeightResource());
276 mIsTablet = DeviceFormFactor.isTablet(this);
277 getWindow().setBackgroundDrawableResource(R.color.light_background_color );
278 }
279
280 @SuppressLint("NewApi")
281 @Override
282 public void postInflationStartup() {
283 super.postInflationStartup();
284 // Low end device UI should be allowed only after a fresh install or whe n the data has
285 // been cleared. This must happen before anyone calls SysUtils.isLowEndD evice() or
286 // SysUtils.isLowEndDevice() will always return the wrong value.
287 if (OmahaClient.isFreshInstallOrDataHasBeenCleared(this)) {
288 ChromePreferenceManager.getInstance(this).setAllowLowEndDeviceUi();
289 }
290
291 if (!ChromePreferenceManager.getInstance(this).getAllowLowEndDeviceUi()) {
292 CommandLine.getInstance().appendSwitch(
293 BaseSwitches.DISABLE_LOW_END_DEVICE_MODE);
294 }
295
296 AccessibilityManager manager = (AccessibilityManager)
297 getBaseContext().getSystemService(Context.ACCESSIBILITY_SERVICE) ;
298 manager.addAccessibilityStateChangeListener(this);
299 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
300 mTouchExplorationStateChangeListener = new TouchExplorationStateChan geListener() {
301 @Override
302 public void onTouchExplorationStateChanged(boolean enabled) {
303 checkAccessibility();
304 }
305 };
306 manager.addTouchExplorationStateChangeListener(mTouchExplorationStat eChangeListener);
307 }
308 }
309
310 @Override
311 public void initializeCompositor() {
312 super.initializeCompositor();
313 }
314
315 @Override
316 public void initializeState() {
317 super.initializeState();
318 IntentHandler.setTestIntentsEnabled(
319 CommandLine.getInstance().hasSwitch(ContentSwitches.ENABLE_TEST_ INTENTS));
320 mIntentHandler = new IntentHandler(createIntentHandlerDelegate(), getPac kageName());
321 }
322
323 @Override
324 public void finishNativeInitialization() {
325 // Set up the initial orientation of the device.
326 checkOrientation();
327 findViewById(android.R.id.content).addOnLayoutChangeListener(
328 new View.OnLayoutChangeListener() {
329 @Override
330 public void onLayoutChange(View v, int left, int top, int ri ght, int bottom,
331 int oldLeft, int oldTop, int oldRight, int oldBottom ) {
332 checkOrientation();
333 }
334 });
335
336 // Make the activity listen to policy change events
337 getChromeApplication().addPolicyChangeListener(this);
338
339 super.finishNativeInitialization();
340 }
341
342 @Override
343 public void onStart() {
344 super.onStart();
345 if (mContextReporter != null) mContextReporter.enable();
346
347 if (mPartnerBrowserRefreshNeeded) {
348 mPartnerBrowserRefreshNeeded = false;
349 PartnerBrowserCustomizations.initializeAsync(getApplicationContext() ,
350 PARTNER_BROWSER_CUSTOMIZATIONS_TIMEOUT_MS);
351 PartnerBrowserCustomizations.setOnInitializeAsyncFinished(new Runnab le() {
352 @Override
353 public void run() {
354 if (PartnerBrowserCustomizations.isIncognitoDisabled()) {
355 terminateIncognitoSession();
356 }
357 }
358 });
359 }
360 }
361
362 @Override
363 public void onStop() {
364 super.onStop();
365 if (mContextReporter != null) mContextReporter.disable();
366
367 // We want to refresh partner browser provider every onStart().
368 mPartnerBrowserRefreshNeeded = true;
369 }
370
371 @Override
372 public void onStartWithNative() {
373 super.onStartWithNative();
374 getChromeApplication().onStartWithNative();
375 Tab tab = getActivityTab();
376 if (tab != null) tab.onActivityStart();
377 FeatureUtilities.setDocumentModeEnabled(FeatureUtilities.isDocumentMode( this));
378 WarmupManager.getInstance().clearWebContentsIfNecessary();
379
380 if (GSAState.getInstance(this).isGsaAvailable()) {
381 mGSAServiceClient = new GSAServiceClient(this);
382 mGSAServiceClient.connect();
383 createContextReporterIfNeeded();
384 } else {
385 ContextReporter.reportStatus(ContextReporter.STATUS_GSA_NOT_AVAILABL E);
386 }
387 }
388
389 private void createContextReporterIfNeeded() {
390 if (mContextReporter != null || getActivityTab() == null) return;
391
392 final ProfileSyncService syncService = ProfileSyncService.get(this);
393
394 if (syncService.isSyncingUrlsWithKeystorePassphrase()) {
395 mContextReporter = ((ChromeMobileApplication) getApplicationContext( )).createGsaHelper()
396 .getContextReporter(this);
397
398 if (mSyncStateChangedListener != null) {
399 syncService.removeSyncStateChangedListener(mSyncStateChangedList ener);
400 mSyncStateChangedListener = null;
401 }
402
403 return;
404 } else {
405 ContextReporter.reportSyncStatus(syncService);
406 }
407
408 if (mSyncStateChangedListener == null) {
409 mSyncStateChangedListener = new ProfileSyncService.SyncStateChangedL istener() {
410 @Override
411 public void syncStateChanged() {
412 createContextReporterIfNeeded();
413 }
414 };
415 syncService.addSyncStateChangedListener(mSyncStateChangedListener);
416 }
417 }
418
419 @Override
420 public void onResumeWithNative() {
421 super.onResumeWithNative();
422 markSessionResume();
423
424 if (getActivityTab() != null) {
425 LaunchMetrics.commitLaunchMetrics(getActivityTab().getWebContents()) ;
426 }
427 }
428
429 @Override
430 public void onPauseWithNative() {
431 markSessionEnd();
432 super.onPauseWithNative();
433 }
434
435 @Override
436 public void onStopWithNative() {
437 if (mGSAServiceClient != null) {
438 mGSAServiceClient.disconnect();
439 mGSAServiceClient = null;
440 if (mSyncStateChangedListener != null) {
441 ProfileSyncService syncService = ProfileSyncService.get(this);
442 syncService.removeSyncStateChangedListener(mSyncStateChangedList ener);
443 mSyncStateChangedListener = null;
444 }
445 }
446
447 super.onStopWithNative();
448 }
449
450 @Override
451 public void onNewIntentWithNative(Intent intent) {
452 super.onNewIntentWithNative(intent);
453 if (mIntentHandler.shouldIgnoreIntent(this, intent)) return;
454
455 mIntentHandler.onNewIntent(intent);
456 }
457
458 /**
459 * Called when the orientation of the device changes. The orientation is ch ecked/detected on
460 * root view layouts.
461 * @param orientation One of {@link Surface#ROTATION_0} (no rotation),
462 * {@link Surface#ROTATION_90}, {@link Surface#ROTATION_1 80}, or
463 * {@link Surface#ROTATION_270}.
464 */
465 protected void onOrientationChange(int orientation) {
466 }
467
468 /**
469 * Called when the accessibility status of this device changes. This might be triggered by
470 * touch exploration or general accessibility status updates. It is an aggr egate of two other
471 * accessibility update methods.
472 * @see #onAccessibilityModeChanged(boolean)
473 * @see #onTouchExplorationStateChanged(boolean)
474 * @param enabled Whether or not accessibility and touch exploration are cur rently enabled.
475 */
476 protected void onAccessibilityModeChanged(boolean enabled) {
477 InfoBarContainer.setIsAllowedToAutoHide(!enabled);
478 }
479
480 @Override
481 public boolean onOptionsItemSelected(MenuItem item) {
482 if (item != null && onMenuOrKeyboardAction(item.getItemId(), true)) {
483 return true;
484 }
485 return super.onOptionsItemSelected(item);
486 }
487
488 @Override
489 public void onUserInteraction() {
490 mLastUserInteractionTime = SystemClock.elapsedRealtime();
491 }
492
493 /**
494 * Handles menu item selection and keyboard shortcuts.
495 *
496 * @param id The ID of the selected menu item (defined in main_menu.xml) or
497 * keyboard shortcut (defined in values.xml).
498 * @param fromMenu Whether this was triggered from the menu.
499 * @return Whether the action was handled.
500 */
501 public boolean onMenuOrKeyboardAction(int id, boolean fromMenu) {
502 return false;
503 }
504
505 /**
506 * Triggered when the share menu item is selected.
507 * This creates and shows a share intent picker dialog or starts a share int ent directly.
508 *
509 * @param currentTab The {@link Tab} a user is watching.
510 * @param windowAndroid The {@link WindowAndroid} currentTab is linked to.
511 * @param shareDirectly Whether it should share directly with the activity t hat was most
512 * recently used to share.
513 * @param isIncognito Whether currentTab is incognito.
514 */
515 public void onShareMenuItemSelected(final Tab currentTab,
516 final WindowAndroid windowAndroid, final boolean shareDirectly, bool ean isIncognito) {
517 if (currentTab == null) return;
518
519 final Activity mainActivity = this;
520 ContentReadbackHandler.GetBitmapCallback bitmapCallback =
521 new ContentReadbackHandler.GetBitmapCallback() {
522 @Override
523 public void onFinishGetBitmap(Bitmap bitmap, int reponse) {
524 ShareHelper.share(shareDirectly, mainActivity, currentTa b.getTitle(),
525 currentTab.getUrl(), bitmap);
526 if (shareDirectly) {
527 RecordUserAction.record("MobileMenuDirectShare");
528 } else {
529 RecordUserAction.record("MobileMenuShare");
530 }
531 }
532 };
533 ContentReadbackHandler readbackHandler = getContentReadbackHandler();
534 if (isIncognito || readbackHandler == null || windowAndroid == null
535 || currentTab.getContentViewCore() == null) {
536 bitmapCallback.onFinishGetBitmap(null, ReadbackResponse.SURFACE_UNAV AILABLE);
537 } else {
538 readbackHandler.getContentBitmapAsync(1, new Rect(), currentTab.getC ontentViewCore(),
539 Bitmap.Config.ARGB_8888, bitmapCallback);
540 }
541 }
542
543 /**
544 * @return Whether the activity is running in tablet mode.
545 */
546 public boolean isTablet() {
547 return mIsTablet;
548 }
549
550 /**
551 * @return Whether the activity is in overview mode.
552 */
553 public boolean isInOverviewMode() {
554 return false;
555 }
556
557 /**
558 * @return Whether the app menu should be shown.
559 */
560 public boolean shouldShowAppMenu() {
561 return false;
562 }
563
564 /**
565 * Allows Activities that extend ChromeActivity to do additional hiding/show ing of menu items.
566 * @param menu Menu that is going to be shown when the menu button is presse d.
567 */
568 public void prepareMenu(Menu menu) {
569 }
570
571 /**
572 * @return timestamp when the last user interaction was made.
573 */
574 public long getLastUserInteractionTime() {
575 return mLastUserInteractionTime;
576 }
577
578 protected IntentHandlerDelegate createIntentHandlerDelegate() {
579 return new IntentHandlerDelegate() {
580 @Override
581 public void processWebSearchIntent(String query) {
582 Intent searchIntent = new Intent(Intent.ACTION_WEB_SEARCH);
583 searchIntent.putExtra(SearchManager.QUERY, query);
584 startActivity(searchIntent);
585 }
586
587 @Override
588 public void processUrlViewIntent(String url, String headers, TabOpen Type tabOpenType,
589 String externalAppId, int tabIdToBringToFront, Intent intent ) {
590 }
591 };
592 }
593
594 /**
595 * @return The resource id that contains how large the top controls are.
596 */
597 protected int getControlContainerHeightResource() {
598 return R.dimen.control_container_height;
599 }
600
601 private void markSessionResume() {
602 // Start new session for UMA.
603 if (mUmaSessionStats == null) {
604 mUmaSessionStats = new UmaSessionStats(this);
605 }
606
607 mUmaSessionStats.updateMetricsServiceState();
608 // In DocumentMode we need the application-level TabModelSelector instea d of per
609 // activity which only manages a single tab.
610 if (FeatureUtilities.isDocumentMode(this)) {
611 mUmaSessionStats.startNewSession(
612 ChromeMobileApplication.getDocumentTabModelSelector());
613 } else {
614 mUmaSessionStats.startNewSession(getTabModelSelector());
615 }
616 }
617
618 /**
619 * Mark that the UMA session has ended.
620 */
621 private void markSessionEnd() {
622 if (mUmaSessionStats == null) {
623 // If you hit this assert, please update crbug.com/172653 on how you got there.
624 assert false;
625 return;
626 }
627 // Record session metrics.
628 mUmaSessionStats.logMultiWindowStats(windowArea(), displayArea(),
629 TabWindowManager.getInstance().getNumberOfAssignedTabModelSelect ors());
630 mUmaSessionStats.logAndEndSession();
631 }
632
633 private int windowArea() {
634 Window window = getWindow();
635 if (window != null) {
636 View view = window.getDecorView();
637 return view.getWidth() * view.getHeight();
638 }
639 return -1;
640 }
641
642 private int displayArea() {
643 if (getResources() != null && getResources().getDisplayMetrics() != null ) {
644 DisplayMetrics metrics = getResources().getDisplayMetrics();
645 return metrics.heightPixels * metrics.widthPixels;
646 }
647 return -1;
648 }
649
650 @Override
651 public final void onAccessibilityStateChanged(boolean enabled) {
652 checkAccessibility();
653 }
654
655 private void checkAccessibility() {
656 onAccessibilityModeChanged(DeviceClassManager.isAccessibilityModeEnabled (this));
657 }
658
659 private void checkOrientation() {
660 WindowManager wm = getWindowManager();
661 if (wm == null) return;
662
663 Display display = wm.getDefaultDisplay();
664 if (display == null) return;
665
666 int oldOrientation = mCurrentOrientation;
667 mCurrentOrientation = display.getRotation();
668
669 if (oldOrientation != mCurrentOrientation) onOrientationChange(mCurrentO rientation);
670 }
671
672 /**
673 * Removes the window background.
674 */
675 protected void removeWindowBackground() {
676 boolean removeWindowBackground = true;
677 try {
678 Field field = Settings.Secure.class.getField(
679 "ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED");
680 field.setAccessible(true);
681
682 if (field.getType() == String.class) {
683 String accessibilityMagnificationSetting = (String) field.get(nu ll);
684 // When Accessibility magnification is turned on, setting a null window
685 // background causes the overlaid android views to stretch when panning.
686 // (crbug/332994)
687 if (Settings.Secure.getInt(
688 getContentResolver(), accessibilityMagnificationSetting) == 1) {
689 removeWindowBackground = false;
690 }
691 }
692 } catch (SettingNotFoundException e) {
693 // Window background is removed if an exception occurs.
694 } catch (NoSuchFieldException e) {
695 // Window background is removed if an exception occurs.
696 } catch (IllegalAccessException e) {
697 // Window background is removed if an exception occurs.
698 } catch (IllegalArgumentException e) {
699 // Window background is removed if an exception occurs.
700 }
701 if (removeWindowBackground) getWindow().setBackgroundDrawable(null);
702 }
703
704 /**
705 * @return A casted version of {@link #getApplication()}.
706 */
707 public ChromeMobileApplication getChromeApplication() {
708 return (ChromeMobileApplication) getApplication();
709 }
710
711 /**
712 * @return Whether the update infobar may be shown.
713 */
714 public boolean mayShowUpdateInfoBar() {
715 return true;
716 }
717
718 /**
719 * Actions that may be run at some point after startup. Place tasks that are not critical to the
720 * startup path here. This method will be called automatically and should n ot be called
721 * directly by subclasses. Overriding methods should call super.onDeferredS tartup().
722 */
723 protected void onDeferredStartup() {
724 boolean crashDumpUploadingDisabled = getIntent() != null
725 && getIntent().hasExtra(
726 ChromeTabbedActivity.INTENT_EXTRA_DISABLE_CRASH_DUMP_UPL OADING);
727 DeferredStartupHandler.getInstance()
728 .onDeferredStartup(getChromeApplication(), crashDumpUploadingDis abled);
729
730 BeamController.registerForBeam(this, new BeamProvider() {
731 @Override
732 public String getTabUrlForBeam() {
733 if (isOverlayVisible()) return null;
734 if (getActivityTab() == null) return null;
735 return getActivityTab().getUrl();
736 }
737 });
738
739 getChromeApplication().getUpdateInfoBarHelper().checkForUpdateOnBackgrou ndThread(this);
740 removeSnapshotDatabase();
741 }
742
743 private void postDeferredStartupIfNeeded() {
744 if (!mDeferredStartupNotified) {
745 // We want to perform deferred startup tasks a short time after the first page
746 // load completes, but only when the main thread Looper has become i dle.
747 mHandler.postDelayed(new Runnable() {
748 @Override
749 public void run() {
750 if (!mDeferredStartupNotified && !isActivityDestroyed()) {
751 mDeferredStartupNotified = true;
752 Looper.myQueue().addIdleHandler(new MessageQueue.IdleHan dler() {
753 @Override
754 public boolean queueIdle() {
755 onDeferredStartup();
756 return false; // Remove this idle handler.
757 }
758 });
759 }
760 }
761 }, DEFERRED_STARTUP_DELAY_MS);
762 }
763 }
764
765 private void showUpdateInfoBarIfNecessary() {
766 getChromeApplication().getUpdateInfoBarHelper().showUpdateInfobarIfNeces sary(this);
767 }
768
769 /**
770 * Determines whether the ContentView is currently visible and not hidden by an overlay
771 * @return true if the ContentView is fully hidden by another view (i.e. the tab stack)
772 */
773 public boolean isOverlayVisible() {
774 return false;
775 }
776
777 /**
778 * Deletes the snapshot database which is no longer used because the feature has been removed
779 * in Chrome M41.
780 */
781 private void removeSnapshotDatabase() {
782 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( this);
783 if (!prefs.getBoolean(SNAPSHOT_DATABASE_REMOVED, false)) {
784 deleteDatabase(SNAPSHOT_DATABASE_NAME);
785 prefs.edit().putBoolean(SNAPSHOT_DATABASE_REMOVED, true).apply();
786 }
787 }
788
789 @Override
790 public void terminateIncognitoSession() {}
791
792 /**
793 * @return The {@code ContextualSearchManager} or {@code null} if none;
794 */
795 public ContextualSearchManager getContextualSearchManager() {
796 return null;
797 }
798 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698