OSDN Git Service

Created metric events for scoped directory access API.
authorFelipe Leme <felipeal@google.com>
Wed, 24 Feb 2016 18:17:41 +0000 (10:17 -0800)
committerFelipe Leme <felipeal@google.com>
Tue, 1 Mar 2016 18:12:58 +0000 (10:12 -0800)
BUG: 27334821
Change-Id: I8a1bfc328dcd26b42bb66884d14b34ad11aa232f

core/java/android/os/Environment.java
packages/DocumentsUI/src/com/android/documentsui/Metrics.java
packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
proto/src/metrics_constants.proto

index 1085b1e..2410503 100644 (file)
@@ -493,7 +493,7 @@ public class Environment {
      * </ul>
      * @hide
      */
-    private static final String[] STANDARD_DIRECTORIES = {
+    public static final String[] STANDARD_DIRECTORIES = {
             DIRECTORY_MUSIC,
             DIRECTORY_PODCASTS,
             DIRECTORY_RINGTONES,
index bff65d5..dcaea15 100644 (file)
 
 package com.android.documentsui;
 
+import static android.os.Environment.STANDARD_DIRECTORIES;
 import static com.android.documentsui.Shared.DEBUG;
-
 import android.annotation.IntDef;
 import android.annotation.Nullable;
+import android.annotation.StringDef;
+import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
@@ -32,6 +34,7 @@ import com.android.documentsui.model.RootInfo;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -376,6 +379,84 @@ public final class Metrics {
         logHistogram(context, histogram, getOpCode(operationType, PROVIDER_INTRA));
     }
 
+    // Types for logInvalidScopedAccessRequest
+    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS =
+            "scoped_directory_access_invalid_args";
+    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY =
+            "scoped_directory_access_invalid_dir";
+    public static final String SCOPED_DIRECTORY_ACCESS_ERROR =
+            "scoped_directory_access_error";
+
+    @StringDef(value = {
+            SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS,
+            SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY,
+            SCOPED_DIRECTORY_ACCESS_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InvalidScopedAccess{}
+
+    public static void logInvalidScopedAccessRequest(Context context,
+            @InvalidScopedAccess String type) {
+        MetricsLogger.count(context, type, 1);
+        switch (type) {
+            case SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS:
+            case SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY:
+            case SCOPED_DIRECTORY_ACCESS_ERROR:
+                MetricsLogger.count(context, type, 1);
+                break;
+            default:
+                Log.wtf(TAG, "invalid InvalidScopedAccess: " + type);
+        }
+    }
+
+    // Types for logValidScopedAccessRequest
+    public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED = 0;
+    public static final int SCOPED_DIRECTORY_ACCESS_GRANTED = 1;
+    public static final int SCOPED_DIRECTORY_ACCESS_DENIED = 2;
+
+    @IntDef(flag = true, value = {
+            SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED,
+            SCOPED_DIRECTORY_ACCESS_GRANTED,
+            SCOPED_DIRECTORY_ACCESS_DENIED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScopedAccessGrant {}
+
+    public static void logValidScopedAccessRequest(Activity activity, String directory,
+            @ScopedAccessGrant int type) {
+        int index = -1;
+        for (int i = 0; i < STANDARD_DIRECTORIES.length; i++) {
+            if (STANDARD_DIRECTORIES[i].equals(directory)) {
+                index = i;
+                break;
+            }
+        }
+        final String packageName = activity.getCallingPackage();
+        switch (type) {
+            case SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED:
+                MetricsLogger.action(activity,
+                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE,
+                        packageName);
+                MetricsLogger.action(activity,
+                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER, index);
+                break;
+            case SCOPED_DIRECTORY_ACCESS_GRANTED:
+                MetricsLogger.action(activity,
+                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity,
+                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER, index);
+                break;
+            case SCOPED_DIRECTORY_ACCESS_DENIED:
+                MetricsLogger.action(activity,
+                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity,
+                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER, index);
+                break;
+            default:
+                Log.wtf(TAG, "invalid ScopedAccessGrant: " + type);
+        }
+    }
+
     /**
      * Internal method for making a MetricsLogger.count call. Increments the given counter by 1.
      *
index 27d6797..dc529ce 100644 (file)
 package com.android.documentsui;
 
 import static android.os.Environment.isStandardDirectory;
+import static android.os.Environment.STANDARD_DIRECTORIES;
 import static android.os.storage.StorageVolume.EXTRA_DIRECTORY_NAME;
 import static android.os.storage.StorageVolume.EXTRA_STORAGE_VOLUME;
 import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.Metrics.logInvalidScopedAccessRequest;
+import static com.android.documentsui.Metrics.logValidScopedAccessRequest;
+import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED;
+import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_DENIED;
+import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ERROR;
+import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_GRANTED;
+import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS;
+import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY;
 
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -73,6 +82,7 @@ public class OpenExternalDirectoryActivity extends Activity {
         final Intent intent = getIntent();
         if (intent == null) {
             if (DEBUG) Log.d(TAG, "missing intent");
+            logInvalidScopedAccessRequest(this, SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS);
             setResult(RESULT_CANCELED);
             finish();
             return;
@@ -82,12 +92,14 @@ public class OpenExternalDirectoryActivity extends Activity {
             if (DEBUG)
                 Log.d(TAG, "extra " + EXTRA_STORAGE_VOLUME + " is not a StorageVolume: "
                         + storageVolume);
+            logInvalidScopedAccessRequest(this, SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS);
             setResult(RESULT_CANCELED);
             finish();
             return;
         }
         final String directoryName = intent.getStringExtra(EXTRA_DIRECTORY_NAME);
         if (directoryName == null) {
+            logInvalidScopedAccessRequest(this, SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS);
             if (DEBUG) Log.d(TAG, "missing extra " + EXTRA_DIRECTORY_NAME + " on " + intent);
             setResult(RESULT_CANCELED);
             finish();
@@ -125,6 +137,7 @@ public class OpenExternalDirectoryActivity extends Activity {
         } catch (IOException e) {
             Log.e(TAG, "Could not get canonical file for volume " + storageVolume.dump()
                     + " and directory " + directoryName);
+            logInvalidScopedAccessRequest(activity, SCOPED_DIRECTORY_ACCESS_ERROR);
             return false;
         }
         final StorageManager sm =
@@ -138,6 +151,7 @@ public class OpenExternalDirectoryActivity extends Activity {
             if (DEBUG)
                 Log.d(TAG, "Directory '" + directory + "' is not standard (full path: '"
                         + file.getAbsolutePath() + "')");
+            logInvalidScopedAccessRequest(activity, SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY);
             return false;
         }
 
@@ -159,6 +173,8 @@ public class OpenExternalDirectoryActivity extends Activity {
         // Checks if the user has granted the permission already.
         final Intent intent = getIntentForExistingPermission(activity, file);
         if (intent != null) {
+            logValidScopedAccessRequest(activity, directory,
+                    SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED);
             activity.setResult(RESULT_OK, intent);
             activity.finish();
             return true;
@@ -166,12 +182,14 @@ public class OpenExternalDirectoryActivity extends Activity {
 
         if (volumeLabel == null) {
             Log.e(TAG, "Could not get volume for " + file);
+            logInvalidScopedAccessRequest(activity, SCOPED_DIRECTORY_ACCESS_ERROR);
             return false;
         }
 
         // Gets the package label.
         final String appLabel = getAppLabel(activity);
         if (appLabel == null) {
+            // Error already logged.
             return false;
         }
 
@@ -198,6 +216,7 @@ public class OpenExternalDirectoryActivity extends Activity {
         try {
             return pm.getApplicationLabel(pm.getApplicationInfo(packageName, 0)).toString();
         } catch (NameNotFoundException e) {
+            logInvalidScopedAccessRequest(activity, SCOPED_DIRECTORY_ACCESS_ERROR);
             Log.w(TAG, "Could not get label for package " + packageName);
             return null;
         }
@@ -217,18 +236,21 @@ public class OpenExternalDirectoryActivity extends Activity {
         return volume.isVisibleForWrite(userId) && root.equals(path);
     }
 
-    private static Uri getGrantedUriPermission(ContentProviderClient provider, File file) {
+    private static Uri getGrantedUriPermission(Context context, ContentProviderClient provider,
+            File file) {
         // Calls ExternalStorageProvider to get the doc id for the file
         final Bundle bundle;
         try {
             bundle = provider.call("getDocIdForFileCreateNewDir", file.getPath(), null);
         } catch (RemoteException e) {
             Log.e(TAG, "Did not get doc id from External Storage provider for " + file, e);
+            logInvalidScopedAccessRequest(context, SCOPED_DIRECTORY_ACCESS_ERROR);
             return null;
         }
         final String docId = bundle == null ? null : bundle.getString("DOC_ID");
         if (docId == null) {
             Log.e(TAG, "Did not get doc id from External Storage provider for " + file);
+            logInvalidScopedAccessRequest(context, SCOPED_DIRECTORY_ACCESS_ERROR);
             return null;
         }
         Log.d(TAG, "doc id for " + file + ": " + docId);
@@ -242,9 +264,9 @@ public class OpenExternalDirectoryActivity extends Activity {
         return uri;
     }
 
-    private static Intent createGrantedUriPermissionsIntent(ContentProviderClient provider,
-            File file) {
-        final Uri uri = getGrantedUriPermission(provider, file);
+    private static Intent createGrantedUriPermissionsIntent(Context context,
+            ContentProviderClient provider, File file) {
+        final Uri uri = getGrantedUriPermission(context, provider, file);
         return createGrantedUriPermissionsIntent(uri);
     }
 
@@ -261,7 +283,8 @@ public class OpenExternalDirectoryActivity extends Activity {
     private static Intent getIntentForExistingPermission(OpenExternalDirectoryActivity activity,
             File file) {
         final String packageName = activity.getCallingPackage();
-        final Uri grantedUri = getGrantedUriPermission(activity.getExternalStorageClient(), file);
+        final Uri grantedUri =
+                getGrantedUriPermission(activity, activity.getExternalStorageClient(), file);
         if (DEBUG)
             Log.d(TAG, "checking if " + packageName + " already has permission for " + grantedUri);
         final ActivityManager am =
@@ -298,7 +321,7 @@ public class OpenExternalDirectoryActivity extends Activity {
 
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final String folder = mFile.getName();
+            final String directory = mFile.getName();
             final Activity activity = getActivity();
             final OnClickListener listener = new OnClickListener() {
 
@@ -306,12 +329,16 @@ public class OpenExternalDirectoryActivity extends Activity {
                 public void onClick(DialogInterface dialog, int which) {
                     Intent intent = null;
                     if (which == DialogInterface.BUTTON_POSITIVE) {
-                        intent = createGrantedUriPermissionsIntent(
+                        intent = createGrantedUriPermissionsIntent(mActivity,
                                 mActivity.getExternalStorageClient(), mFile);
                     }
                     if (which == DialogInterface.BUTTON_NEGATIVE || intent == null) {
+                        logValidScopedAccessRequest(activity, directory,
+                                SCOPED_DIRECTORY_ACCESS_DENIED);
                         activity.setResult(RESULT_CANCELED);
                     } else {
+                        logValidScopedAccessRequest(activity, directory,
+                                SCOPED_DIRECTORY_ACCESS_GRANTED);
                         activity.setResult(RESULT_OK, intent);
                     }
                     activity.finish();
@@ -320,7 +347,7 @@ public class OpenExternalDirectoryActivity extends Activity {
 
             final CharSequence message = TextUtils
                     .expandTemplate(
-                            getText(R.string.open_external_dialog_request), mAppLabel, folder,
+                            getText(R.string.open_external_dialog_request), mAppLabel, directory,
                             mVolumeLabel);
             return new AlertDialog.Builder(activity, R.style.AlertDialogTheme)
                     .setMessage(message)
@@ -333,6 +360,7 @@ public class OpenExternalDirectoryActivity extends Activity {
         public void onCancel(DialogInterface dialog) {
             super.onCancel(dialog);
             final Activity activity = getActivity();
+            logValidScopedAccessRequest(activity, mFile.getName(), SCOPED_DIRECTORY_ACCESS_DENIED);
             activity.setResult(RESULT_CANCELED);
             activity.finish();
         }
index 471feef..ec09b13 100644 (file)
@@ -478,5 +478,30 @@ message MetricsEvent {
     // Logged when we execute an app transition. This indicates the device uptime in seconds when
     // the transition was executed.
     APP_TRANSITION_DEVICE_UPTIME_SECONDS = 325;
+
+    // User granted access to the request folder; action takes an integer
+    // representing the folder's index on Environment.STANDARD_DIRECTORIES
+    ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER = 326;
+
+    // User denied access to the request folder; action takes an integer
+    // representing the folder's index on Environment.STANDARD_DIRECTORIES
+    ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER = 327;
+
+    // User granted access to the request folder; action pass package name
+    // of calling package.
+    ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE = 328;
+
+    // User denied access to the request folder; action pass package name
+    // of calling package.
+    ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE = 329;
+
+    // App requested access to a directory it has already been granted
+    // access before; action takes an integer representing the folder's
+    // index on Environment.STANDARD_DIRECTORIES
+    ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER = 330;
+
+    // App requested access to a directory it has already been granted
+    // access before; action pass package name of calling package.
+    ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE = 331;
   }
 }