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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java

Issue 2843693002: Add UMA metrics regarding default browser status (Closed)
Patch Set: Rebased 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
index 5477da8e5d919194e7702f6de8d1c44b736d213d..ade647d7071acb690a9af43f7001d2414ec7e9f5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
@@ -6,30 +6,78 @@ package org.chromium.chrome.browser;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.AsyncTask;
+import android.support.annotation.IntDef;
+import android.text.TextUtils;
import org.chromium.base.BuildInfo;
import org.chromium.base.ContextUtils;
+import org.chromium.base.library_loader.LibraryProcessType;
+import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.content.browser.BrowserStartupController;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.RejectedExecutionException;
/**
* A utility class for querying information about the default browser setting.
*/
-public class DefaultBrowserInfo {
+public final class DefaultBrowserInfo {
private static final String SAMPLE_URL = "https://www.madeupdomainforcheck123.com/";
+ /**
+ * A list of potential default browser states. To add a type to this list please update
+ * MobileDefaultBrowserState in histograms.xml and make sure to keep this list in sync.
+ * Additions should be treated as APPEND ONLY to keep the UMA metric semantics the same over
+ * time.
+ */
+ @IntDef({
+ MobileDefaultBrowserState.NO_DEFAULT,
+ MobileDefaultBrowserState.CHROME_SYSTEM_DEFAULT,
+ MobileDefaultBrowserState.CHROME_INSTALLED_DEFAULT,
+ MobileDefaultBrowserState.OTHER_SYSTEM_DEFAULT,
+ MobileDefaultBrowserState.OTHER_INSTALLED_DEFAULT,
+
+ MobileDefaultBrowserState.BOUNDARY,
+ })
+ private @interface MobileDefaultBrowserState {
+ int NO_DEFAULT = 0;
+ int CHROME_SYSTEM_DEFAULT = 1;
+ int CHROME_INSTALLED_DEFAULT = 2;
+ int OTHER_SYSTEM_DEFAULT = 3;
+ int OTHER_INSTALLED_DEFAULT = 4;
+ int BOUNDARY = 5;
+ }
+
+ /**
+ * Helper class for passing information about the system's default browser settings back from a
+ * worker task.
+ */
+ private static class DefaultInfo {
+ public boolean isChromeDefault;
+ public boolean isDefaultSystem;
+ public boolean hasDefault;
+ public int browserCount;
+ }
+
/** A lock to synchronize background tasks to retrieve browser information. */
private static final Object sDirCreationLock = new Object();
private static AsyncTask<Void, Void, ArrayList<String>> sDefaultBrowserFetcher;
+ /** Don't instantiate me. */
+ private DefaultBrowserInfo() {}
+
/**
* Initialize an AsyncTask for getting menu title of opening a link in default browser.
*/
@@ -102,4 +150,89 @@ public class DefaultBrowserInfo {
R.string.menu_open_in_product_default);
}
}
+
+ /**
+ * Log statistics about the current default browser to UMA.
+ */
+ public static void logDefaultBrowserStats() {
+ assert BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER)
+ .isStartupSuccessfullyCompleted();
+
+ try {
+ new AsyncTask<Context, Void, DefaultInfo>() {
+ @Override
+ protected DefaultInfo doInBackground(Context... params) {
+ Context context = params[0];
+
+ PackageManager pm = context.getPackageManager();
+
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(SAMPLE_URL));
+
+ DefaultInfo info = new DefaultInfo();
+
+ // Query the default handler first.
+ ResolveInfo defaultRi = pm.resolveActivity(intent, 0);
+ if (defaultRi != null && defaultRi.match != 0) {
+ info.hasDefault = true;
+ info.isChromeDefault = isSamePackage(context, defaultRi);
+ info.isDefaultSystem = isSystemPackage(defaultRi);
+ }
+
+ // Query all other intent handlers.
+ Set<String> uniquePackages = new HashSet<>();
+ List<ResolveInfo> ris =
+ pm.queryIntentActivities(intent, PackageManager.MATCH_ALL);
+ for (ResolveInfo ri : ris) {
+ uniquePackages.add(ri.activityInfo.applicationInfo.packageName);
+ }
+
+ info.browserCount = uniquePackages.size();
+
+ return info;
+ }
+
+ @Override
+ protected void onPostExecute(DefaultInfo info) {
+ if (info == null) return;
+
+ RecordHistogram.recordCount100Histogram(
+ getDefaultBrowserCountUmaName(info), info.browserCount);
+ RecordHistogram.recordEnumeratedHistogram("Mobile.DefaultBrowser.State",
+ getDefaultBrowserUmaState(info), MobileDefaultBrowserState.BOUNDARY);
+ }
+ }
+ .executeOnExecutor(
+ AsyncTask.THREAD_POOL_EXECUTOR, ContextUtils.getApplicationContext());
+ } catch (RejectedExecutionException ex) {
+ // Fail silently here since this is not a critical task.
+ }
+ }
+
+ private static String getDefaultBrowserCountUmaName(DefaultInfo info) {
+ if (!info.hasDefault) return "Mobile.DefaultBrowser.BrowserCount.NoDefault";
+ if (info.isChromeDefault) return "Mobile.DefaultBrowser.BrowserCount.ChromeDefault";
+ return "Mobile.DefaultBrowser.BrowserCount.OtherDefault";
+ }
+
+ private static @MobileDefaultBrowserState int getDefaultBrowserUmaState(DefaultInfo info) {
+ if (!info.hasDefault) return MobileDefaultBrowserState.NO_DEFAULT;
+
+ if (info.isChromeDefault) {
+ if (info.isDefaultSystem) return MobileDefaultBrowserState.CHROME_SYSTEM_DEFAULT;
+ return MobileDefaultBrowserState.CHROME_INSTALLED_DEFAULT;
+ }
+
+ if (info.isDefaultSystem) return MobileDefaultBrowserState.OTHER_SYSTEM_DEFAULT;
+ return MobileDefaultBrowserState.OTHER_INSTALLED_DEFAULT;
+ }
+
+ private static boolean isSamePackage(Context context, ResolveInfo info) {
+ return TextUtils.equals(
+ context.getPackageName(), info.activityInfo.applicationInfo.packageName);
+ }
+
+ private static boolean isSystemPackage(ResolveInfo info) {
+ return (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ }
}
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698