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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java

Issue 2814843006: IPH - Added triggers for Download page (Closed)
Patch Set: rebase Created 3 years, 8 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.toolbar; 5 package org.chromium.chrome.browser.toolbar;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.content.res.Configuration; 8 import android.content.res.Configuration;
9 import android.graphics.drawable.Drawable; 9 import android.graphics.drawable.Drawable;
10 import android.os.Handler; 10 import android.os.Handler;
11 import android.os.Looper; 11 import android.os.Looper;
12 import android.os.Message; 12 import android.os.Message;
13 import android.os.SystemClock; 13 import android.os.SystemClock;
14 import android.support.v7.app.ActionBar; 14 import android.support.v7.app.ActionBar;
15 import android.text.TextUtils; 15 import android.text.TextUtils;
16 import android.view.View; 16 import android.view.View;
17 import android.view.View.OnAttachStateChangeListener; 17 import android.view.View.OnAttachStateChangeListener;
18 import android.view.View.OnClickListener; 18 import android.view.View.OnClickListener;
19 import android.view.ViewGroup.MarginLayoutParams; 19 import android.view.ViewGroup.MarginLayoutParams;
20 import android.widget.FrameLayout; 20 import android.widget.FrameLayout;
21 import android.widget.PopupWindow.OnDismissListener;
21 22
22 import org.chromium.base.ApiCompatibilityUtils; 23 import org.chromium.base.ApiCompatibilityUtils;
23 import org.chromium.base.Callback; 24 import org.chromium.base.Callback;
24 import org.chromium.base.ThreadUtils; 25 import org.chromium.base.ThreadUtils;
25 import org.chromium.base.VisibleForTesting; 26 import org.chromium.base.VisibleForTesting;
26 import org.chromium.base.metrics.RecordHistogram; 27 import org.chromium.base.metrics.RecordHistogram;
27 import org.chromium.base.metrics.RecordUserAction; 28 import org.chromium.base.metrics.RecordUserAction;
28 import org.chromium.chrome.R; 29 import org.chromium.chrome.R;
29 import org.chromium.chrome.browser.ChromeActivity; 30 import org.chromium.chrome.browser.ChromeActivity;
31 import org.chromium.chrome.browser.ChromeTabbedActivity;
30 import org.chromium.chrome.browser.NativePage; 32 import org.chromium.chrome.browser.NativePage;
31 import org.chromium.chrome.browser.TabLoadStatus; 33 import org.chromium.chrome.browser.TabLoadStatus;
32 import org.chromium.chrome.browser.UrlConstants; 34 import org.chromium.chrome.browser.UrlConstants;
33 import org.chromium.chrome.browser.WindowDelegate; 35 import org.chromium.chrome.browser.WindowDelegate;
34 import org.chromium.chrome.browser.appmenu.AppMenuButtonHelper; 36 import org.chromium.chrome.browser.appmenu.AppMenuButtonHelper;
35 import org.chromium.chrome.browser.appmenu.AppMenuHandler; 37 import org.chromium.chrome.browser.appmenu.AppMenuHandler;
36 import org.chromium.chrome.browser.appmenu.AppMenuObserver; 38 import org.chromium.chrome.browser.appmenu.AppMenuObserver;
37 import org.chromium.chrome.browser.appmenu.AppMenuPropertiesDelegate; 39 import org.chromium.chrome.browser.appmenu.AppMenuPropertiesDelegate;
38 import org.chromium.chrome.browser.bookmarks.BookmarkBridge; 40 import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
39 import org.chromium.chrome.browser.compositor.Invalidator; 41 import org.chromium.chrome.browser.compositor.Invalidator;
40 import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; 42 import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver;
41 import org.chromium.chrome.browser.compositor.layouts.Layout; 43 import org.chromium.chrome.browser.compositor.layouts.Layout;
42 import org.chromium.chrome.browser.compositor.layouts.LayoutManager; 44 import org.chromium.chrome.browser.compositor.layouts.LayoutManager;
43 import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; 45 import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
44 import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.Overv iewModeObserver; 46 import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.Overv iewModeObserver;
45 import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; 47 import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver;
48 import org.chromium.chrome.browser.download.DownloadUtils;
49 import org.chromium.chrome.browser.feature_engagement_tracker.FeatureEngagementT rackerFactory;
46 import org.chromium.chrome.browser.fullscreen.BrowserStateBrowserControlsVisibil ityDelegate; 50 import org.chromium.chrome.browser.fullscreen.BrowserStateBrowserControlsVisibil ityDelegate;
47 import org.chromium.chrome.browser.fullscreen.FullscreenManager; 51 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
48 import org.chromium.chrome.browser.ntp.IncognitoNewTabPage; 52 import org.chromium.chrome.browser.ntp.IncognitoNewTabPage;
49 import org.chromium.chrome.browser.ntp.NativePageFactory; 53 import org.chromium.chrome.browser.ntp.NativePageFactory;
50 import org.chromium.chrome.browser.ntp.NewTabPage; 54 import org.chromium.chrome.browser.ntp.NewTabPage;
51 import org.chromium.chrome.browser.omnibox.LocationBar; 55 import org.chromium.chrome.browser.omnibox.LocationBar;
52 import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; 56 import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener;
53 import org.chromium.chrome.browser.partnercustomizations.HomepageManager; 57 import org.chromium.chrome.browser.partnercustomizations.HomepageManager;
54 import org.chromium.chrome.browser.partnercustomizations.HomepageManager.Homepag eStateListener; 58 import org.chromium.chrome.browser.partnercustomizations.HomepageManager.Homepag eStateListener;
55 import org.chromium.chrome.browser.profiles.Profile; 59 import org.chromium.chrome.browser.profiles.Profile;
56 import org.chromium.chrome.browser.search_engines.TemplateUrlService; 60 import org.chromium.chrome.browser.search_engines.TemplateUrlService;
57 import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrl ; 61 import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrl ;
58 import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrl ServiceObserver; 62 import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrl ServiceObserver;
59 import org.chromium.chrome.browser.tab.EmptyTabObserver; 63 import org.chromium.chrome.browser.tab.EmptyTabObserver;
60 import org.chromium.chrome.browser.tab.Tab; 64 import org.chromium.chrome.browser.tab.Tab;
61 import org.chromium.chrome.browser.tab.TabObserver; 65 import org.chromium.chrome.browser.tab.TabObserver;
62 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; 66 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
63 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; 67 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
64 import org.chromium.chrome.browser.tabmodel.TabModel; 68 import org.chromium.chrome.browser.tabmodel.TabModel;
65 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; 69 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
66 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; 70 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
67 import org.chromium.chrome.browser.tabmodel.TabModelObserver; 71 import org.chromium.chrome.browser.tabmodel.TabModelObserver;
68 import org.chromium.chrome.browser.tabmodel.TabModelSelector; 72 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
69 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; 73 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
70 import org.chromium.chrome.browser.toolbar.ActionModeController.ActionBarDelegat e; 74 import org.chromium.chrome.browser.toolbar.ActionModeController.ActionBarDelegat e;
71 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; 75 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager;
72 import org.chromium.chrome.browser.widget.findinpage.FindToolbarObserver; 76 import org.chromium.chrome.browser.widget.findinpage.FindToolbarObserver;
77 import org.chromium.chrome.browser.widget.textbubble.ViewAnchoredTextBubble;
78 import org.chromium.components.feature_engagement_tracker.EventConstants;
79 import org.chromium.components.feature_engagement_tracker.FeatureConstants;
80 import org.chromium.components.feature_engagement_tracker.FeatureEngagementTrack er;
73 import org.chromium.content_public.browser.LoadUrlParams; 81 import org.chromium.content_public.browser.LoadUrlParams;
74 import org.chromium.content_public.browser.NavigationController; 82 import org.chromium.content_public.browser.NavigationController;
75 import org.chromium.content_public.browser.NavigationEntry; 83 import org.chromium.content_public.browser.NavigationEntry;
76 import org.chromium.content_public.browser.WebContents; 84 import org.chromium.content_public.browser.WebContents;
85 import org.chromium.net.NetError;
77 import org.chromium.ui.UiUtils; 86 import org.chromium.ui.UiUtils;
78 import org.chromium.ui.base.DeviceFormFactor; 87 import org.chromium.ui.base.DeviceFormFactor;
79 import org.chromium.ui.base.PageTransition; 88 import org.chromium.ui.base.PageTransition;
80 89
81 import java.util.ArrayList; 90 import java.util.ArrayList;
82 import java.util.List; 91 import java.util.List;
83 import java.util.concurrent.TimeUnit; 92 import java.util.concurrent.TimeUnit;
84 93
85 /** 94 /**
86 * Contains logic for managing the toolbar visual component. This class manages the interactions 95 * Contains logic for managing the toolbar visual component. This class manages the interactions
(...skipping 14 matching lines...) Expand all
101 public void updateReloadButtonState(boolean isLoading); 110 public void updateReloadButtonState(boolean isLoading);
102 } 111 }
103 112
104 /** 113 /**
105 * The number of ms to wait before reporting to UMA omnibox interaction metr ics. 114 * The number of ms to wait before reporting to UMA omnibox interaction metr ics.
106 */ 115 */
107 private static final int RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS = 30000; 116 private static final int RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS = 30000;
108 117
109 private static final int MIN_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS = 1000; 118 private static final int MIN_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS = 1000;
110 private static final int MAX_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS = 30000; 119 private static final int MAX_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS = 30000;
120 private static final int INITIAL_DELAY_IPH_DOWNLOAD_PAGE_MS = 500;
121 private static final int CLEAR_MENU_ITEM_HIGHLIGHT_DELAY_MS = 20;
David Trainor- moved to gerrit 2017/04/17 23:03:41 Do we have to delay here? Should we just post the
shaktisahu 2017/04/19 02:39:11 No, just posting the task seems sufficient.
111 122
112 /** 123 /**
113 * The minimum load progress that can be shown when a page is loading. This is not 0 so that 124 * The minimum load progress that can be shown when a page is loading. This is not 0 so that
114 * it's obvious to the user that something is attempting to load. 125 * it's obvious to the user that something is attempting to load.
115 */ 126 */
116 public static final int MINIMUM_LOAD_PROGRESS = 5; 127 public static final int MINIMUM_LOAD_PROGRESS = 5;
117 128
118 private final ToolbarLayout mToolbar; 129 private final ToolbarLayout mToolbar;
119 private final ToolbarControlContainer mControlContainer; 130 private final ToolbarControlContainer mControlContainer;
120 131
(...skipping 11 matching lines...) Expand all
132 143
133 private final TabObserver mTabObserver; 144 private final TabObserver mTabObserver;
134 private final BookmarkBridge.BookmarkModelObserver mBookmarksObserver; 145 private final BookmarkBridge.BookmarkModelObserver mBookmarksObserver;
135 private final List<FindToolbarObserver> mFindToolbarObservers; 146 private final List<FindToolbarObserver> mFindToolbarObservers;
136 private final OverviewModeObserver mOverviewModeObserver; 147 private final OverviewModeObserver mOverviewModeObserver;
137 private final SceneChangeObserver mSceneChangeObserver; 148 private final SceneChangeObserver mSceneChangeObserver;
138 private final ActionBarDelegate mActionBarDelegate; 149 private final ActionBarDelegate mActionBarDelegate;
139 private final ActionModeController mActionModeController; 150 private final ActionModeController mActionModeController;
140 private final LoadProgressSimulator mLoadProgressSimulator; 151 private final LoadProgressSimulator mLoadProgressSimulator;
141 private final Callback<Boolean> mUrlFocusChangedCallback; 152 private final Callback<Boolean> mUrlFocusChangedCallback;
153 private final Handler mHandler = new Handler();
142 154
143 private BrowserStateBrowserControlsVisibilityDelegate mControlsVisibilityDel egate; 155 private BrowserStateBrowserControlsVisibilityDelegate mControlsVisibilityDel egate;
144 private int mFullscreenFocusToken = FullscreenManager.INVALID_TOKEN; 156 private int mFullscreenFocusToken = FullscreenManager.INVALID_TOKEN;
145 private int mFullscreenFindInPageToken = FullscreenManager.INVALID_TOKEN; 157 private int mFullscreenFindInPageToken = FullscreenManager.INVALID_TOKEN;
146 private int mFullscreenMenuToken = FullscreenManager.INVALID_TOKEN; 158 private int mFullscreenMenuToken = FullscreenManager.INVALID_TOKEN;
147 private int mFullscreenHighlightToken = FullscreenManager.INVALID_TOKEN; 159 private int mFullscreenHighlightToken = FullscreenManager.INVALID_TOKEN;
148 160
149 private int mPreselectedTabId = Tab.INVALID_TAB_ID; 161 private int mPreselectedTabId = Tab.INVALID_TAB_ID;
150 162
151 private boolean mNativeLibraryReady; 163 private boolean mNativeLibraryReady;
152 private boolean mTabRestoreCompleted; 164 private boolean mTabRestoreCompleted;
153 165
154 private AppMenuButtonHelper mAppMenuButtonHelper; 166 private AppMenuButtonHelper mAppMenuButtonHelper;
155 167
168 private ViewAnchoredTextBubble mTextBubble;
169
156 private HomepageStateListener mHomepageStateListener; 170 private HomepageStateListener mHomepageStateListener;
157 171
158 private boolean mInitializedWithNative; 172 private boolean mInitializedWithNative;
159 173
160 private boolean mShouldUpdateTabCount = true; 174 private boolean mShouldUpdateTabCount = true;
161 private boolean mShouldUpdateToolbarPrimaryColor = true; 175 private boolean mShouldUpdateToolbarPrimaryColor = true;
162 176
163 /** 177 /**
164 * Creates a ToolbarManager object. 178 * Creates a ToolbarManager object.
165 * 179 *
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 477
464 @Override 478 @Override
465 public void onDidFinishNavigation(Tab tab, String url, boolean isInM ainFrame, 479 public void onDidFinishNavigation(Tab tab, String url, boolean isInM ainFrame,
466 boolean isErrorPage, boolean hasCommitted, boolean isSameDoc ument, 480 boolean isErrorPage, boolean hasCommitted, boolean isSameDoc ument,
467 boolean isFragmentNavigation, Integer pageTransition, int er rorCode, 481 boolean isFragmentNavigation, Integer pageTransition, int er rorCode,
468 int httpStatusCode) { 482 int httpStatusCode) {
469 if (hasCommitted && isInMainFrame && !isSameDocument) { 483 if (hasCommitted && isInMainFrame && !isSameDocument) {
470 mToolbar.onNavigatedToDifferentPage(); 484 mToolbar.onNavigatedToDifferentPage();
471 } 485 }
472 486
487 displayFeatureEngagementTextBubbleIfNecessary(tab, errorCode);
488
473 // If the load failed due to a different navigation, there is no need to reset the 489 // If the load failed due to a different navigation, there is no need to reset the
474 // location bar animations. 490 // location bar animations.
475 if (errorCode != 0 && isInMainFrame && !hasPendingNonNtpNavigati on(tab)) { 491 if (errorCode != 0 && isInMainFrame && !hasPendingNonNtpNavigati on(tab)) {
476 NewTabPage ntp = mToolbarModel.getNewTabPageForCurrentTab(); 492 NewTabPage ntp = mToolbarModel.getNewTabPageForCurrentTab();
477 if (ntp == null) return; 493 if (ntp == null) return;
478 494
479 ntp.setUrlFocusAnimationsDisabled(false); 495 ntp.setUrlFocusAnimationsDisabled(false);
480 mToolbar.onTabOrModelChanged(); 496 mToolbar.onTabOrModelChanged();
481 if (mToolbar.getProgressBar() != null) mToolbar.getProgressB ar().finish(false); 497 if (mToolbar.getProgressBar() != null) mToolbar.getProgressB ar().finish(false);
482 } 498 }
483 } 499 }
500
501 private void displayFeatureEngagementTextBubbleIfNecessary(
502 final Tab tab, int errorCode) {
503 if (mTextBubble != null) {
504 mTextBubble.dismiss();
505 mTextBubble = null;
506 return;
507 }
508
509 if (!(activity instanceof ChromeTabbedActivity)
David Trainor- moved to gerrit 2017/04/17 23:03:41 Add a TODO and a bug to key this off of whether or
shaktisahu 2017/04/19 02:39:11 Done. Added below.
510 || DeviceFormFactor.isTablet(mToolbar.getContext())
511 || activity.isInOverviewMode()) {
512 return;
513 }
514
515 final FeatureEngagementTracker tracker =
516 FeatureEngagementTrackerFactory.getFeatureEngagementTrac kerForProfile(
517 tab.getProfile());
518
519 if (errorCode == NetError.ERR_INTERNET_DISCONNECTED) {
520 tracker.notifyEvent(EventConstants.USER_HAS_SEEN_DINO);
521 }
522
523 if (errorCode != 0) return;
524
525 mHandler.postDelayed(new Runnable() {
526 @Override
527 public void run() {
528 if (!DownloadUtils.isAllowedToDownloadPage(tab)) return;
529 if (!tracker.shouldTriggerHelpUI(FeatureConstants.DOWNLO AD_PAGE_FEATURE)) {
530 return;
531 }
532
533 mTextBubble = new ViewAnchoredTextBubble(mToolbar.getCon text(),
534 getMenuAnchor(), R.string.iph_download_page_for_ offline_usage_text);
535 mTextBubble.setDismissOnTouchInteraction(true);
536 mTextBubble.addOnDismissListener(new OnDismissListener() {
537 @Override
538 public void onDismiss() {
539 mHandler.postDelayed(new Runnable() {
540 @Override
541 public void run() {
542 tracker.dismissed();
543 activity.getAppMenuHandler().setMenuHigh light(0);
544 }
545 }, CLEAR_MENU_ITEM_HIGHLIGHT_DELAY_MS);
546 }
547 });
548 activity.getAppMenuHandler().setMenuHighlight(R.id.offli ne_page_id);
549 mTextBubble.show();
550 }
551 }, INITIAL_DELAY_IPH_DOWNLOAD_PAGE_MS);
David Trainor- moved to gerrit 2017/04/17 23:03:41 Why do we delay the show call again?
shaktisahu 2017/04/19 02:39:11 Removed this delay. Moved trigger part of this fun
552 }
484 }; 553 };
485 554
486 mBookmarksObserver = new BookmarkBridge.BookmarkModelObserver() { 555 mBookmarksObserver = new BookmarkBridge.BookmarkModelObserver() {
487 @Override 556 @Override
488 public void bookmarkModelChanged() { 557 public void bookmarkModelChanged() {
489 updateBookmarkButtonStatus(); 558 updateBookmarkButtonStatus();
490 } 559 }
491 }; 560 };
492 561
493 mFindToolbarObservers = new ArrayList<>(); 562 mFindToolbarObservers = new ArrayList<>();
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 } 1353 }
1285 1354
1286 /** 1355 /**
1287 * Cancels simulating load progress. 1356 * Cancels simulating load progress.
1288 */ 1357 */
1289 public void cancel() { 1358 public void cancel() {
1290 mHandler.removeMessages(MSG_ID_UPDATE_PROGRESS); 1359 mHandler.removeMessages(MSG_ID_UPDATE_PROGRESS);
1291 } 1360 }
1292 } 1361 }
1293 } 1362 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698