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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java

Issue 1325213002: customtabs: UMA histogram tracking whether clients call warmup(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 3 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.customtabs; 5 package org.chromium.chrome.browser.customtabs;
6 6
7 import android.app.ActivityManager; 7 import android.app.ActivityManager;
8 import android.app.Application; 8 import android.app.Application;
9 import android.content.ComponentName; 9 import android.content.ComponentName;
10 import android.content.Context; 10 import android.content.Context;
11 import android.content.Intent; 11 import android.content.Intent;
12 import android.content.ServiceConnection; 12 import android.content.ServiceConnection;
13 import android.content.pm.PackageManager; 13 import android.content.pm.PackageManager;
14 import android.content.res.Resources; 14 import android.content.res.Resources;
15 import android.graphics.Point; 15 import android.graphics.Point;
16 import android.net.ConnectivityManager; 16 import android.net.ConnectivityManager;
17 import android.net.Uri; 17 import android.net.Uri;
18 import android.os.AsyncTask; 18 import android.os.AsyncTask;
19 import android.os.Binder; 19 import android.os.Binder;
20 import android.os.Build; 20 import android.os.Build;
21 import android.os.Bundle; 21 import android.os.Bundle;
22 import android.os.IBinder; 22 import android.os.IBinder;
23 import android.os.Process; 23 import android.os.Process;
24 import android.os.RemoteException; 24 import android.os.RemoteException;
25 import android.os.SystemClock; 25 import android.os.SystemClock;
26 import android.support.customtabs.ICustomTabsCallback; 26 import android.support.customtabs.ICustomTabsCallback;
27 import android.support.customtabs.ICustomTabsService; 27 import android.support.customtabs.ICustomTabsService;
28 import android.text.TextUtils; 28 import android.text.TextUtils;
29 import android.util.SparseArray; 29 import android.util.SparseArray;
30 import android.util.SparseBooleanArray;
30 import android.view.WindowManager; 31 import android.view.WindowManager;
31 32
32 import org.chromium.base.FieldTrialList; 33 import org.chromium.base.FieldTrialList;
33 import org.chromium.base.Log; 34 import org.chromium.base.Log;
34 import org.chromium.base.ThreadUtils; 35 import org.chromium.base.ThreadUtils;
35 import org.chromium.base.VisibleForTesting; 36 import org.chromium.base.VisibleForTesting;
36 import org.chromium.base.annotations.SuppressFBWarnings; 37 import org.chromium.base.annotations.SuppressFBWarnings;
37 import org.chromium.base.library_loader.ProcessInitException; 38 import org.chromium.base.library_loader.ProcessInitException;
38 import org.chromium.base.metrics.RecordHistogram; 39 import org.chromium.base.metrics.RecordHistogram;
39 import org.chromium.chrome.R; 40 import org.chromium.chrome.R;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 private static final String TAG = "cr.ChromeConnection"; 73 private static final String TAG = "cr.ChromeConnection";
73 @VisibleForTesting 74 @VisibleForTesting
74 static final String NO_PRERENDERING_KEY = 75 static final String NO_PRERENDERING_KEY =
75 "android.support.customtabs.maylaunchurl.NO_PRERENDERING"; 76 "android.support.customtabs.maylaunchurl.NO_PRERENDERING";
76 77
77 // Values for the "CustomTabs.PredictionStatus" UMA histogram. Append-only. 78 // Values for the "CustomTabs.PredictionStatus" UMA histogram. Append-only.
78 private static final int NO_PREDICTION = 0; 79 private static final int NO_PREDICTION = 0;
79 private static final int GOOD_PREDICTION = 1; 80 private static final int GOOD_PREDICTION = 1;
80 private static final int BAD_PREDICTION = 2; 81 private static final int BAD_PREDICTION = 2;
81 private static final int PREDICTION_STATUS_COUNT = 3; 82 private static final int PREDICTION_STATUS_COUNT = 3;
83 // Values for the "CustomTabs.CalledWarmup" UMA histogram. Append-only.
pasko 2015/09/03 18:02:19 nittynit: empty line above would look nicer
Benoit L 2015/09/29 09:04:23 Ack.
84 private static final int NO_SESSION_NO_WARMUP = 0;
85 private static final int NO_SESSION_WARMUP = 1;
86 private static final int SESSION_NO_WARMUP_ALREADY_CALLED = 2;
87 private static final int SESSION_NO_WARMUP_NOT_CALLED = 3;
88 private static final int SESSION_WARMUP = 4;
89 private static final int SESSION_WARMUP_COUNT = 5;
82 90
83 private static AtomicReference<CustomTabsConnection> sInstance = 91 private static AtomicReference<CustomTabsConnection> sInstance =
84 new AtomicReference<CustomTabsConnection>(); 92 new AtomicReference<CustomTabsConnection>();
85 93
86 private static final class PrerenderedUrlParams { 94 private static final class PrerenderedUrlParams {
87 public final IBinder mSession; 95 public final IBinder mSession;
88 public final WebContents mWebContents; 96 public final WebContents mWebContents;
89 public final String mUrl; 97 public final String mUrl;
90 public final String mReferrer; 98 public final String mReferrer;
91 public final Bundle mExtras; 99 public final Bundle mExtras;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 192
185 public String getPredictedUrl() { 193 public String getPredictedUrl() {
186 return mPredictedUrl; 194 return mPredictedUrl;
187 } 195 }
188 196
189 public long getLastMayLaunchUrlTimestamp() { 197 public long getLastMayLaunchUrlTimestamp() {
190 return mLastMayLaunchUrlTimestamp; 198 return mLastMayLaunchUrlTimestamp;
191 } 199 }
192 } 200 }
193 201
194 private final Object mLock = new Object(); 202 private final Object mLock = new Object();
pasko 2015/09/03 18:02:20 please add a comment saying something like: 'mLock
Benoit L 2015/09/29 09:04:23 Refactored this, so... done?
195 private final Map<IBinder, SessionParams> mSessionParams = new HashMap<>(); 203 private final Map<IBinder, SessionParams> mSessionParams = new HashMap<>();
196 // Prediction tracking is done by UID and not by session, since a 204 // Prediction tracking is done by UID and not by session, since a
197 // mis-behaving application can create a large number of sessions. 205 // mis-behaving application can create a large number of sessions.
198 private SparseArray<PredictionStats> mUidToPredictionsStats = new SparseArra y<>(); 206 private SparseArray<PredictionStats> mUidToPredictionsStats = new SparseArra y<>();
207 // Whether a client application has called warmup() in this instance lifetim e.
208 private SparseBooleanArray mUidHasCalledWarmup = new SparseBooleanArray();
199 209
200 /** 210 /**
201 * <strong>DO NOT CALL</strong> 211 * <strong>DO NOT CALL</strong>
202 * Public to be instanciable from {@link ChromeApplication}. This is however 212 * Public to be instanciable from {@link ChromeApplication}. This is however
203 * intended to be private. 213 * intended to be private.
204 */ 214 */
205 public CustomTabsConnection(Application application) { 215 public CustomTabsConnection(Application application) {
206 super(); 216 super();
207 mApplication = application; 217 mApplication = application;
208 } 218 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 mUidToPredictionsStats.put(uid, new PredictionStats()); 264 mUidToPredictionsStats.put(uid, new PredictionStats());
255 } 265 }
256 } 266 }
257 return true; 267 return true;
258 } 268 }
259 269
260 @Override 270 @Override
261 public boolean warmup(long flags) { 271 public boolean warmup(long flags) {
262 // Here and in mayLaunchUrl(), don't do expensive work for background ap plications. 272 // Here and in mayLaunchUrl(), don't do expensive work for background ap plications.
263 if (!isCallerForegroundOrSelf()) return false; 273 if (!isCallerForegroundOrSelf()) return false;
274
275 synchronized (mLock) {
276 mUidHasCalledWarmup.put(Binder.getCallingUid(), true);
277 }
278
264 if (!mWarmupHasBeenCalled.compareAndSet(false, true)) return true; 279 if (!mWarmupHasBeenCalled.compareAndSet(false, true)) return true;
265 // The call is non-blocking and this must execute on the UI thread, post a task. 280 // The call is non-blocking and this must execute on the UI thread, post a task.
266 ThreadUtils.postOnUiThread(new Runnable() { 281 ThreadUtils.postOnUiThread(new Runnable() {
267 @Override 282 @Override
268 @SuppressFBWarnings("DM_EXIT") 283 @SuppressFBWarnings("DM_EXIT")
269 public void run() { 284 public void run() {
270 ChromeApplication app = (ChromeApplication) mApplication; 285 ChromeApplication app = (ChromeApplication) mApplication;
271 try { 286 try {
272 app.startBrowserProcessesAndLoadLibrariesSync(true); 287 app.startBrowserProcessesAndLoadLibrariesSync(true);
273 } catch (ProcessInitException e) { 288 } catch (ProcessInitException e) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 } 392 }
378 393
379 /** 394 /**
380 * Registers a launch of a |url| for a given |session|. 395 * Registers a launch of a |url| for a given |session|.
381 * 396 *
382 * This is used for accounting. 397 * This is used for accounting.
383 */ 398 */
384 void registerLaunch(IBinder session, String url) { 399 void registerLaunch(IBinder session, String url) {
385 int outcome; 400 int outcome;
386 long elapsedTimeMs = -1; 401 long elapsedTimeMs = -1;
402 boolean hasValidSession = false;
403 boolean hasUidCalledWarmup = false;
387 synchronized (mLock) { 404 synchronized (mLock) {
388 SessionParams sessionParams = mSessionParams.get(session); 405 SessionParams sessionParams = mSessionParams.get(session);
389 if (sessionParams == null) { 406 if (sessionParams == null) {
390 outcome = NO_PREDICTION; 407 outcome = NO_PREDICTION;
391 } else { 408 } else {
409 hasValidSession = true;
410 hasUidCalledWarmup = mUidHasCalledWarmup.get(sessionParams.mUid) ;
411
392 String predictedUrl = sessionParams.getPredictedUrl(); 412 String predictedUrl = sessionParams.getPredictedUrl();
393 outcome = predictedUrl == null ? NO_PREDICTION 413 outcome = predictedUrl == null ? NO_PREDICTION
394 : predictedUrl.equals(url) ? GOOD_PREDICTION : BAD_PREDI CTION; 414 : predictedUrl.equals(url) ? GOOD_PREDICTION : BAD_PREDI CTION;
395 elapsedTimeMs = SystemClock.elapsedRealtime() 415 elapsedTimeMs = SystemClock.elapsedRealtime()
396 - sessionParams.getLastMayLaunchUrlTimestamp(); 416 - sessionParams.getLastMayLaunchUrlTimestamp();
397 sessionParams.setPredictionMetrics(null, 0); 417 sessionParams.setPredictionMetrics(null, 0);
398 if (outcome == GOOD_PREDICTION) { 418 if (outcome == GOOD_PREDICTION) {
399 // If the prediction was correct, back to the smallest 419 // If the prediction was correct, back to the smallest
400 // throttling level. 420 // throttling level.
401 mUidToPredictionsStats.put(sessionParams.mUid, new Predictio nStats()); 421 mUidToPredictionsStats.put(sessionParams.mUid, new Predictio nStats());
402 } 422 }
403 } 423 }
404 } 424 }
405 RecordHistogram.recordEnumeratedHistogram( 425 RecordHistogram.recordEnumeratedHistogram(
406 "CustomTabs.PredictionStatus", outcome, PREDICTION_STATUS_COUNT) ; 426 "CustomTabs.PredictionStatus", outcome, PREDICTION_STATUS_COUNT) ;
407 if (outcome == GOOD_PREDICTION) { 427 if (outcome == GOOD_PREDICTION) {
408 RecordHistogram.recordCustomTimesHistogram("CustomTabs.PredictionToL aunch", 428 RecordHistogram.recordCustomTimesHistogram("CustomTabs.PredictionToL aunch",
409 elapsedTimeMs, 1, TimeUnit.MINUTES.toMillis(3), TimeUnit.MIL LISECONDS, 100); 429 elapsedTimeMs, 1, TimeUnit.MINUTES.toMillis(3), TimeUnit.MIL LISECONDS, 100);
410 } 430 }
431 // CustomTabs.CalledWarmup histogram.
432 boolean warmupCalled = mWarmupHasBeenCalled.get();
433 int warmupKind = warmupCalled ? NO_SESSION_WARMUP : NO_SESSION_NO_WARMUP ;
434 if (hasValidSession) {
435 if (hasUidCalledWarmup) {
436 warmupKind = SESSION_WARMUP;
437 } else {
438 warmupKind = warmupCalled ? SESSION_NO_WARMUP_ALREADY_CALLED
439 : SESSION_NO_WARMUP_NOT_CALLED;
440 }
441 }
442 RecordHistogram.recordEnumeratedHistogram(
443 "CustomTabs.CalledWarmup", warmupKind, SESSION_WARMUP_COUNT);
411 } 444 }
412 445
413 /** 446 /**
414 * Transfers a prerendered WebContents if one exists. 447 * Transfers a prerendered WebContents if one exists.
415 * 448 *
416 * This resets the internal WebContents; a subsequent call to this method 449 * This resets the internal WebContents; a subsequent call to this method
417 * returns null. Must be called from the UI thread. 450 * returns null. Must be called from the UI thread.
418 * If a prerender exists for a different URL with the same sessionId or with 451 * If a prerender exists for a different URL with the same sessionId or with
419 * a different referrer, then this is treated as a mispredict from the 452 * a different referrer, then this is treated as a mispredict from the
420 * client application, and cancels the previous prerender. This is done to 453 * client application, and cancels the previous prerender. This is done to
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 } 663 }
631 664
632 /** 665 /**
633 * Called when a remote client has died. 666 * Called when a remote client has died.
634 */ 667 */
635 private void cleanupAlreadyLocked(IBinder session) { 668 private void cleanupAlreadyLocked(IBinder session) {
636 ThreadUtils.assertOnUiThread(); 669 ThreadUtils.assertOnUiThread();
637 SessionParams params = mSessionParams.get(session); 670 SessionParams params = mSessionParams.get(session);
638 if (params == null) return; 671 if (params == null) return;
639 mSessionParams.remove(session); 672 mSessionParams.remove(session);
673 mUidHasCalledWarmup.delete(params.mUid);
640 IBinder binder = params.mCallback.asBinder(); 674 IBinder binder = params.mCallback.asBinder();
641 binder.unlinkToDeath(params.mDeathRecipient, 0); 675 binder.unlinkToDeath(params.mDeathRecipient, 0);
642 if (mPrerender != null && session.equals(mPrerender.mSession)) { 676 if (mPrerender != null && session.equals(mPrerender.mSession)) {
643 prerenderUrl(session, null, null); // Cancels the pre-render. 677 prerenderUrl(session, null, null); // Cancels the pre-render.
644 } 678 }
645 } 679 }
646 680
647 private boolean mayPrerender() { 681 private boolean mayPrerender() {
648 if (FieldTrialList.findFullName("CustomTabs").equals("DisablePrerender") ) return false; 682 if (FieldTrialList.findFullName("CustomTabs").equals("DisablePrerender") ) return false;
649 if (!DeviceClassManager.enablePrerendering()) return false; 683 if (!DeviceClassManager.enablePrerendering()) return false;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 return screenSize; 751 return screenSize;
718 } 752 }
719 753
720 @VisibleForTesting 754 @VisibleForTesting
721 void resetThrottling(int uid) { 755 void resetThrottling(int uid) {
722 synchronized (mLock) { 756 synchronized (mLock) {
723 mUidToPredictionsStats.put(uid, new PredictionStats()); 757 mUidToPredictionsStats.put(uid, new PredictionStats());
724 } 758 }
725 } 759 }
726 } 760 }
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | tools/metrics/histograms/histograms.xml » ('J')

Powered by Google App Engine
This is Rietveld 408576698