下面列出了android.view.MenuItem.OnMenuItemClickListener#org.chromium.base.metrics.RecordHistogram 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void onClosed(StateChangeReason reason) {
if (mReaderModePanel == null || mTabModelSelector == null) return;
restoreInfobars();
// Only dismiss the panel if the close was a result of user interaction.
if (reason != StateChangeReason.FLING && reason != StateChangeReason.SWIPE
&& reason != StateChangeReason.CLOSE_BUTTON) {
return;
}
// Record close button usage.
if (reason == StateChangeReason.CLOSE_BUTTON) {
RecordHistogram.recordBooleanHistogram("DomDistiller.BarCloseButtonUsage",
mReaderModePanel.getPanelState() == PanelState.EXPANDED
|| mReaderModePanel.getPanelState() == PanelState.MAXIMIZED);
}
int currentTabId = mTabModelSelector.getCurrentTabId();
if (!mTabStatusMap.containsKey(currentTabId)) return;
mTabStatusMap.get(currentTabId).setIsDismissed(true);
}
/**
* Returns the directory for a web app, creating it if necessary.
* @param webappId ID for the web app. Used as a subdirectory name.
* @return File for storing information about the web app.
*/
File getWebappDirectory(Context context, String webappId) {
// Temporarily allowing disk access while fixing. TODO: http://crbug.com/525781
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
try {
long time = SystemClock.elapsedRealtime();
File webappDirectory = new File(getBaseWebappDirectory(context), webappId);
if (!webappDirectory.exists() && !webappDirectory.mkdir()) {
Log.e(TAG, "Failed to create web app directory.");
}
RecordHistogram.recordTimesHistogram("Android.StrictMode.WebappDir",
SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECONDS);
return webappDirectory;
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
}
/**
* Logs the outcome of the Promo.
* Logs multiple histograms; with and without the originating gesture.
* @param wasTap Whether the gesture that originally caused the panel to show was a Tap.
* @param wasMandatory Whether the Promo was mandatory.
*/
public static void logPromoOutcome(boolean wasTap, boolean wasMandatory) {
int preferenceCode = getPreferenceValue();
RecordHistogram.recordEnumeratedHistogram("Search.ContextualSearchFirstRunFlowOutcome",
preferenceCode, PREFERENCE_HISTOGRAM_BOUNDARY);
int preferenceByGestureCode = getPromoByGestureStateCode(preferenceCode, wasTap);
if (wasMandatory) {
RecordHistogram.recordEnumeratedHistogram(
"Search.ContextualSearchMandatoryPromoOutcomeByGesture",
preferenceByGestureCode, PROMO_BY_GESTURE_BOUNDARY);
} else {
RecordHistogram.recordEnumeratedHistogram(
"Search.ContextualSearchPromoOutcomeByGesture",
preferenceByGestureCode, PROMO_BY_GESTURE_BOUNDARY);
}
}
@Override
public void onCharacteristicRead(
final Wrappers.BluetoothGattCharacteristicWrapper characteristic,
final int status) {
Wrappers.ThreadUtilsWrapper.getInstance().runOnUiThread(new Runnable() {
@Override
public void run() {
ChromeBluetoothRemoteGattCharacteristic chromeCharacteristic =
mWrapperToChromeCharacteristicsMap.get(characteristic);
if (chromeCharacteristic == null) {
// Android events arriving with no Chrome object is expected rarely: only
// when the event races object destruction.
Log.v(TAG, "onCharacteristicRead when chromeCharacteristic == null.");
} else {
RecordHistogram.recordSparseSlowlyHistogram(
"Bluetooth.Web.Android.onCharacteristicRead.Status", status);
chromeCharacteristic.onCharacteristicRead(status);
}
}
});
}
/**
* Called when clearing browsing data completes.
* Implements the ChromePreferences.OnClearBrowsingDataListener interface.
*/
@Override
public void onBrowsingDataCleared() {
if (getActivity() == null) return;
// If the user deleted their browsing history, the dialog about other forms of history
// is enabled, and it has never been shown before, show it. Note that opening a new
// DialogFragment is only possible if the Activity is visible.
//
// If conditions to show the dialog about other forms of history are not met, just close
// this preference screen.
if (MultiWindowUtils.isActivityVisible(getActivity())
&& getSelectedOptions().contains(DialogOption.CLEAR_HISTORY)
&& mIsDialogAboutOtherFormsOfBrowsingHistoryEnabled
&& !OtherFormsOfHistoryDialogFragment.wasDialogShown(getActivity())) {
mDialogAboutOtherFormsOfBrowsingHistory = new OtherFormsOfHistoryDialogFragment();
mDialogAboutOtherFormsOfBrowsingHistory.show(getActivity());
dismissProgressDialog();
RecordHistogram.recordBooleanHistogram(DIALOG_HISTOGRAM, true);
} else {
dismissProgressDialog();
getActivity().finish();
RecordHistogram.recordBooleanHistogram(DIALOG_HISTOGRAM, false);
}
}
/**
* Record the precache event. The event is persisted in shared preferences if the native library
* is not loaded. If library is loaded, the event will be recorded as UMA metric, and any prior
* persisted events are recorded to UMA as well.
* @param event the precache event.
*/
public static void record(int event) {
SharedPreferences sharedPreferences = ContextUtils.getAppSharedPreferences();
long persistent_metric = sharedPreferences.getLong(PREF_PERSISTENCE_METRICS, 0);
Editor preferencesEditor = sharedPreferences.edit();
if (LibraryLoader.isInitialized()) {
RecordHistogram.recordEnumeratedHistogram(
EVENTS_HISTOGRAM, Event.getBitPosition(event), Event.EVENT_END);
for (int e : Event.getEventsFromBitMask(persistent_metric)) {
RecordHistogram.recordEnumeratedHistogram(
EVENTS_HISTOGRAM, Event.getBitPosition(e), Event.EVENT_END);
}
preferencesEditor.remove(PREF_PERSISTENCE_METRICS);
} else {
// Save the metric in preferences.
persistent_metric = Event.addEventToBitMask(persistent_metric, event);
preferencesEditor.putLong(PREF_PERSISTENCE_METRICS, persistent_metric);
}
preferencesEditor.apply();
}
/**
* All deferred startup tasks that require the activity rather than the app should go here.
*/
private void onDeferredStartupForActivity() {
BeamController.registerForBeam(this, new BeamProvider() {
@Override
public String getTabUrlForBeam() {
if (isOverlayVisible()) return null;
if (getActivityTab() == null) return null;
return getActivityTab().getUrl();
}
});
UpdateMenuItemHelper.getInstance().checkForUpdateOnBackgroundThread(this);
if (mToolbarManager != null) {
String simpleName = getClass().getSimpleName();
RecordHistogram.recordTimesHistogram("MobileStartup.ToolbarInflationTime." + simpleName,
mInflateInitialLayoutDurationMs, TimeUnit.MILLISECONDS);
mToolbarManager.onDeferredStartup(getOnCreateTimestampMs(), simpleName);
}
if (MultiWindowUtils.getInstance().isInMultiWindowMode(this)) {
onDeferredStartupForMultiWindowMode();
}
}
/**
* Registers that a client has launched a URL inside a Custom Tab.
*/
public synchronized void registerLaunch(CustomTabsSessionToken session, String url) {
int outcome = getPredictionOutcome(session, url);
RecordHistogram.recordEnumeratedHistogram(
"CustomTabs.PredictionStatus", outcome, PREDICTION_STATUS_COUNT);
SessionParams params = mSessionParams.get(session);
if (outcome == GOOD_PREDICTION) {
long elapsedTimeMs = SystemClock.elapsedRealtime()
- params.getLastMayLaunchUrlTimestamp();
RequestThrottler.getForUid(mContext, params.uid).registerSuccess(
params.mPredictedUrl);
RecordHistogram.recordCustomTimesHistogram("CustomTabs.PredictionToLaunch",
elapsedTimeMs, 1, TimeUnit.MINUTES.toMillis(3), TimeUnit.MILLISECONDS, 100);
}
RecordHistogram.recordEnumeratedHistogram(
"CustomTabs.WarmupStateOnLaunch", getWarmupState(session), SESSION_WARMUP_COUNT);
if (params == null) return;
int value = (params.lowConfidencePrediction ? LOW_CONFIDENCE : 0)
+ (params.highConfidencePrediction ? HIGH_CONFIDENCE : 0);
RecordHistogram.recordEnumeratedHistogram(
"CustomTabs.MayLaunchUrlType", value, MAY_LAUNCH_URL_TYPE_COUNT);
params.resetPredictionMetrics();
}
/**
* Saves the tab data out to a file.
*/
void saveState(File activityDirectory) {
String tabFileName = TabState.getTabStateFilename(getActivityTab().getId(), false);
File tabFile = new File(activityDirectory, tabFileName);
// Temporarily allowing disk access while fixing. TODO: http://crbug.com/525781
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
StrictMode.allowThreadDiskWrites();
try {
long time = SystemClock.elapsedRealtime();
TabState.saveState(tabFile, getActivityTab().getState(), false);
RecordHistogram.recordTimesHistogram("Android.StrictMode.WebappSaveState",
SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECONDS);
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
}
/**
* Encapsulates CustomTabsConnection#takeHiddenTab()
* with additional initialization logic.
*/
private Tab getHiddenTab(CustomTabsConnection connection) {
String url = getUrlToLoad();
String referrerUrl = connection.getReferrer(mSession, getIntent());
Tab tab = connection.takeHiddenTab(mSession, url, referrerUrl);
mUsingHiddenTab = tab != null;
if (!mUsingHiddenTab) return null;
RecordHistogram.recordEnumeratedHistogram("CustomTabs.WebContentsStateOnLaunch",
WEBCONTENTS_STATE_PRERENDERED_WEBCONTENTS, WEBCONTENTS_STATE_MAX);
tab.setAppAssociatedWith(connection.getClientPackageNameForSession(mSession));
if (mIntentDataProvider.shouldEnableEmbeddedMediaExperience()) {
tab.enableEmbeddedMediaExperience(true);
}
initializeMainTab(tab);
return tab;
}
/**
* Handle all necessary tasks that can be delayed until initialization completes.
* @param activityCreationTimeMs The time of creation for the activity this toolbar belongs to.
* @param activityName Simple class name for the activity this toolbar belongs to.
*/
public void onDeferredStartup(final long activityCreationTimeMs,
final String activityName) {
// Record startup performance statistics
long elapsedTime = SystemClock.elapsedRealtime() - activityCreationTimeMs;
if (elapsedTime < RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS) {
ThreadUtils.postOnUiThreadDelayed(new Runnable() {
@Override
public void run() {
onDeferredStartup(activityCreationTimeMs, activityName);
}
}, RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS - elapsedTime);
}
RecordHistogram.recordTimesHistogram("MobileStartup.ToolbarFirstDrawTime." + activityName,
mToolbar.getFirstDrawTime() - activityCreationTimeMs, TimeUnit.MILLISECONDS);
long firstFocusTime = mToolbar.getLocationBar().getFirstUrlBarFocusTime();
if (firstFocusTime != 0) {
RecordHistogram.recordCustomTimesHistogram(
"MobileStartup.ToolbarFirstFocusTime." + activityName,
firstFocusTime - activityCreationTimeMs, MIN_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS,
MAX_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS, TimeUnit.MILLISECONDS, 50);
}
}
/**
* Called when last of Chrome activities is stopped, ending the foreground session. This will
* not be called when a Chrome activity is stopped because another Chrome activity takes over.
* This is ensured by ActivityStatus, which switches to track new activity when its started and
* will not report the old one being stopped (see createStateListener() below).
*/
private void onForegroundSessionEnd() {
if (!mIsStarted) return;
UmaUtils.recordBackgroundTime();
ChromeApplication.flushPersistentData();
mIsStarted = false;
mPowerBroadcastReceiver.onForegroundSessionEnd();
ChildProcessLauncher.onSentToBackground();
IntentHandler.clearPendingReferrer();
IntentHandler.clearPendingIncognitoUrl();
int totalTabCount = 0;
for (WeakReference<Activity> reference : ApplicationStatus.getRunningActivities()) {
Activity activity = reference.get();
if (activity instanceof ChromeActivity) {
TabModelSelector tabModelSelector =
((ChromeActivity) activity).getTabModelSelector();
if (tabModelSelector != null) {
totalTabCount += tabModelSelector.getTotalTabCount();
}
}
}
RecordHistogram.recordCountHistogram(
"Tab.TotalTabCount.BeforeLeavingApp", totalTabCount);
}
/**
* Logs whether results were seen and whether any tap suppression heuristics were satisfied.
* @param wasSearchContentViewSeen If the panel was opened.
* @param wasAnySuppressionHeuristicSatisfied Whether any of the implemented suppression
* heuristics were satisfied.
*/
public static void logAnyTapSuppressionHeuristicSatisfied(boolean wasSearchContentViewSeen,
boolean wasAnySuppressionHeuristicSatisfied) {
int code;
if (wasAnySuppressionHeuristicSatisfied) {
code = wasSearchContentViewSeen ? RESULTS_SEEN_SUPPRESSION_HEURSTIC_SATISFIED
: RESULTS_NOT_SEEN_SUPPRESSION_HEURSTIC_SATISFIED;
} else {
code = wasSearchContentViewSeen ? RESULTS_SEEN_SUPPRESSION_HEURSTIC_NOT_SATISFIED
: RESULTS_NOT_SEEN_SUPPRESSION_HEURSTIC_NOT_SATISFIED;
}
RecordHistogram.recordEnumeratedHistogram(
"Search.ContextualSearchTapSuppressionSeen.AnyHeuristicSatisfied",
code,
RESULTS_SEEN_SUPPRESSION_BOUNDARY);
}
/**
* Called when clearing browsing data completes.
* Implements the ChromePreferences.OnClearBrowsingDataListener interface.
*/
@Override
public void onBrowsingDataCleared() {
if (getActivity() == null) return;
// If the user deleted their browsing history, the dialog about other forms of history
// is enabled, and it has never been shown before, show it. Note that opening a new
// DialogFragment is only possible if the Activity is visible.
//
// If conditions to show the dialog about other forms of history are not met, just close
// this preference screen.
if (MultiWindowUtils.isActivityVisible(getActivity())
&& getSelectedOptions().contains(DialogOption.CLEAR_HISTORY)
&& mIsDialogAboutOtherFormsOfBrowsingHistoryEnabled
&& !OtherFormsOfHistoryDialogFragment.wasDialogShown(getActivity())) {
mDialogAboutOtherFormsOfBrowsingHistory = new OtherFormsOfHistoryDialogFragment();
mDialogAboutOtherFormsOfBrowsingHistory.show(getActivity());
dismissProgressDialog();
RecordHistogram.recordBooleanHistogram(DIALOG_HISTOGRAM, true);
} else {
dismissProgressDialog();
getActivity().finish();
RecordHistogram.recordBooleanHistogram(DIALOG_HISTOGRAM, false);
}
}
private static void handleTime(Context context, String key, long duration, TimeUnit tu) {
if (LibraryLoader.isInitialized()) {
RecordHistogram.recordTimesHistogram(key, duration, tu);
} else {
storeValue(context, key, duration);
}
}
/**
* All deferred startup tasks that require the activity rather than the app should go here.
*/
private void initDeferredStartupForActivity() {
DeferredStartupHandler.getInstance().addDeferredTask(new Runnable() {
@Override
public void run() {
if (isActivityDestroyed()) return;
BeamController.registerForBeam(ChromeActivity.this, new BeamProvider() {
@Override
public String getTabUrlForBeam() {
if (isOverlayVisible()) return null;
if (getActivityTab() == null) return null;
return getActivityTab().getUrl();
}
});
UpdateMenuItemHelper.getInstance().checkForUpdateOnBackgroundThread(
ChromeActivity.this);
}
});
final String simpleName = getClass().getSimpleName();
DeferredStartupHandler.getInstance().addDeferredTask(new Runnable() {
@Override
public void run() {
if (isActivityDestroyed()) return;
if (mToolbarManager != null) {
RecordHistogram.recordTimesHistogram(
"MobileStartup.ToolbarInflationTime." + simpleName,
mInflateInitialLayoutDurationMs, TimeUnit.MILLISECONDS);
mToolbarManager.onDeferredStartup(getOnCreateTimestampMs(), simpleName);
}
if (MultiWindowUtils.getInstance().isInMultiWindowMode(ChromeActivity.this)) {
onDeferredStartupForMultiWindowMode();
}
}
});
}
private void recordDeferredStartupStats() {
RecordHistogram.recordLongTimesHistogram(
"UMA.Debug.EnableCrashUpload.DeferredStartUpDuration", mDeferredStartupDuration,
TimeUnit.MILLISECONDS);
RecordHistogram.recordLongTimesHistogram(
"UMA.Debug.EnableCrashUpload.DeferredStartUpMaxTaskDuration", mMaxTaskDuration,
TimeUnit.MILLISECONDS);
RecordHistogram.recordLongTimesHistogram(
"UMA.Debug.EnableCrashUpload.DeferredStartUpCompleteTime",
SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(),
TimeUnit.MILLISECONDS);
}
/**
* Calls {@link TabModel#cancelTabClosure(int)} for the tab or for each tab in
* the list of closed tabs.
*/
@SuppressWarnings("unchecked")
@Override
public void onAction(Object actionData) {
RecordHistogram.recordEnumeratedHistogram("AndroidTabCloseUndo.Toast",
TAB_CLOSE_UNDO_TOAST_PRESSED, TAB_CLOSE_UNDO_TOAST_COUNT);
if (actionData instanceof Integer) {
cancelTabClosure((Integer) actionData);
} else {
for (Integer id : (List<Integer>) actionData) {
cancelTabClosure(id);
}
}
}
@Override
public void onSheetClosed() {
mIsSheetOpen = false;
recordSheetCloseReason(mSheetCloseReason);
mSheetCloseReason = CLOSED_BY_NONE;
mLastCloseTime = System.currentTimeMillis();
RecordHistogram.recordMediumTimesHistogram("Android.ChromeHome.DurationOpen",
mLastCloseTime - mLastOpenTime, TimeUnit.MILLISECONDS);
}
public void onLowMemory() {
memoryNotificationForeground(FOREGROUND_LOW);
long now = SystemClock.elapsedRealtime();
if (mLastLowMemoryMsec >= 0) {
RecordHistogram.recordCustomTimesHistogram("MemoryAndroid.LowMemoryTimeBetween",
now - mLastLowMemoryMsec, 0, TimeUnit.MINUTES.toMillis(10),
TimeUnit.MILLISECONDS, 50);
}
mLastLowMemoryMsec = now;
}
/**
* Determines whether the URL needs to be sent as an intent to the system,
* and sends it, if appropriate.
* @return Whether the URL generated an intent, caused a navigation in
* current tab, or wasn't handled at all.
*/
public OverrideUrlLoadingResult shouldOverrideUrlLoading(ExternalNavigationParams params) {
Intent intent;
// Perform generic parsing of the URI to turn it into an Intent.
try {
intent = Intent.parseUri(params.getUrl(), Intent.URI_INTENT_SCHEME);
} catch (Exception ex) {
Log.w(TAG, "Bad URI %s", params.getUrl(), ex);
return OverrideUrlLoadingResult.NO_OVERRIDE;
}
boolean hasBrowserFallbackUrl = false;
String browserFallbackUrl =
IntentUtils.safeGetStringExtra(intent, EXTRA_BROWSER_FALLBACK_URL);
if (browserFallbackUrl != null
&& UrlUtilities.isValidForIntentFallbackNavigation(browserFallbackUrl)) {
hasBrowserFallbackUrl = true;
} else {
browserFallbackUrl = null;
}
long time = SystemClock.elapsedRealtime();
OverrideUrlLoadingResult result = shouldOverrideUrlLoadingInternal(
params, intent, hasBrowserFallbackUrl, browserFallbackUrl);
RecordHistogram.recordTimesHistogram("Android.StrictMode.OverrideUrlLoadingTime",
SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECONDS);
if (result == OverrideUrlLoadingResult.NO_OVERRIDE && hasBrowserFallbackUrl
&& (params.getRedirectHandler() == null
// For instance, if this is a chained fallback URL, we ignore it.
|| !params.getRedirectHandler().shouldNotOverrideUrlLoading())) {
return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, params);
}
return result;
}
/**
* Checks to see if the summary notification is alone and, if so, hides it. If the summary
* notification thinks it's in the foreground, this will start the service with the goal of
* shutting it down. That is because if the service is in the foreground it's not possible to
* stop it through the notification manager.
* @param removedNotificationId The id of the notification that was just removed or {@code -1}
* if this does not apply.
*/
@TargetApi(Build.VERSION_CODES.M)
public static void hideDanglingSummaryNotification(Context context, int removedNotificationId) {
if (!useForegroundService()) return;
NotificationManager manager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (hasDownloadNotifications(manager, removedNotificationId)) return;
StatusBarNotification summary = getSummaryNotification(manager);
if (summary == null) return;
boolean isForeground =
(summary.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
if (BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER)
.isStartupSuccessfullyCompleted()) {
RecordHistogram.recordBooleanHistogram(
"MobileDownload.Notification.FixingSummaryLeak", isForeground);
}
if (isForeground) {
// If it is a foreground notification, we are in a bad state. We don't have any
// other download notifications, but we can't close the summary. Try to start
// up the service and quit through that path?
startDownloadNotificationService(context, new Intent(ACTION_DOWNLOAD_FAIL_SAFE));
} else {
manager.cancel(NotificationConstants.NOTIFICATION_ID_DOWNLOAD_SUMMARY);
}
}
private void saveListToFile(byte[] listData) {
if (Arrays.equals(mLastSavedMetadata, listData)) return;
saveListToFile(getStateDirectory(), mSelectorIndex, listData);
mLastSavedMetadata = listData;
if (LibraryLoader.isInitialized()) {
RecordHistogram.recordCountHistogram(
"Android.TabPersistentStore.MetadataFileSize", listData.length);
}
}
/**
* Returns if we should show the important sites dialog. We check to see if
* <ol>
* <li>We've fetched the important sites,
* <li>there are important sites,
* <li>the feature is enabled, and
* <li>we have cache or cookies selected.
* </ol>
*/
private boolean shouldShowImportantSitesDialog() {
if (!ChromeFeatureList.isEnabled(ChromeFeatureList.IMPORTANT_SITES_IN_CBD)) return false;
EnumSet<DialogOption> selectedOptions = getSelectedOptions();
if (!selectedOptions.contains(DialogOption.CLEAR_CACHE)
&& !selectedOptions.contains(DialogOption.CLEAR_COOKIES_AND_SITE_DATA)) {
return false;
}
boolean haveImportantSites =
mSortedImportantDomains != null && mSortedImportantDomains.length != 0;
RecordHistogram.recordBooleanHistogram(
"History.ClearBrowsingData.ImportantDialogShown", haveImportantSites);
return haveImportantSites;
}
/**
* Transfers a prerendered WebContents if one exists.
*
* This resets the internal WebContents; a subsequent call to this method
* returns null. Must be called from the UI thread.
* If a prerender exists for a different URL with the same sessionId or with
* a different referrer, then this is treated as a mispredict from the
* client application, and cancels the previous prerender. This is done to
* avoid keeping resources laying around for too long, but is subject to a
* race condition, as the following scenario is possible:
* The application calls:
* 1. mayLaunchUrl(url1) <- IPC
* 2. loadUrl(url2) <- Intent
* 3. mayLaunchUrl(url3) <- IPC
* If the IPC for url3 arrives before the intent for url2, then this methods
* cancels the prerender for url3, which is unexpected. On the other
* hand, not cancelling the previous prerender leads to wasted resources, as
* a WebContents is lingering. This can be solved by requiring applications
* to call mayLaunchUrl(null) to cancel a current prerender before 2, that
* is for a mispredict.
*
* Note that this methods accepts URLs that don't exactly match the initially
* prerendered URL. More precisely, the #fragment is ignored. In this case,
* the client needs to navigate to the correct URL after the WebContents
* swap. This can be tested using {@link UrlUtilities#urlsFragmentsDiffer()}.
*
* @param session The Binder object identifying a session.
* @param url The URL the WebContents is for.
* @param referrer The referrer to use for |url|.
* @return The prerendered WebContents, or null.
*/
WebContents takePrerenderedUrl(CustomTabsSessionToken session, String url, String referrer) {
ThreadUtils.assertOnUiThread();
if (mSpeculation == null || session == null || !session.equals(mSpeculation.session)) {
return null;
}
if (mSpeculation.prefetchOnly) {
Profile profile = Profile.getLastUsedProfile();
new ResourcePrefetchPredictor(profile).stopPrefetching(mSpeculation.url);
mSpeculation = null;
return null;
}
WebContents webContents = mSpeculation.webContents;
String prerenderedUrl = mSpeculation.url;
String prerenderReferrer = mSpeculation.referrer;
if (referrer == null) referrer = "";
boolean ignoreFragments = mClientManager.getIgnoreFragmentsForSession(session);
boolean urlsMatch = TextUtils.equals(prerenderedUrl, url)
|| (ignoreFragments
&& UrlUtilities.urlsMatchIgnoringFragments(prerenderedUrl, url));
WebContents result = null;
if (urlsMatch && TextUtils.equals(prerenderReferrer, referrer)) {
result = webContents;
mSpeculation = null;
} else {
cancelPrerender(session);
}
if (!mClientManager.usesDefaultSessionParameters(session) && webContents != null) {
RecordHistogram.recordBooleanHistogram(
"CustomTabs.NonDefaultSessionPrerenderMatched", result != null);
}
return result;
}
private static void handleTime(Context context, String key, long duration, TimeUnit tu) {
if (sUploadAllowed) {
RecordHistogram.recordTimesHistogram(key, duration, tu);
} else {
storeValue(context, key, duration);
}
}
private static void recordShareHistograms(int count, int filterType) {
RecordHistogram.recordEnumeratedHistogram("Android.DownloadManager.Share.FileTypes",
filterType, DownloadFilter.FILTER_BOUNDARY);
RecordHistogram.recordLinearCountHistogram("Android.DownloadManager.Share.Count",
count, 1, 20, 20);
}
@Override
public void notifyDataSetChanged() {
mGroups.clear();
addGroup(mRecentlyClosedTabsGroup);
for (ForeignSession session : mRecentTabsManager.getForeignSessions()) {
if (!mHasForeignDataRecorded) {
RecordHistogram.recordEnumeratedHistogram("HistoryPage.OtherDevicesMenu",
OtherSessionsActions.HAS_FOREIGN_DATA, OtherSessionsActions.LIMIT);
mHasForeignDataRecorded = true;
}
addGroup(new ForeignSessionGroup(session));
}
if (mRecentTabsManager.shouldDisplaySyncPromo()) {
addGroup(new SyncPromoGroup());
}
// Add separator line after the recently closed tabs group.
int recentlyClosedIndex = mGroups.indexOf(mRecentlyClosedTabsGroup);
if (DeviceFormFactor.isTablet()) {
if (recentlyClosedIndex != mGroups.size() - 2) {
mGroups.set(recentlyClosedIndex + 1, mVisibleSeparatorGroup);
}
} else if (recentlyClosedIndex != mGroups.size() - 1) {
mGroups.add(recentlyClosedIndex + 1, mVisibleSeparatorGroup);
}
super.notifyDataSetChanged();
}
/**
* Logs whether a certain category of a blacklisted term resulted in the search results
* being seen.
* @param reason The given reason.
* @param wasSeen Whether the search results were seen.
*/
public static void logBlacklistSeen(BlacklistReason reason, boolean wasSeen) {
if (reason == null) reason = BlacklistReason.NONE;
int code = ContextualSearchBlacklist.getBlacklistMetricsCode(reason, wasSeen);
RecordHistogram.recordEnumeratedHistogram("Search.ContextualSearchBlacklistSeen",
code, ContextualSearchBlacklist.BLACKLIST_BOUNDARY);
}
/**
* Record if the remotely played media element is alive when the
* {@link ExpandedControllerActivity} is shown.
*
* @param isMediaElementAlive if the media element is alive.
*/
public static void recordFullscreenControlsShown(boolean isMediaElementAlive) {
if (LibraryLoader.isInitialized()) {
RecordHistogram.recordBooleanHistogram(
"Cast.Sender.MediaElementPresentWhenShowFullscreenControls",
isMediaElementAlive);
}
}