Migration to Westworld (1/2)

Migrate existing MetricsLogger to DocumentsStatsLog

Bug: 111552654
Test: atest DocumentsUITests
Change-Id: I4d6d4b13cefeeefd06b844ff07a0ccc3ef606c3e
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java
index ed17216..45f48d3 100644
--- a/src/com/android/documentsui/AbstractActionHandler.java
+++ b/src/com/android/documentsui/AbstractActionHandler.java
@@ -213,7 +213,7 @@
 
     @Override
     public void openInNewWindow(DocumentStack path) {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_NEW_WINDOW);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_NEW_WINDOW);
 
         Intent intent = LauncherActivity.createLaunchIntent(mActivity);
         intent.putExtra(Shared.EXTRA_STACK, (Parcelable) path);
@@ -275,7 +275,7 @@
 
     @Override
     public void selectAllFiles() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_SELECT_ALL);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_SELECT_ALL);
         Model model = mInjector.getModel();
 
         // Exclude disabled files
@@ -303,7 +303,7 @@
 
     @Override
     public void showCreateDirectoryDialog() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_CREATE_DIR);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_CREATE_DIR);
 
         CreateDirectoryFragment.show(mActivity.getSupportFragmentManager());
     }
@@ -528,12 +528,12 @@
             mState.stack.reset(stack);
             mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
 
-            Metrics.logLaunchAtLocation(mActivity, mState, stack.getRoot().getUri());
+            Metrics.logLaunchAtLocation(mState, stack.getRoot().getUri());
         } else {
             Log.w(TAG, "Failed to launch into the given uri. Launch to default location.");
             launchToDefaultLocation();
 
-            Metrics.logLaunchAtLocation(mActivity, mState, null);
+            Metrics.logLaunchAtLocation(mState, null);
         }
     }
 
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index e1e7af0..c57029e 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -141,7 +141,7 @@
         mInjector = getInjector();
         mState = getState(icicle);
         mDrawer = DrawerController.create(this, mInjector.config);
-        Metrics.logActivityLaunch(this, mState, intent);
+        Metrics.logActivityLaunch(mState, intent);
 
         mProviders = DocumentsApplication.getProvidersCache(this);
         mDocs = DocumentsAccess.create(this);
@@ -163,7 +163,7 @@
             @Override
             public void onSearchChanged(@Nullable String query) {
                 if (query != null) {
-                    Metrics.logUserAction(BaseActivity.this, Metrics.USER_ACTION_SEARCH);
+                    Metrics.logUserAction(MetricConsts.USER_ACTION_SEARCH);
                 }
 
                 mInjector.actions.loadDocumentsForCurrentStack();
@@ -512,8 +512,8 @@
      */
     private void onDisplayAdvancedDevices() {
         boolean display = !mState.showAdvanced;
-        Metrics.logUserAction(this,
-                display ? Metrics.USER_ACTION_SHOW_ADVANCED : Metrics.USER_ACTION_HIDE_ADVANCED);
+        Metrics.logUserAction(display
+                ? MetricConsts.USER_ACTION_SHOW_ADVANCED : MetricConsts.USER_ACTION_HIDE_ADVANCED);
 
         mInjector.prefs.setShowDeviceRoot(display);
         updateDisplayAdvancedDevices(display);
@@ -534,9 +534,9 @@
      */
     void setViewMode(@ViewMode int mode) {
         if (mode == State.MODE_GRID) {
-            Metrics.logUserAction(this, Metrics.USER_ACTION_GRID);
+            Metrics.logUserAction(MetricConsts.USER_ACTION_GRID);
         } else if (mode == State.MODE_LIST) {
-            Metrics.logUserAction(this, Metrics.USER_ACTION_LIST);
+            Metrics.logUserAction(MetricConsts.USER_ACTION_LIST);
         }
 
         LocalPreferences.setViewMode(this, getCurrentRoot(), mode);
@@ -759,8 +759,7 @@
                             finish();
                         }
 
-                        Metrics.logStartupMs(
-                                BaseActivity.this, (int) (new Date().getTime() - mStartTime));
+                        Metrics.logStartupMs((int) (new Date().getTime() - mStartTime));
 
                         // Remove the idle handler.
                         return false;
diff --git a/src/com/android/documentsui/CreateDirectoryFragment.java b/src/com/android/documentsui/CreateDirectoryFragment.java
index d20eee6..606678d 100644
--- a/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -163,11 +163,11 @@
             if (result != null) {
                 // Navigate into newly created child
                 mActivity.onDirectoryCreated(result);
-                Metrics.logCreateDirOperation(getContext());
+                Metrics.logCreateDirOperation();
             } else {
                 Snackbars.makeSnackbar(mActivity, R.string.create_error, Snackbar.LENGTH_SHORT)
                         .show();
-                Metrics.logCreateDirError(getContext());
+                Metrics.logCreateDirError();
             }
             mActivity.setPending(false);
         }
diff --git a/src/com/android/documentsui/DragAndDropManager.java b/src/com/android/documentsui/DragAndDropManager.java
index 55dff38..d49b689 100644
--- a/src/com/android/documentsui/DragAndDropManager.java
+++ b/src/com/android/documentsui/DragAndDropManager.java
@@ -440,9 +440,9 @@
             // is changed. The info about window should be passed in the localState then.
             // The localState could also be null for copying from Recents in single window
             // mode, but Recents doesn't offer this functionality (no directories).
-            Metrics.logUserAction(mContext,
-                    localState == null ? Metrics.USER_ACTION_DRAG_N_DROP_MULTI_WINDOW
-                            : Metrics.USER_ACTION_DRAG_N_DROP);
+            Metrics.logUserAction(
+                    localState == null ? MetricConsts.USER_ACTION_DRAG_N_DROP_MULTI_WINDOW
+                            : MetricConsts.USER_ACTION_DRAG_N_DROP);
 
             mClipper.copyFromClipData(dstStack, clipData, opType, callback);
         }
diff --git a/src/com/android/documentsui/MetricConsts.java b/src/com/android/documentsui/MetricConsts.java
new file mode 100644
index 0000000..6db30fa
--- /dev/null
+++ b/src/com/android/documentsui/MetricConsts.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * All constants are based on the enums in
+ * frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto.
+ */
+public class MetricConsts {
+
+    // Codes representing different root types.
+    public static final int ROOT_UNKNOWN = 0;
+    public static final int ROOT_NONE = 1;
+    public static final int ROOT_OTHER_DOCS_PROVIDER = 2;
+    public static final int ROOT_AUDIO = 3;
+    public static final int ROOT_DEVICE_STORAGE = 4;
+    public static final int ROOT_DOWNLOADS = 5;
+    public static final int ROOT_HOME = 6;
+    public static final int ROOT_IMAGES = 7;
+    public static final int ROOT_RECENTS = 8;
+    public static final int ROOT_VIDEOS = 9;
+    public static final int ROOT_MTP = 10;
+    public static final int ROOT_THIRD_PARTY_APP = 11;
+
+    @IntDef(flag = true, value = {
+            ROOT_UNKNOWN,
+            ROOT_NONE,
+            ROOT_OTHER_DOCS_PROVIDER,
+            ROOT_AUDIO,
+            ROOT_DEVICE_STORAGE,
+            ROOT_DOWNLOADS,
+            ROOT_HOME,
+            ROOT_IMAGES,
+            ROOT_RECENTS,
+            ROOT_VIDEOS,
+            ROOT_MTP,
+            ROOT_THIRD_PARTY_APP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Root {
+    }
+
+    // Codes representing different mime types.
+    static final int MIME_UNKNOWN = 0;
+    static final int MIME_NONE = 1; // null mime
+    static final int MIME_ANY = 2; // */*
+    static final int MIME_APPLICATION = 3; // application/*
+    static final int MIME_AUDIO = 4; // audio/*
+    static final int MIME_IMAGE = 5; // image/*
+    static final int MIME_MESSAGE = 6; // message/*
+    static final int MIME_MULTIPART = 7; // multipart/*
+    static final int MIME_TEXT = 8; // text/*
+    static final int MIME_VIDEO = 9; // video/*
+    static final int MIME_OTHER = 10; // anything not enumerated below
+
+    @IntDef(flag = true, value = {
+            MIME_UNKNOWN,
+            MIME_NONE,
+            MIME_ANY,
+            MIME_APPLICATION,
+            MIME_AUDIO,
+            MIME_IMAGE,
+            MIME_MESSAGE,
+            MIME_MULTIPART,
+            MIME_TEXT,
+            MIME_VIDEO,
+            MIME_OTHER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Mime {
+    }
+
+    public static final int UNKNOWN_SCOPE = 0;
+    public static final int FILES_SCOPE = 1;
+    public static final int PICKER_SCOPE = 2;
+
+    // Codes representing different scopes(FILE/PICKER mode).
+    @IntDef({UNKNOWN_SCOPE, FILES_SCOPE, PICKER_SCOPE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ContextScope {
+    }
+
+    // Codes representing different kinds of file operations.
+    static final int FILEOP_UNKNOWN = 0;
+    static final int FILEOP_OTHER = 1; // any file operation not listed below
+    static final int FILEOP_COPY = 2;
+    static final int FILEOP_COPY_INTRA_PROVIDER = 3; // Copy within a provider
+    static final int FILEOP_COPY_SYSTEM_PROVIDER = 4; // Copy to a system provider.
+    static final int FILEOP_COPY_EXTERNAL_PROVIDER = 5; // Copy to a 3rd-party provider.
+    static final int FILEOP_MOVE = 6;
+    static final int FILEOP_MOVE_INTRA_PROVIDER = 7; // Move within a provider.
+    static final int FILEOP_MOVE_SYSTEM_PROVIDER = 8; // Move to a system provider.
+    static final int FILEOP_MOVE_EXTERNAL_PROVIDER = 9; // Move to a 3rd-party provider.
+    static final int FILEOP_DELETE = 10;
+    static final int FILEOP_RENAME = 11;
+    static final int FILEOP_CREATE_DIR = 12;
+    static final int FILEOP_OTHER_ERROR = 13;
+    static final int FILEOP_DELETE_ERROR = 14;
+    static final int FILEOP_MOVE_ERROR = 15;
+    static final int FILEOP_COPY_ERROR = 16;
+    static final int FILEOP_RENAME_ERROR = 17;
+    static final int FILEOP_CREATE_DIR_ERROR = 18;
+    static final int FILEOP_COMPRESS_INTRA_PROVIDER = 19; // Compres within a provider
+    static final int FILEOP_COMPRESS_SYSTEM_PROVIDER = 20; // Compress to a system provider.
+    static final int FILEOP_COMPRESS_EXTERNAL_PROVIDER = 21; // Compress to a 3rd-party provider.
+    static final int FILEOP_EXTRACT_INTRA_PROVIDER = 22; // Extract within a provider
+    static final int FILEOP_EXTRACT_SYSTEM_PROVIDER = 23; // Extract to a system provider.
+    static final int FILEOP_EXTRACT_EXTERNAL_PROVIDER = 24; // Extract to a 3rd-party provider.
+    static final int FILEOP_COMPRESS_ERROR = 25;
+    static final int FILEOP_EXTRACT_ERROR = 26;
+
+    @IntDef(flag = true, value = {
+            FILEOP_UNKNOWN,
+            FILEOP_OTHER,
+            FILEOP_COPY,
+            FILEOP_COPY_INTRA_PROVIDER,
+            FILEOP_COPY_SYSTEM_PROVIDER,
+            FILEOP_COPY_EXTERNAL_PROVIDER,
+            FILEOP_MOVE,
+            FILEOP_MOVE_INTRA_PROVIDER,
+            FILEOP_MOVE_SYSTEM_PROVIDER,
+            FILEOP_MOVE_EXTERNAL_PROVIDER,
+            FILEOP_DELETE,
+            FILEOP_RENAME,
+            FILEOP_CREATE_DIR,
+            FILEOP_OTHER_ERROR,
+            FILEOP_DELETE_ERROR,
+            FILEOP_MOVE_ERROR,
+            FILEOP_COPY_ERROR,
+            FILEOP_RENAME_ERROR,
+            FILEOP_CREATE_DIR_ERROR,
+            FILEOP_COMPRESS_INTRA_PROVIDER,
+            FILEOP_COMPRESS_SYSTEM_PROVIDER,
+            FILEOP_COMPRESS_EXTERNAL_PROVIDER,
+            FILEOP_EXTRACT_INTRA_PROVIDER,
+            FILEOP_EXTRACT_SYSTEM_PROVIDER,
+            FILEOP_EXTRACT_EXTERNAL_PROVIDER,
+            FILEOP_COMPRESS_ERROR,
+            FILEOP_EXTRACT_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FileOp {
+    }
+
+    // Codes representing different provider types.  Used for sorting file operations when logging.
+    static final int PROVIDER_INTRA = 0;
+    static final int PROVIDER_SYSTEM = 1;
+    static final int PROVIDER_EXTERNAL = 2;
+
+    @IntDef(flag = false, value = {
+            PROVIDER_INTRA,
+            PROVIDER_SYSTEM,
+            PROVIDER_EXTERNAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Provider {
+    }
+
+    // Codes representing different types of sub-fileops.
+    public static final int SUBFILEOP_UNKNOWN = 0;
+    public static final int SUBFILEOP_QUERY_DOCUMENT = 1;
+    public static final int SUBFILEOP_QUERY_CHILDREN = 2;
+    public static final int SUBFILEOP_OPEN_FILE = 3;
+    public static final int SUBFILEOP_READ_FILE = 4;
+    public static final int SUBFILEOP_CREATE_DOCUMENT = 5;
+    public static final int SUBFILEOP_WRITE_FILE = 6;
+    public static final int SUBFILEOP_DELETE_DOCUMENT = 7;
+    public static final int SUBFILEOP_OBTAIN_STREAM_TYPE = 8;
+    public static final int SUBFILEOP_QUICK_MOVE = 9;
+    public static final int SUBFILEOP_QUICK_COPY = 10;
+
+    @IntDef(flag = false, value = {
+            SUBFILEOP_UNKNOWN,
+            SUBFILEOP_QUERY_DOCUMENT,
+            SUBFILEOP_QUERY_CHILDREN,
+            SUBFILEOP_OPEN_FILE,
+            SUBFILEOP_READ_FILE,
+            SUBFILEOP_CREATE_DOCUMENT,
+            SUBFILEOP_WRITE_FILE,
+            SUBFILEOP_DELETE_DOCUMENT,
+            SUBFILEOP_OBTAIN_STREAM_TYPE,
+            SUBFILEOP_QUICK_MOVE,
+            SUBFILEOP_QUICK_COPY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SubFileOp {
+    }
+
+    // Codes representing different user actions
+    public static final int USER_ACTION_UNKNOWN = 0;
+    public static final int USER_ACTION_OTHER = 1;
+    public static final int USER_ACTION_GRID = 2;
+    public static final int USER_ACTION_LIST = 3;
+    public static final int USER_ACTION_SORT_NAME = 4;
+    public static final int USER_ACTION_SORT_DATE = 5;
+    public static final int USER_ACTION_SORT_SIZE = 6;
+    public static final int USER_ACTION_SORT_TYPE = 7;
+    public static final int USER_ACTION_SEARCH = 8;
+    public static final int USER_ACTION_SHOW_SIZE = 9;
+    public static final int USER_ACTION_HIDE_SIZE = 10;
+    public static final int USER_ACTION_SETTINGS = 11;
+    public static final int USER_ACTION_COPY_TO = 12;
+    public static final int USER_ACTION_MOVE_TO = 13;
+    public static final int USER_ACTION_DELETE = 14;
+    public static final int USER_ACTION_RENAME = 15;
+    public static final int USER_ACTION_CREATE_DIR = 16;
+    public static final int USER_ACTION_SELECT_ALL = 17;
+    public static final int USER_ACTION_SHARE = 18;
+    public static final int USER_ACTION_OPEN = 19;
+    public static final int USER_ACTION_SHOW_ADVANCED = 20;
+    public static final int USER_ACTION_HIDE_ADVANCED = 21;
+    public static final int USER_ACTION_NEW_WINDOW = 22;
+    public static final int USER_ACTION_PASTE_CLIPBOARD = 23;
+    public static final int USER_ACTION_COPY_CLIPBOARD = 24;
+    public static final int USER_ACTION_DRAG_N_DROP = 25;
+    public static final int USER_ACTION_DRAG_N_DROP_MULTI_WINDOW = 26;
+    public static final int USER_ACTION_CUT_CLIPBOARD = 27;
+    public static final int USER_ACTION_COMPRESS = 28;
+    public static final int USER_ACTION_EXTRACT_TO = 29;
+    public static final int USER_ACTION_VIEW_IN_APPLICATION = 30;
+    public static final int USER_ACTION_INSPECTOR = 31;
+    public static final int USER_ACTION_SEARCH_CHIP = 32;
+    public static final int USER_ACTION_SEARCH_HISTORY = 33;
+
+    @IntDef(flag = false, value = {
+            USER_ACTION_UNKNOWN,
+            USER_ACTION_OTHER,
+            USER_ACTION_GRID,
+            USER_ACTION_LIST,
+            USER_ACTION_SORT_NAME,
+            USER_ACTION_SORT_DATE,
+            USER_ACTION_SORT_SIZE,
+            USER_ACTION_SORT_TYPE,
+            USER_ACTION_SEARCH,
+            USER_ACTION_SHOW_SIZE,
+            USER_ACTION_HIDE_SIZE,
+            USER_ACTION_SETTINGS,
+            USER_ACTION_COPY_TO,
+            USER_ACTION_MOVE_TO,
+            USER_ACTION_DELETE,
+            USER_ACTION_RENAME,
+            USER_ACTION_CREATE_DIR,
+            USER_ACTION_SELECT_ALL,
+            USER_ACTION_SHARE,
+            USER_ACTION_OPEN,
+            USER_ACTION_SHOW_ADVANCED,
+            USER_ACTION_HIDE_ADVANCED,
+            USER_ACTION_NEW_WINDOW,
+            USER_ACTION_PASTE_CLIPBOARD,
+            USER_ACTION_COPY_CLIPBOARD,
+            USER_ACTION_DRAG_N_DROP,
+            USER_ACTION_DRAG_N_DROP_MULTI_WINDOW,
+            USER_ACTION_CUT_CLIPBOARD,
+            USER_ACTION_COMPRESS,
+            USER_ACTION_EXTRACT_TO,
+            USER_ACTION_VIEW_IN_APPLICATION,
+            USER_ACTION_INSPECTOR,
+            USER_ACTION_SEARCH_CHIP,
+            USER_ACTION_SEARCH_HISTORY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UserAction {
+    }
+
+    // Codes representing different approaches to copy/move a document. OPMODE_PROVIDER indicates
+    // it's an optimized operation provided by providers; OPMODE_CONVERTED means it's converted from
+    // a virtual file; and OPMODE_CONVENTIONAL means it's byte copied.
+    public static final int OPMODE_UNKNOWN = 0;
+    public static final int OPMODE_PROVIDER = 1;
+    public static final int OPMODE_CONVERTED = 2;
+    public static final int OPMODE_CONVENTIONAL = 3;
+
+    @IntDef({OPMODE_UNKNOWN, OPMODE_PROVIDER, OPMODE_CONVERTED, OPMODE_CONVENTIONAL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FileOpMode {
+    }
+
+    // Codes representing different menu actions.
+    static final int ACTION_UNKNOWN = 0;
+    static final int ACTION_OPEN = 1;
+    static final int ACTION_CREATE = 2;
+    static final int ACTION_GET_CONTENT = 3;
+    static final int ACTION_OPEN_TREE = 4;
+    static final int ACTION_PICK_COPY_DESTINATION = 5;
+    static final int ACTION_BROWSE = 6;
+    static final int ACTION_OTHER = 7;
+
+    @IntDef(flag = true, value = {
+            ACTION_UNKNOWN,
+            ACTION_OPEN,
+            ACTION_CREATE,
+            ACTION_GET_CONTENT,
+            ACTION_OPEN_TREE,
+            ACTION_PICK_COPY_DESTINATION,
+            ACTION_BROWSE,
+            ACTION_OTHER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MetricsAction {
+    }
+
+    public static final int AUTH_UNKNOWN = 0;
+    public static final int AUTH_OTHER = 1;
+    public static final int AUTH_MEDIA = 2;
+    public static final int AUTH_STORAGE_INTERNAL = 3;
+    public static final int AUTH_STORAGE_EXTERNAL = 4;
+    public static final int AUTH_DOWNLOADS = 5;
+    public static final int AUTH_MTP = 6;
+
+    @IntDef(flag = true, value = {
+            AUTH_UNKNOWN,
+            AUTH_OTHER,
+            AUTH_MEDIA,
+            AUTH_STORAGE_INTERNAL,
+            AUTH_STORAGE_EXTERNAL,
+            AUTH_DOWNLOADS,
+            AUTH_MTP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MetricsAuth {
+    }
+
+    // Types for logInvalidScopedAccessRequest
+    public static final int SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS = 1;
+    public static final int SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY = 2;
+    public static final int SCOPED_DIRECTORY_ACCESS_ERROR = 3;
+    public static final int SCOPED_DIRECTORY_ACCESS_DEPRECATED = 4;
+
+    @IntDef(value = {
+            SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS,
+            SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY,
+            SCOPED_DIRECTORY_ACCESS_ERROR,
+            SCOPED_DIRECTORY_ACCESS_DEPRECATED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InvalidScopedAccess {
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/Metrics.java b/src/com/android/documentsui/Metrics.java
index 77000a3..d3a7663 100644
--- a/src/com/android/documentsui/Metrics.java
+++ b/src/com/android/documentsui/Metrics.java
@@ -17,9 +17,7 @@
 package com.android.documentsui;
 
 import static com.android.documentsui.DocumentsApplication.acquireUnstableProviderOrThrow;
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
 
-import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
 import android.content.ContentProviderClient;
 import android.content.Context;
@@ -30,21 +28,19 @@
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Path;
 import android.provider.DocumentsProvider;
+import android.util.DocumentsStatsLog;
 import android.util.Log;
 
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Providers;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
-import com.android.documentsui.base.State.ActionType;
 import com.android.documentsui.files.LauncherActivity;
 import com.android.documentsui.roots.ProvidersAccess;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
 
 import java.io.FileNotFoundException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -53,445 +49,48 @@
 public final class Metrics {
     private static final String TAG = "Metrics";
 
-    // These strings have to be whitelisted in tron. Do not change them.
-    private static final String COUNT_LAUNCH_ACTION = "docsui_launch_action";
-    private static final String COUNT_ROOT_VISITED_IN_MANAGER
-            = "docsui_root_visited_in_manager";
-    private static final String COUNT_ROOT_VISITED_IN_PICKER
-            = "docsui_root_visited_in_picker";
-    private static final String COUNT_OPEN_MIME = "docsui_open_mime";
-    private static final String COUNT_CREATE_MIME = "docsui_create_mime";
-    private static final String COUNT_GET_CONTENT_MIME = "docsui_get_content_mime";
-    private static final String COUNT_BROWSE_ROOT = "docsui_browse_root";
-    @Deprecated private static final String COUNT_MANAGE_ROOT = "docsui_manage_root";
-    @Deprecated private static final String COUNT_MULTI_WINDOW = "docsui_multi_window";
-    private static final String COUNT_FILEOP_SYSTEM = "docsui_fileop_system";
-    private static final String COUNT_FILEOP_EXTERNAL = "docsui_fileop_external";
-    private static final String COUNT_FILEOP_CANCELED = "docsui_fileop_canceled";
-    private static final String COUNT_STARTUP_MS = "docsui_startup_ms";
-    @Deprecated private static final String COUNT_DRAWER_OPENED = "docsui_drawer_opened";
-    private static final String COUNT_USER_ACTION = "docsui_menu_action";
-    private static final String COUNT_BROWSE_AT_LOCATION = "docsui_browse_at_location";
-    private static final String COUNT_CREATE_AT_LOCATION = "docsui_create_at_location";
-    private static final String COUNT_OPEN_AT_LOCATION = "docsui_open_at_location";
-    private static final String COUNT_GET_CONTENT_AT_LOCATION = "docsui_get_content_at_location";
-    private static final String COUNT_MEDIA_FILEOP_FAILURE = "docsui_media_fileop_failure";
-    private static final String COUNT_DOWNLOADS_FILEOP_FAILURE = "docsui_downloads_fileop_failure";
-    private static final String COUNT_INTERNAL_STORAGE_FILEOP_FAILURE
-            = "docsui_internal_storage_fileop_failure";
-    private static final String COUNT_EXTERNAL_STORAGE_FILEOP_FAILURE
-            = "docsui_external_storage_fileop_failure";
-    private static final String COUNT_MTP_FILEOP_FAILURE = "docsui_mtp_fileop_failure";
-    private static final String COUNT_OTHER_FILEOP_FAILURE = "docsui_other_fileop_failure";
-    private static final String COUNT_FILE_COPIED = "docsui_file_copied";
-    private static final String COUNT_FILE_MOVED = "docsui_file_moved";
-
-    // Indices for bucketing roots in the roots histogram. "Other" is the catch-all index for any
-    // root that is not explicitly recognized by the Metrics code (see {@link
-    // #getSanitizedRootIndex}). Apps are also bucketed in this histogram.
-    // Do not change or rearrange these values, that will break historical data. Only add to the end
-    // of the list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int ROOT_NONE = 1;
-    private static final int ROOT_OTHER = 2;
-    private static final int ROOT_AUDIO = 3;
-    private static final int ROOT_DEVICE_STORAGE = 4;
-    private static final int ROOT_DOWNLOADS = 5;
-    private static final int ROOT_HOME = 6;
-    private static final int ROOT_IMAGES = 7;
-    private static final int ROOT_RECENTS = 8;
-    private static final int ROOT_VIDEOS = 9;
-    private static final int ROOT_MTP = 10;
-    // Apps aren't really "roots", but they are treated as such in the roots fragment UI and so they
-    // are logged analogously to roots.
-    private static final int ROOT_THIRD_PARTY_APP = 100;
-
-    @IntDef(flag = true, value = {
-            ROOT_NONE,
-            ROOT_OTHER,
-            ROOT_AUDIO,
-            ROOT_DEVICE_STORAGE,
-            ROOT_DOWNLOADS,
-            ROOT_HOME,
-            ROOT_IMAGES,
-            ROOT_RECENTS,
-            ROOT_VIDEOS,
-            ROOT_MTP,
-            ROOT_THIRD_PARTY_APP
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Root {}
-
-    // Indices for bucketing mime types.
-    // Do not change or rearrange these values, that will break historical data. Only add to the end
-    // of the list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int MIME_NONE = 1; // null mime
-    private static final int MIME_ANY = 2; // */*
-    private static final int MIME_APPLICATION = 3; // application/*
-    private static final int MIME_AUDIO = 4; // audio/*
-    private static final int MIME_IMAGE = 5; // image/*
-    private static final int MIME_MESSAGE = 6; // message/*
-    private static final int MIME_MULTIPART = 7; // multipart/*
-    private static final int MIME_TEXT = 8; // text/*
-    private static final int MIME_VIDEO = 9; // video/*
-    private static final int MIME_OTHER = 10; // anything not enumerated below
-
-    @IntDef(flag = true, value = {
-            MIME_NONE,
-            MIME_ANY,
-            MIME_APPLICATION,
-            MIME_AUDIO,
-            MIME_IMAGE,
-            MIME_MESSAGE,
-            MIME_MULTIPART,
-            MIME_TEXT,
-            MIME_VIDEO,
-            MIME_OTHER
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Mime {}
-
-    public static final int FILES_SCOPE = 1;
-    public static final int PICKER_SCOPE = 2;
-
-    @IntDef({ FILES_SCOPE, PICKER_SCOPE })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ContextScope {}
-
-    // Codes representing different kinds of file operations. These are used for bucketing
-    // operations in the COUNT_FILEOP_{SYSTEM|EXTERNAL} histograms.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int FILEOP_OTHER = 1; // any file operation not listed below
-    private static final int FILEOP_COPY_INTRA_PROVIDER = 2; // Copy within a provider
-    private static final int FILEOP_COPY_SYSTEM_PROVIDER = 3; // Copy to a system provider.
-    private static final int FILEOP_COPY_EXTERNAL_PROVIDER = 4; // Copy to a 3rd-party provider.
-    private static final int FILEOP_MOVE_INTRA_PROVIDER = 5; // Move within a provider.
-    private static final int FILEOP_MOVE_SYSTEM_PROVIDER = 6; // Move to a system provider.
-    private static final int FILEOP_MOVE_EXTERNAL_PROVIDER = 7; // Move to a 3rd-party provider.
-    private static final int FILEOP_DELETE = 8;
-    private static final int FILEOP_RENAME = 9;
-    private static final int FILEOP_CREATE_DIR = 10;
-    private static final int FILEOP_OTHER_ERROR = 100;
-    private static final int FILEOP_DELETE_ERROR = 101;
-    private static final int FILEOP_MOVE_ERROR = 102;
-    private static final int FILEOP_COPY_ERROR = 103;
-    private static final int FILEOP_RENAME_ERROR = 104;
-    private static final int FILEOP_CREATE_DIR_ERROR = 105;
-    private static final int FILEOP_COMPRESS_INTRA_PROVIDER = 106; // Compres within a provider
-    private static final int FILEOP_COMPRESS_SYSTEM_PROVIDER = 107; // Compress to a system provider.
-    private static final int FILEOP_COMPRESS_EXTERNAL_PROVIDER = 108; // Compress to a 3rd-party provider.
-    private static final int FILEOP_EXTRACT_INTRA_PROVIDER = 109; // Extract within a provider
-    private static final int FILEOP_EXTRACT_SYSTEM_PROVIDER = 110; // Extract to a system provider.
-    private static final int FILEOP_EXTRACT_EXTERNAL_PROVIDER = 111; // Extract to a 3rd-party provider.
-    private static final int FILEOP_COMPRESS_ERROR = 112;
-    private static final int FILEOP_EXTRACT_ERROR = 113;
-
-    @IntDef(flag = true, value = {
-            FILEOP_OTHER,
-            FILEOP_COPY_INTRA_PROVIDER,
-            FILEOP_COPY_SYSTEM_PROVIDER,
-            FILEOP_COPY_EXTERNAL_PROVIDER,
-            FILEOP_MOVE_INTRA_PROVIDER,
-            FILEOP_MOVE_SYSTEM_PROVIDER,
-            FILEOP_MOVE_EXTERNAL_PROVIDER,
-            FILEOP_DELETE,
-            FILEOP_RENAME,
-            FILEOP_CREATE_DIR,
-            FILEOP_OTHER_ERROR,
-            FILEOP_DELETE_ERROR,
-            FILEOP_MOVE_ERROR,
-            FILEOP_COPY_ERROR,
-            FILEOP_RENAME_ERROR,
-            FILEOP_CREATE_DIR_ERROR,
-            FILEOP_COMPRESS_INTRA_PROVIDER,
-            FILEOP_COMPRESS_SYSTEM_PROVIDER,
-            FILEOP_COMPRESS_EXTERNAL_PROVIDER,
-            FILEOP_EXTRACT_INTRA_PROVIDER,
-            FILEOP_EXTRACT_SYSTEM_PROVIDER,
-            FILEOP_EXTRACT_EXTERNAL_PROVIDER,
-            FILEOP_COMPRESS_ERROR,
-            FILEOP_EXTRACT_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface FileOp {}
-
-    // Codes representing different kinds of file operations. These are used for bucketing
-    // operations in the COUNT_FILEOP_CANCELED histogram.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int OPERATION_UNKNOWN = 1;
-    private static final int OPERATION_COPY = 2;
-    private static final int OPERATION_MOVE = 3;
-    private static final int OPERATION_DELETE = 4;
-    private static final int OPERATION_COMPRESS = 5;
-    private static final int OPERATION_EXTRACT = 6;
-
-    @IntDef(flag = true, value = {
-            OPERATION_UNKNOWN,
-            OPERATION_COPY,
-            OPERATION_MOVE,
-            OPERATION_DELETE,
-            OPERATION_COMPRESS,
-            OPERATION_EXTRACT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MetricsOpType {}
-
-    // Codes representing different provider types.  Used for sorting file operations when logging.
-    private static final int PROVIDER_INTRA = 0;
-    private static final int PROVIDER_SYSTEM = 1;
-    private static final int PROVIDER_EXTERNAL = 2;
-
-    @IntDef(flag = false, value = {
-            PROVIDER_INTRA,
-            PROVIDER_SYSTEM,
-            PROVIDER_EXTERNAL
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Provider {}
-
-    // Codes representing different types of sub-fileops. These are used for bucketing fileop
-    // failures in COUNT_*_FILEOP_FAILURE.
-    public static final int SUBFILEOP_QUERY_DOCUMENT = 1;
-    public static final int SUBFILEOP_QUERY_CHILDREN = 2;
-    public static final int SUBFILEOP_OPEN_FILE = 3;
-    public static final int SUBFILEOP_READ_FILE = 4;
-    public static final int SUBFILEOP_CREATE_DOCUMENT = 5;
-    public static final int SUBFILEOP_WRITE_FILE = 6;
-    public static final int SUBFILEOP_DELETE_DOCUMENT = 7;
-    public static final int SUBFILEOP_OBTAIN_STREAM_TYPE = 8;
-    public static final int SUBFILEOP_QUICK_MOVE = 9;
-    public static final int SUBFILEOP_QUICK_COPY = 10;
-
-    @IntDef(flag = false, value = {
-            SUBFILEOP_QUERY_DOCUMENT,
-            SUBFILEOP_QUERY_CHILDREN,
-            SUBFILEOP_OPEN_FILE,
-            SUBFILEOP_READ_FILE,
-            SUBFILEOP_CREATE_DOCUMENT,
-            SUBFILEOP_WRITE_FILE,
-            SUBFILEOP_DELETE_DOCUMENT,
-            SUBFILEOP_OBTAIN_STREAM_TYPE,
-            SUBFILEOP_QUICK_MOVE,
-            SUBFILEOP_QUICK_COPY
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SubFileOp {}
-
-    // Codes representing different user actions. These are used for bucketing stats in the
-    // COUNT_USER_ACTION histogram.
-    // The historgram includes action triggered from menu or invoked by keyboard shortcut.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    public static final int USER_ACTION_OTHER = 1;
-    public static final int USER_ACTION_GRID = 2;
-    public static final int USER_ACTION_LIST = 3;
-    public static final int USER_ACTION_SORT_NAME = 4;
-    public static final int USER_ACTION_SORT_DATE = 5;
-    public static final int USER_ACTION_SORT_SIZE = 6;
-    public static final int USER_ACTION_SEARCH = 7;
-    public static final int USER_ACTION_SHOW_SIZE = 8;
-    public static final int USER_ACTION_HIDE_SIZE = 9;
-    public static final int USER_ACTION_SETTINGS = 10;
-    public static final int USER_ACTION_COPY_TO = 11;
-    public static final int USER_ACTION_MOVE_TO = 12;
-    public static final int USER_ACTION_DELETE = 13;
-    public static final int USER_ACTION_RENAME = 14;
-    public static final int USER_ACTION_CREATE_DIR = 15;
-    public static final int USER_ACTION_SELECT_ALL = 16;
-    public static final int USER_ACTION_SHARE = 17;
-    public static final int USER_ACTION_OPEN = 18;
-    public static final int USER_ACTION_SHOW_ADVANCED = 19;
-    public static final int USER_ACTION_HIDE_ADVANCED = 20;
-    public static final int USER_ACTION_NEW_WINDOW = 21;
-    public static final int USER_ACTION_PASTE_CLIPBOARD = 22;
-    public static final int USER_ACTION_COPY_CLIPBOARD = 23;
-    public static final int USER_ACTION_DRAG_N_DROP = 24;
-    public static final int USER_ACTION_DRAG_N_DROP_MULTI_WINDOW = 25;
-    public static final int USER_ACTION_CUT_CLIPBOARD = 26;
-    public static final int USER_ACTION_COMPRESS = 27;
-    public static final int USER_ACTION_EXTRACT_TO = 28;
-    public static final int USER_ACTION_VIEW_IN_APPLICATION = 29;
-    public static final int USER_ACTION_INSPECTOR = 30;
-
-    @IntDef(flag = false, value = {
-            USER_ACTION_OTHER,
-            USER_ACTION_GRID,
-            USER_ACTION_LIST,
-            USER_ACTION_SORT_NAME,
-            USER_ACTION_SORT_DATE,
-            USER_ACTION_SORT_SIZE,
-            USER_ACTION_SEARCH,
-            USER_ACTION_SHOW_SIZE,
-            USER_ACTION_HIDE_SIZE,
-            USER_ACTION_SETTINGS,
-            USER_ACTION_COPY_TO,
-            USER_ACTION_MOVE_TO,
-            USER_ACTION_DELETE,
-            USER_ACTION_RENAME,
-            USER_ACTION_CREATE_DIR,
-            USER_ACTION_SELECT_ALL,
-            USER_ACTION_SHARE,
-            USER_ACTION_OPEN,
-            USER_ACTION_SHOW_ADVANCED,
-            USER_ACTION_HIDE_ADVANCED,
-            USER_ACTION_NEW_WINDOW,
-            USER_ACTION_PASTE_CLIPBOARD,
-            USER_ACTION_COPY_CLIPBOARD,
-            USER_ACTION_DRAG_N_DROP,
-            USER_ACTION_DRAG_N_DROP_MULTI_WINDOW,
-            USER_ACTION_CUT_CLIPBOARD,
-            USER_ACTION_COMPRESS,
-            USER_ACTION_EXTRACT_TO,
-            USER_ACTION_VIEW_IN_APPLICATION,
-            USER_ACTION_INSPECTOR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface UserAction {}
-
-    // Codes representing different approaches to copy/move a document. OPMODE_PROVIDER indicates
-    // it's an optimized operation provided by providers; OPMODE_CONVERTED means it's converted from
-    // a virtual file; and OPMODE_CONVENTIONAL means it's byte copied.
-    public static final int OPMODE_PROVIDER = 1;
-    public static final int OPMODE_CONVERTED = 2;
-    public static final int OPMODE_CONVENTIONAL = 3;
-    @IntDef({OPMODE_PROVIDER, OPMODE_CONVERTED, OPMODE_CONVENTIONAL})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface FileOpMode {}
-
-    // Codes representing different menu actions. These are used for bucketing stats in the
-    // COUNT_MENU_ACTION histogram.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int ACTION_OTHER = 1;
-    private static final int ACTION_OPEN = 2;
-    private static final int ACTION_CREATE = 3;
-    private static final int ACTION_GET_CONTENT = 4;
-    private static final int ACTION_OPEN_TREE = 5;
-    @Deprecated private static final int ACTION_MANAGE = 6;
-    private static final int ACTION_BROWSE = 7;
-    private static final int ACTION_PICK_COPY_DESTINATION = 8;
-
-    @IntDef(flag = true, value = {
-            ACTION_OTHER,
-            ACTION_OPEN,
-            ACTION_CREATE,
-            ACTION_GET_CONTENT,
-            ACTION_OPEN_TREE,
-            ACTION_MANAGE,
-            ACTION_BROWSE,
-            ACTION_PICK_COPY_DESTINATION
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MetricsAction {}
-
-    // Codes representing different actions to open the drawer. They are used for bucketing stats in
-    // the COUNT_DRAWER_OPENED histogram.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int DRAWER_OPENED_HAMBURGER = 1;
-    private static final int DRAWER_OPENED_SWIPE = 2;
-
-    @IntDef(flag = true, value = {
-            DRAWER_OPENED_HAMBURGER,
-            DRAWER_OPENED_SWIPE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface DrawerTrigger {}
-
     /**
      * Logs when DocumentsUI is started, and how. Call this when DocumentsUI first starts up.
      *
-     * @param context
      * @param state
      * @param intent
      */
-    public static void logActivityLaunch(Context context, State state, Intent intent) {
-        // Log the launch action.
-        logHistogram(context, COUNT_LAUNCH_ACTION, toMetricsAction(state.action));
-        // Then log auxiliary data (roots/mime types) associated with some actions.
+    public static void logActivityLaunch(State state, Intent intent) {
         Uri uri = intent.getData();
-        switch (state.action) {
-            case State.ACTION_OPEN:
-                logHistogram(context, COUNT_OPEN_MIME, sanitizeMime(intent.getType()));
-                break;
-            case State.ACTION_CREATE:
-                logHistogram(context, COUNT_CREATE_MIME, sanitizeMime(intent.getType()));
-                break;
-            case State.ACTION_GET_CONTENT:
-                logHistogram(context, COUNT_GET_CONTENT_MIME, sanitizeMime(intent.getType()));
-                break;
-            case State.ACTION_BROWSE:
-                logHistogram(context, COUNT_BROWSE_ROOT, sanitizeRoot(uri));
-                break;
-            default:
-                break;
-        }
+        DocumentsStatsLog.logActivityLaunch(toMetricsAction(state.action), false,
+                sanitizeMime(intent.getType()), sanitizeRoot(uri));
     }
 
     /**
      * Logs when DocumentsUI are launched with {@link DocumentsContract#EXTRA_INITIAL_URI}.
      *
-     * @param context
      * @param state used to resolve action
      * @param rootUri the resolved rootUri, or {@code null} if the provider doesn't
      *                support {@link DocumentsProvider#findDocumentPath(String, String)}
      */
-    public static void logLaunchAtLocation(Context context, State state, @Nullable Uri rootUri) {
-        switch (state.action) {
-            case State.ACTION_BROWSE:
-                logHistogram(context, COUNT_BROWSE_AT_LOCATION, sanitizeRoot(rootUri));
-                break;
-            case State.ACTION_CREATE:
-                logHistogram(context, COUNT_CREATE_AT_LOCATION, sanitizeRoot(rootUri));
-                break;
-            case State.ACTION_GET_CONTENT:
-                logHistogram(context, COUNT_GET_CONTENT_AT_LOCATION, sanitizeRoot(rootUri));
-                break;
-            case State.ACTION_OPEN:
-                logHistogram(context, COUNT_OPEN_AT_LOCATION, sanitizeRoot(rootUri));
-                break;
-        }
+    public static void logLaunchAtLocation(State state, @Nullable Uri rootUri) {
+        DocumentsStatsLog.logActivityLaunch(toMetricsAction(state.action), true,
+                MetricConsts.MIME_UNKNOWN, sanitizeRoot(rootUri));
     }
 
     /**
      * Logs a root visited event in file managers. Call this when the user
      * taps on a root in {@link com.android.documentsui.sidebar.RootsFragment}.
-     *
-     * @param context
      * @param scope
      * @param info
      */
-    public static void logRootVisited(
-            Context context, @ContextScope int scope, RootInfo info) {
-        switch (scope) {
-            case FILES_SCOPE:
-                logHistogram(context, COUNT_ROOT_VISITED_IN_MANAGER,
-                        sanitizeRoot(info));
-                break;
-            case PICKER_SCOPE:
-                logHistogram(context, COUNT_ROOT_VISITED_IN_PICKER,
-                        sanitizeRoot(info));
-                break;
-        }
+    public static void logRootVisited(@MetricConsts.ContextScope int scope, RootInfo info) {
+        DocumentsStatsLog.logRootVisited(scope, sanitizeRoot(info));
     }
 
     /**
      * Logs an app visited event in file pickers. Call this when the user visits
      * on an app in the RootsFragment.
      *
-     * @param context
      * @param info
      */
-    public static void logAppVisited(Context context, ResolveInfo info) {
-        logHistogram(context, COUNT_ROOT_VISITED_IN_PICKER, sanitizeRoot(info));
+    public static void logAppVisited(ResolveInfo info) {
+        DocumentsStatsLog.logRootVisited(MetricConsts.PICKER_SCOPE, sanitizeRoot(info));
     }
 
     /**
@@ -499,41 +98,39 @@
      * DocumentInfo is only used to distinguish broad categories of actions (e.g. copying from one
      * provider to another vs copying within a given provider).  No PII is logged.
      *
-     * @param context
      * @param operationType
      * @param srcs
      * @param dst
      */
     public static void logFileOperation(
-            Context context,
             @OpType int operationType,
             List<DocumentInfo> srcs,
             @Nullable DocumentInfo dst) {
-
         ProviderCounts counts = new ProviderCounts();
         countProviders(counts, srcs, dst);
-
         if (counts.intraProvider > 0) {
-            logIntraProviderFileOps(context, dst.authority, operationType);
+            logIntraProviderFileOps(dst.authority, operationType);
         }
         if (counts.systemProvider > 0) {
             // Log file operations on system providers.
-            logInterProviderFileOps(context, COUNT_FILEOP_SYSTEM, dst, operationType);
+            logInterProviderFileOps(MetricConsts.PROVIDER_SYSTEM, dst, operationType);
         }
         if (counts.externalProvider > 0) {
             // Log file operations on external providers.
-            logInterProviderFileOps(context, COUNT_FILEOP_EXTERNAL, dst, operationType);
+            logInterProviderFileOps(MetricConsts.PROVIDER_EXTERNAL, dst, operationType);
         }
     }
 
     public static void logFileOperated(
-            Context context, @OpType int operationType, @FileOpMode int approach) {
+            @OpType int operationType, @MetricConsts.FileOpMode int approach) {
         switch (operationType) {
             case FileOperationService.OPERATION_COPY:
-                logHistogram(context, COUNT_FILE_COPIED, approach);
+                DocumentsStatsLog.logFileOperationCopyMoveMode(
+                        MetricConsts.FILEOP_COPY, approach);
                 break;
             case FileOperationService.OPERATION_MOVE:
-                logHistogram(context, COUNT_FILE_MOVED, approach);
+                DocumentsStatsLog.logFileOperationCopyMoveMode(
+                        MetricConsts.FILEOP_MOVE, approach);
                 break;
         }
     }
@@ -542,85 +139,79 @@
      * Logs create directory operation. It is a part of file operation stats. We do not
      * differentiate between internal and external locations, all create directory operations are
      * logged under COUNT_FILEOP_SYSTEM. Call this when a create directory operation has completed.
-     *
-     * @param context
      */
-    public static void logCreateDirOperation(Context context) {
-        logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_CREATE_DIR);
+    public static void logCreateDirOperation() {
+        DocumentsStatsLog.logFileOperation(
+                MetricConsts.PROVIDER_SYSTEM, MetricConsts.FILEOP_CREATE_DIR);
     }
 
     /**
      * Logs rename file operation. It is a part of file operation stats. We do not differentiate
      * between internal and external locations, all rename operations are logged under
      * COUNT_FILEOP_SYSTEM. Call this when a rename file operation has completed.
-     *
-     * @param context
      */
-    public static void logRenameFileOperation(Context context) {
-        logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_RENAME);
+    public static void logRenameFileOperation() {
+        DocumentsStatsLog.logFileOperation(
+                MetricConsts.PROVIDER_SYSTEM, MetricConsts.FILEOP_RENAME);
     }
 
     /**
      * Logs some kind of file operation error. Call this when a file operation (e.g. copy, delete)
      * fails.
      *
-     * @param context
      * @param operationType
      * @param failedFiles
      */
-    public static void logFileOperationErrors(Context context, @OpType int operationType,
+    public static void logFileOperationErrors(@OpType int operationType,
             List<DocumentInfo> failedFiles, List<Uri> failedUris) {
-
         ProviderCounts counts = new ProviderCounts();
         countProviders(counts, failedFiles, null);
-
         // TODO: Report URI errors separate from file operation errors.
         countProviders(counts, failedUris);
-
-        @FileOp int opCode = FILEOP_OTHER_ERROR;
+        @MetricConsts.FileOp int opCode = MetricConsts.FILEOP_OTHER_ERROR;
         switch (operationType) {
             case FileOperationService.OPERATION_COPY:
-                opCode = FILEOP_COPY_ERROR;
+                opCode = MetricConsts.FILEOP_COPY_ERROR;
                 break;
             case FileOperationService.OPERATION_COMPRESS:
-                opCode = FILEOP_COMPRESS_ERROR;
+                opCode = MetricConsts.FILEOP_COMPRESS_ERROR;
                 break;
             case FileOperationService.OPERATION_EXTRACT:
-                opCode = FILEOP_EXTRACT_ERROR;
+                opCode = MetricConsts.FILEOP_EXTRACT_ERROR;
                 break;
             case FileOperationService.OPERATION_DELETE:
-                opCode = FILEOP_DELETE_ERROR;
+                opCode = MetricConsts.FILEOP_DELETE_ERROR;
                 break;
             case FileOperationService.OPERATION_MOVE:
-                opCode = FILEOP_MOVE_ERROR;
+                opCode = MetricConsts.FILEOP_MOVE_ERROR;
                 break;
         }
         if (counts.systemProvider > 0) {
-            logHistogram(context, COUNT_FILEOP_SYSTEM, opCode);
+            DocumentsStatsLog.logFileOperation(MetricConsts.PROVIDER_SYSTEM, opCode);
         }
         if (counts.externalProvider > 0) {
-            logHistogram(context, COUNT_FILEOP_EXTERNAL, opCode);
+            DocumentsStatsLog.logFileOperation(MetricConsts.PROVIDER_EXTERNAL, opCode);
         }
     }
 
     public static void logFileOperationFailure(
-            Context context, @SubFileOp int subFileOp, Uri docUri) {
+            Context context, @MetricConsts.SubFileOp int subFileOp, Uri docUri) {
         final String authority = docUri.getAuthority();
         switch (authority) {
             case Providers.AUTHORITY_MEDIA:
-                logHistogram(context, COUNT_MEDIA_FILEOP_FAILURE, subFileOp);
+                DocumentsStatsLog.logFileOperationFailure(MetricConsts.AUTH_MEDIA, subFileOp);
                 break;
             case Providers.AUTHORITY_STORAGE:
                 logStorageFileOperationFailure(context, subFileOp, docUri);
                 break;
             case Providers.AUTHORITY_DOWNLOADS:
-                logHistogram(context, COUNT_DOWNLOADS_FILEOP_FAILURE, subFileOp);
+                DocumentsStatsLog.logFileOperationFailure(MetricConsts.AUTH_DOWNLOADS, subFileOp);
                 break;
             case Providers.AUTHORITY_MTP:
-                logHistogram(context, COUNT_MTP_FILEOP_FAILURE, subFileOp);
+                DocumentsStatsLog.logFileOperationFailure(MetricConsts.AUTH_MTP, subFileOp);
                 break;
             default:
-                logHistogram(context, COUNT_OTHER_FILEOP_FAILURE, subFileOp);
+                DocumentsStatsLog.logFileOperationFailure(MetricConsts.AUTH_OTHER, subFileOp);
                 break;
         }
     }
@@ -629,82 +220,78 @@
      * Logs create directory operation error. We do not differentiate between internal and external
      * locations, all create directory errors are logged under COUNT_FILEOP_SYSTEM. Call this when a
      * create directory operation fails.
-     *
-     * @param context
      */
-    public static void logCreateDirError(Context context) {
-        logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_CREATE_DIR_ERROR);
+    public static void logCreateDirError() {
+        DocumentsStatsLog.logFileOperation(
+                MetricConsts.PROVIDER_SYSTEM, MetricConsts.FILEOP_CREATE_DIR_ERROR);
     }
 
     /**
      * Logs rename file operation error. We do not differentiate between internal and external
      * locations, all rename errors are logged under COUNT_FILEOP_SYSTEM. Call this
      * when a rename file operation fails.
-     *
-     * @param context
      */
-    public static void logRenameFileError(Context context) {
-        logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_RENAME_ERROR);
+    public static void logRenameFileError() {
+        DocumentsStatsLog.logFileOperation(
+                MetricConsts.PROVIDER_SYSTEM, MetricConsts.FILEOP_RENAME_ERROR);
     }
 
     /**
      * Logs the cancellation of a file operation.  Call this when a Job is canceled.
-     * @param context
+     *
      * @param operationType
      */
-    public static void logFileOperationCancelled(Context context, @OpType int operationType) {
-        logHistogram(context, COUNT_FILEOP_CANCELED, toMetricsOpType(operationType));
+    public static void logFileOperationCancelled(@OpType int operationType) {
+        DocumentsStatsLog.logFileOperationCanceled(toMetricsOpType(operationType));
     }
 
     /**
      * Logs startup time in milliseconds.
-     * @param context
+     *
      * @param startupMs Startup time in milliseconds.
      */
-    public static void logStartupMs(Context context, int startupMs) {
-        logHistogram(context, COUNT_STARTUP_MS, startupMs);
+    public static void logStartupMs(int startupMs) {
+        DocumentsStatsLog.logStartupMs(startupMs);
     }
 
     private static void logInterProviderFileOps(
-            Context context,
-            String histogram,
+            @MetricConsts.Provider int providerType,
             DocumentInfo dst,
             @OpType int operationType) {
         if (operationType == FileOperationService.OPERATION_DELETE) {
-            logHistogram(context, histogram, FILEOP_DELETE);
+            DocumentsStatsLog.logFileOperation(providerType, MetricConsts.FILEOP_DELETE);
         } else {
             assert(dst != null);
-            @Provider int providerType =
-                    isSystemProvider(dst.authority) ? PROVIDER_SYSTEM : PROVIDER_EXTERNAL;
-            logHistogram(context, histogram, getOpCode(operationType, providerType));
+            @MetricConsts.Provider int opProviderType = isSystemProvider(dst.authority)
+                    ? MetricConsts.PROVIDER_SYSTEM : MetricConsts.PROVIDER_EXTERNAL;
+            DocumentsStatsLog.logFileOperation(
+                    providerType, getOpCode(operationType, opProviderType));
         }
     }
 
-    private static void logIntraProviderFileOps(
-            Context context, String authority, @OpType int operationType) {
-        // Find the right histogram to log to, then log the operation.
-        String histogram = isSystemProvider(authority) ? COUNT_FILEOP_SYSTEM : COUNT_FILEOP_EXTERNAL;
-        logHistogram(context, histogram, getOpCode(operationType, PROVIDER_INTRA));
+    private static void logIntraProviderFileOps(String authority, @OpType int operationType) {
+        @MetricConsts.Provider int providerType = isSystemProvider(authority)
+                ? MetricConsts.PROVIDER_SYSTEM : MetricConsts.PROVIDER_EXTERNAL;
+        DocumentsStatsLog.logFileOperation(
+                providerType, getOpCode(operationType, MetricConsts.PROVIDER_INTRA));
     }
 
     /**
      * Logs the action that was started by user.
-     * @param context
+     *
      * @param userAction
      */
-    public static void logUserAction(Context context, @UserAction int userAction) {
-        logHistogram(context, COUNT_USER_ACTION, userAction);
+    public static void logUserAction(@MetricConsts.UserAction int userAction) {
+        DocumentsStatsLog.logUserAction(userAction);
     }
 
     private static void logStorageFileOperationFailure(
-            Context context, @SubFileOp int subFileOp, Uri docUri) {
+            Context context, @MetricConsts.SubFileOp int subFileOp, Uri docUri) {
         assert(Providers.AUTHORITY_STORAGE.equals(docUri.getAuthority()));
-
         boolean isInternal;
         try (ContentProviderClient client = acquireUnstableProviderOrThrow(
                 context.getContentResolver(), Providers.AUTHORITY_STORAGE)) {
             final Path path = DocumentsContract.findDocumentPath(client, docUri);
-
             final ProvidersAccess providers = DocumentsApplication.getProvidersCache(context);
             final RootInfo root = providers.getRootOneshot(
                     Providers.AUTHORITY_STORAGE, path.getRootId());
@@ -714,34 +301,9 @@
             // It's not very likely to have an external storage so log it as internal.
             isInternal = true;
         }
-
-        final String histogram = isInternal
-                ? COUNT_INTERNAL_STORAGE_FILEOP_FAILURE
-                : COUNT_EXTERNAL_STORAGE_FILEOP_FAILURE;
-        logHistogram(context, histogram, subFileOp);
-    }
-
-    /**
-     * Internal method for making a MetricsLogger.count call. Increments the given counter by 1.
-     *
-     * @param context
-     * @param name The counter to increment.
-     */
-    private static void logCount(Context context, String name) {
-        if (DEBUG) Log.d(TAG, name + ": " + 1);
-        // TODO b/111552654 migrate westworld
-    }
-
-    /**
-     * Internal method for making a MetricsLogger.histogram call.
-     *
-     * @param context
-     * @param name The name of the histogram.
-     * @param bucket The bucket to increment.
-     */
-    private static void logHistogram(Context context, String name, @ActionType int bucket) {
-        if (DEBUG) Log.d(TAG, name + ": " + bucket);
-        // TODO b/111552654 migrate westworld
+        @MetricConsts.MetricsAuth final int authority = isInternal
+                ? MetricConsts.AUTH_STORAGE_INTERNAL : MetricConsts.AUTH_STORAGE_EXTERNAL;
+        DocumentsStatsLog.logFileOperationFailure(authority, subFileOp);
     }
 
     /**
@@ -749,61 +311,60 @@
      * small set of hard-coded roots (ones provided by the system). Other roots are all grouped into
      * a single ROOT_OTHER bucket.
      */
-    private static @Root int sanitizeRoot(Uri uri) {
+    private static @MetricConsts.Root int sanitizeRoot(Uri uri) {
         if (uri == null || uri.getAuthority() == null || LauncherActivity.isLaunchUri(uri)) {
-            return ROOT_NONE;
+            return MetricConsts.ROOT_NONE;
         }
-
         switch (uri.getAuthority()) {
             case Providers.AUTHORITY_MEDIA:
                 String rootId = getRootIdSafely(uri);
                 if (rootId == null) {
-                    return ROOT_NONE;
+                    return MetricConsts.ROOT_NONE;
                 }
                 switch (rootId) {
                     case Providers.ROOT_ID_AUDIO:
-                        return ROOT_AUDIO;
+                        return MetricConsts.ROOT_AUDIO;
                     case Providers.ROOT_ID_IMAGES:
-                        return ROOT_IMAGES;
+                        return MetricConsts.ROOT_IMAGES;
                     case Providers.ROOT_ID_VIDEOS:
-                        return ROOT_VIDEOS;
+                        return MetricConsts.ROOT_VIDEOS;
                     default:
-                        return ROOT_OTHER;
+                        return MetricConsts.ROOT_OTHER_DOCS_PROVIDER;
                 }
             case Providers.AUTHORITY_STORAGE:
                 rootId = getRootIdSafely(uri);
                 if (rootId == null) {
-                    return ROOT_NONE;
+                    return MetricConsts.ROOT_NONE;
                 }
                 if (Providers.ROOT_ID_HOME.equals(rootId)) {
-                    return ROOT_HOME;
+                    return MetricConsts.ROOT_HOME;
                 } else {
-                    return ROOT_DEVICE_STORAGE;
+                    return MetricConsts.ROOT_DEVICE_STORAGE;
                 }
             case Providers.AUTHORITY_DOWNLOADS:
-                return ROOT_DOWNLOADS;
+                return MetricConsts.ROOT_DOWNLOADS;
             case Providers.AUTHORITY_MTP:
-                return ROOT_MTP;
+                return MetricConsts.ROOT_MTP;
             default:
-                return ROOT_OTHER;
+                return MetricConsts.ROOT_OTHER_DOCS_PROVIDER;
         }
     }
 
     /** @see #sanitizeRoot(Uri) */
-    private static @Root int sanitizeRoot(RootInfo root) {
+    public static @MetricConsts.Root int sanitizeRoot(RootInfo root) {
         if (root.isRecents()) {
             // Recents root is special and only identifiable via this method call. Other roots are
             // identified by URI.
-            return ROOT_RECENTS;
+            return MetricConsts.ROOT_RECENTS;
         } else {
             return sanitizeRoot(root.getUri());
         }
     }
 
     /** @see #sanitizeRoot(Uri) */
-    private static @Root int sanitizeRoot(ResolveInfo info) {
+    public static @MetricConsts.Root int sanitizeRoot(ResolveInfo info) {
         // Log all apps under a single bucket in the roots histogram.
-        return ROOT_THIRD_PARTY_APP;
+        return MetricConsts.ROOT_THIRD_PARTY_APP;
     }
 
     /**
@@ -813,32 +374,32 @@
      * @param mimeType
      * @return
      */
-    private static @Mime int sanitizeMime(String mimeType) {
+    public static @MetricConsts.Mime int sanitizeMime(String mimeType) {
         if (mimeType == null) {
-            return MIME_NONE;
+            return MetricConsts.MIME_NONE;
         } else if ("*/*".equals(mimeType)) {
-            return MIME_ANY;
+            return MetricConsts.MIME_ANY;
         } else {
             String type = mimeType.substring(0, mimeType.indexOf('/'));
             switch (type) {
                 case "application":
-                    return MIME_APPLICATION;
+                    return MetricConsts.MIME_APPLICATION;
                 case "audio":
-                    return MIME_AUDIO;
+                    return MetricConsts.MIME_AUDIO;
                 case "image":
-                    return MIME_IMAGE;
+                    return MetricConsts.MIME_IMAGE;
                 case "message":
-                    return MIME_MESSAGE;
+                    return MetricConsts.MIME_MESSAGE;
                 case "multipart":
-                    return MIME_MULTIPART;
+                    return MetricConsts.MIME_MULTIPART;
                 case "text":
-                    return MIME_TEXT;
+                    return MetricConsts.MIME_TEXT;
                 case "video":
-                    return MIME_VIDEO;
+                    return MetricConsts.MIME_VIDEO;
             }
         }
         // Bucket all other types into one bucket.
-        return MIME_OTHER;
+        return MetricConsts.MIME_OTHER;
     }
 
     private static boolean isSystemProvider(String authority) {
@@ -858,85 +419,86 @@
      * @return An opcode, suitable for use as histogram bucket, for the given operation/provider
      *         combination.
      */
-    private static @FileOp int getOpCode(@OpType int operation, @Provider int providerType) {
+    private static @MetricConsts.FileOp int getOpCode(
+            @OpType int operation, @MetricConsts.Provider int providerType) {
         switch (operation) {
             case FileOperationService.OPERATION_COPY:
                 switch (providerType) {
-                    case PROVIDER_INTRA:
-                        return FILEOP_COPY_INTRA_PROVIDER;
-                    case PROVIDER_SYSTEM:
-                        return FILEOP_COPY_SYSTEM_PROVIDER;
-                    case PROVIDER_EXTERNAL:
-                        return FILEOP_COPY_EXTERNAL_PROVIDER;
+                    case MetricConsts.PROVIDER_INTRA:
+                        return MetricConsts.FILEOP_COPY_INTRA_PROVIDER;
+                    case MetricConsts.PROVIDER_SYSTEM:
+                        return MetricConsts.FILEOP_COPY_SYSTEM_PROVIDER;
+                    case MetricConsts.PROVIDER_EXTERNAL:
+                        return MetricConsts.FILEOP_COPY_EXTERNAL_PROVIDER;
                 }
             case FileOperationService.OPERATION_COMPRESS:
                 switch (providerType) {
-                    case PROVIDER_INTRA:
-                        return FILEOP_COMPRESS_INTRA_PROVIDER;
-                    case PROVIDER_SYSTEM:
-                        return FILEOP_COMPRESS_SYSTEM_PROVIDER;
-                    case PROVIDER_EXTERNAL:
-                        return FILEOP_COMPRESS_EXTERNAL_PROVIDER;
+                    case MetricConsts.PROVIDER_INTRA:
+                        return MetricConsts.FILEOP_COMPRESS_INTRA_PROVIDER;
+                    case MetricConsts.PROVIDER_SYSTEM:
+                        return MetricConsts.FILEOP_COMPRESS_SYSTEM_PROVIDER;
+                    case MetricConsts.PROVIDER_EXTERNAL:
+                        return MetricConsts.FILEOP_COMPRESS_EXTERNAL_PROVIDER;
                 }
-             case FileOperationService.OPERATION_EXTRACT:
+            case FileOperationService.OPERATION_EXTRACT:
                 switch (providerType) {
-                    case PROVIDER_INTRA:
-                        return FILEOP_EXTRACT_INTRA_PROVIDER;
-                    case PROVIDER_SYSTEM:
-                        return FILEOP_EXTRACT_SYSTEM_PROVIDER;
-                    case PROVIDER_EXTERNAL:
-                        return FILEOP_EXTRACT_EXTERNAL_PROVIDER;
+                    case MetricConsts.PROVIDER_INTRA:
+                        return MetricConsts.FILEOP_EXTRACT_INTRA_PROVIDER;
+                    case MetricConsts.PROVIDER_SYSTEM:
+                        return MetricConsts.FILEOP_EXTRACT_SYSTEM_PROVIDER;
+                    case MetricConsts.PROVIDER_EXTERNAL:
+                        return MetricConsts.FILEOP_EXTRACT_EXTERNAL_PROVIDER;
                 }
             case FileOperationService.OPERATION_MOVE:
                 switch (providerType) {
-                    case PROVIDER_INTRA:
-                        return FILEOP_MOVE_INTRA_PROVIDER;
-                    case PROVIDER_SYSTEM:
-                        return FILEOP_MOVE_SYSTEM_PROVIDER;
-                    case PROVIDER_EXTERNAL:
-                        return FILEOP_MOVE_EXTERNAL_PROVIDER;
+                    case MetricConsts.PROVIDER_INTRA:
+                        return MetricConsts.FILEOP_MOVE_INTRA_PROVIDER;
+                    case MetricConsts.PROVIDER_SYSTEM:
+                        return MetricConsts.FILEOP_MOVE_SYSTEM_PROVIDER;
+                    case MetricConsts.PROVIDER_EXTERNAL:
+                        return MetricConsts.FILEOP_MOVE_EXTERNAL_PROVIDER;
                 }
             case FileOperationService.OPERATION_DELETE:
-                return FILEOP_DELETE;
+                return MetricConsts.FILEOP_DELETE;
             default:
                 Log.w(TAG, "Unrecognized operation type when logging a file operation");
-                return FILEOP_OTHER;
+                return MetricConsts.FILEOP_OTHER;
         }
     }
 
     /**
      * Maps FileOperationService OpType values, to MetricsOpType values.
      */
-    private static @MetricsOpType int toMetricsOpType(@OpType int operation) {
+    private static @MetricConsts.FileOp int toMetricsOpType(@OpType int operation) {
         switch (operation) {
             case FileOperationService.OPERATION_COPY:
-                return OPERATION_COPY;
+                return MetricConsts.FILEOP_COPY;
             case FileOperationService.OPERATION_MOVE:
-                return OPERATION_MOVE;
+                return MetricConsts.FILEOP_MOVE;
             case FileOperationService.OPERATION_DELETE:
-                return OPERATION_DELETE;
+                return MetricConsts.FILEOP_DELETE;
             case FileOperationService.OPERATION_UNKNOWN:
             default:
-                return OPERATION_UNKNOWN;
+                return MetricConsts.FILEOP_UNKNOWN;
         }
     }
 
-    private static @MetricsAction int toMetricsAction(int action) {
+    private static @MetricConsts.MetricsAction int toMetricsAction(int action) {
         switch(action) {
             case State.ACTION_OPEN:
-                return ACTION_OPEN;
+                return MetricConsts.ACTION_OPEN;
             case State.ACTION_CREATE:
-                return ACTION_CREATE;
+                return MetricConsts.ACTION_CREATE;
             case State.ACTION_GET_CONTENT:
-                return ACTION_GET_CONTENT;
+                return MetricConsts.ACTION_GET_CONTENT;
             case State.ACTION_OPEN_TREE:
-                return ACTION_OPEN_TREE;
+                return MetricConsts.ACTION_OPEN_TREE;
             case State.ACTION_BROWSE:
-                return ACTION_BROWSE;
+                return MetricConsts.ACTION_BROWSE;
             case State.ACTION_PICK_COPY_DESTINATION:
-                return ACTION_PICK_COPY_DESTINATION;
+                return MetricConsts.ACTION_PICK_COPY_DESTINATION;
             default:
-                return ACTION_OTHER;
+                return MetricConsts.ACTION_OTHER;
         }
     }
 
diff --git a/src/com/android/documentsui/ScopedAccessActivity.java b/src/com/android/documentsui/ScopedAccessActivity.java
index 6deab4e..425c275 100644
--- a/src/com/android/documentsui/ScopedAccessActivity.java
+++ b/src/com/android/documentsui/ScopedAccessActivity.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_DEPRECATED;
+import static com.android.documentsui.MetricConsts.SCOPED_DIRECTORY_ACCESS_DEPRECATED;
 import static com.android.documentsui.ScopedAccessMetrics.logInvalidScopedAccessRequest;
 
 import android.app.Activity;
@@ -33,7 +33,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        logInvalidScopedAccessRequest(this, SCOPED_DIRECTORY_ACCESS_DEPRECATED);
+        logInvalidScopedAccessRequest(SCOPED_DIRECTORY_ACCESS_DEPRECATED);
         setResult(RESULT_CANCELED);
         finish();
     }
diff --git a/src/com/android/documentsui/ScopedAccessMetrics.java b/src/com/android/documentsui/ScopedAccessMetrics.java
index 0af2bf5..c4b8627 100644
--- a/src/com/android/documentsui/ScopedAccessMetrics.java
+++ b/src/com/android/documentsui/ScopedAccessMetrics.java
@@ -16,14 +16,7 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
-
-import androidx.annotation.StringDef;
-import android.content.Context;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import android.util.DocumentsStatsLog;
 
 /**
  * Methods for logging scoped directory access metrics.
@@ -31,47 +24,7 @@
 public final class ScopedAccessMetrics {
     private static final String TAG = "ScopedAccessMetrics";
 
-    // Types for logInvalidScopedAccessRequest
-    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS =
-            "docsui_scoped_directory_access_invalid_args";
-    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY =
-            "docsui_scoped_directory_access_invalid_dir";
-    public static final String SCOPED_DIRECTORY_ACCESS_ERROR =
-            "docsui_scoped_directory_access_error";
-    public static final String SCOPED_DIRECTORY_ACCESS_DEPRECATED =
-            "docsui_scoped_directory_access_deprecated";
-
-    @StringDef(value = {
-            SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS,
-            SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY,
-            SCOPED_DIRECTORY_ACCESS_ERROR,
-            SCOPED_DIRECTORY_ACCESS_DEPRECATED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface InvalidScopedAccess{}
-
-    public static void logInvalidScopedAccessRequest(Context context,
-            @InvalidScopedAccess String type) {
-        switch (type) {
-            case SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS:
-            case SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY:
-            case SCOPED_DIRECTORY_ACCESS_ERROR:
-            case SCOPED_DIRECTORY_ACCESS_DEPRECATED:
-                logCount(context, type);
-                break;
-            default:
-                Log.wtf(TAG, "invalid InvalidScopedAccess: " + type);
-        }
-    }
-
-    /**
-     * Internal method for making a MetricsLogger.count call. Increments the given counter by 1.
-     *
-     * @param context
-     * @param name The counter to increment.
-     */
-    private static void logCount(Context context, String name) {
-        if (DEBUG) Log.d(TAG, name + ": " + 1);
-        // TODO b/111552654 migrate westworld
+    public static void logInvalidScopedAccessRequest(@MetricConsts.InvalidScopedAccess int type) {
+        DocumentsStatsLog.logInvalidScopedAccessRequest(type);
     }
 }
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
index c15556f..5e05115 100644
--- a/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -75,6 +75,7 @@
 import com.android.documentsui.Injector;
 import com.android.documentsui.Injector.ContentScoped;
 import com.android.documentsui.Injector.Injected;
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.Model;
 import com.android.documentsui.R;
@@ -757,7 +758,7 @@
 
     // Support for opening multiple documents is currently exclusive to DocumentsActivity.
     private void openDocuments(final Selection selected) {
-        Metrics.logUserAction(getContext(), Metrics.USER_ACTION_OPEN);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_OPEN);
 
         // Model must be accessed in UI thread, since underlying cursor is not threadsafe.
         List<DocumentInfo> docs = mModel.getDocuments(selected);
@@ -769,7 +770,7 @@
     }
 
     private void showChooserForDoc(final Selection<String> selected) {
-        Metrics.logUserAction(getContext(), Metrics.USER_ACTION_OPEN);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_OPEN);
 
         assert selected.size() == 1;
         DocumentInfo doc =
@@ -782,16 +783,16 @@
             final @OpType int mode) {
         switch (mode) {
             case FileOperationService.OPERATION_COPY:
-                Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COPY_TO);
+                Metrics.logUserAction(MetricConsts.USER_ACTION_COPY_TO);
                 break;
             case FileOperationService.OPERATION_COMPRESS:
-                Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COMPRESS);
+                Metrics.logUserAction(MetricConsts.USER_ACTION_COMPRESS);
                 break;
             case FileOperationService.OPERATION_EXTRACT:
-                Metrics.logUserAction(getContext(), Metrics.USER_ACTION_EXTRACT_TO);
+                Metrics.logUserAction(MetricConsts.USER_ACTION_EXTRACT_TO);
                 break;
             case FileOperationService.OPERATION_MOVE:
-                Metrics.logUserAction(getContext(), Metrics.USER_ACTION_MOVE_TO);
+                Metrics.logUserAction(MetricConsts.USER_ACTION_MOVE_TO);
                 break;
         }
 
@@ -890,7 +891,7 @@
     }
 
     private void renameDocuments(Selection selected) {
-        Metrics.logUserAction(getContext(), Metrics.USER_ACTION_RENAME);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_RENAME);
 
         // Batch renaming not supported
         // Rename option is only available in menu when 1 document selected
@@ -909,7 +910,7 @@
      * Paste selection files from the primary clip into the current window.
      */
     public void pasteFromClipboard() {
-        Metrics.logUserAction(getContext(), Metrics.USER_ACTION_PASTE_CLIPBOARD);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_PASTE_CLIPBOARD);
         // Since we are pasting into the current window, we already have the destination in the
         // stack. No need for a destination DocumentInfo.
         mClipper.copyFromClipboard(
diff --git a/src/com/android/documentsui/dirlist/RenameDocumentFragment.java b/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
index 8e9dd1c..e9ccbcc 100644
--- a/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
+++ b/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
@@ -195,7 +195,7 @@
         } else if (activity.getInjector().getModel().hasFileWithName(newDisplayName)){
             mRenameInputWrapper.setError(getContext().getString(R.string.name_conflict));
             selectFileName(mEditText);
-            Metrics.logRenameFileError(getContext());
+            Metrics.logRenameFileError();
         } else {
             new RenameDocumentsTask(activity, newDisplayName).execute(mDocument);
         }
@@ -226,10 +226,10 @@
         @Override
         protected void onPostExecute(DocumentInfo result) {
             if (result != null) {
-                Metrics.logRenameFileOperation(getContext());
+                Metrics.logRenameFileOperation();
             } else {
                 Snackbars.showRenameFailed(mActivity);
-                Metrics.logRenameFileError(getContext());
+                Metrics.logRenameFileError();
             }
             if (mDialog != null) {
                 mDialog.dismiss();
diff --git a/src/com/android/documentsui/files/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index af48af0..3465bf2 100644
--- a/src/com/android/documentsui/files/ActionHandler.java
+++ b/src/com/android/documentsui/files/ActionHandler.java
@@ -41,6 +41,7 @@
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.DragAndDropManager;
 import com.android.documentsui.Injector;
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.Model;
 import com.android.documentsui.R;
@@ -145,7 +146,7 @@
 
     @Override
     public void openSettings(RootInfo root) {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_SETTINGS);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_SETTINGS);
         final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
         intent.setDataAndType(root.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
         mActivity.startActivity(intent);
@@ -185,7 +186,7 @@
 
     @Override
     public void openRoot(RootInfo root) {
-        Metrics.logRootVisited(mActivity, Metrics.FILES_SCOPE, root);
+        Metrics.logRootVisited(MetricConsts.FILES_SCOPE, root);
         mActivity.onRootPicked(root);
     }
 
@@ -234,7 +235,7 @@
 
     @Override
     public void cutToClipboard() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_CUT_CLIPBOARD);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_CUT_CLIPBOARD);
         Selection<String> selection = getSelectedOrFocused();
 
         if (selection.isEmpty()) {
@@ -255,7 +256,7 @@
 
     @Override
     public void copyToClipboard() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_COPY_CLIPBOARD);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_COPY_CLIPBOARD);
         Selection<String> selection = getSelectedOrFocused();
 
         if (selection.isEmpty()) {
@@ -270,7 +271,7 @@
 
     @Override
     public void viewInOwner() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_VIEW_IN_APPLICATION);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_VIEW_IN_APPLICATION);
         Selection<String> selection = getSelectedOrFocused();
 
         if (selection.isEmpty() || selection.size() > 1) {
@@ -292,7 +293,7 @@
 
     @Override
     public void deleteSelectedDocuments() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_DELETE);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_DELETE);
         Selection selection = getSelectedOrFocused();
 
         if (selection.isEmpty()) {
@@ -343,7 +344,7 @@
 
     @Override
     public void shareSelectedDocuments() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_SHARE);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_SHARE);
 
         Selection<String> selection = getStableSelection();
 
@@ -697,7 +698,7 @@
 
     @Override
     public void showInspector(DocumentInfo doc) {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_INSPECTOR);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_INSPECTOR);
         Intent intent = new Intent(mActivity, InspectorActivity.class);
         intent.setData(doc.derivedUri);
 
diff --git a/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java
index 1af85c1..8266a80 100644
--- a/src/com/android/documentsui/picker/ActionHandler.java
+++ b/src/com/android/documentsui/picker/ActionHandler.java
@@ -43,6 +43,7 @@
 import com.android.documentsui.ActivityConfig;
 import com.android.documentsui.DocumentsAccess;
 import com.android.documentsui.Injector;
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.Model;
 import com.android.documentsui.base.BooleanConsumer;
@@ -238,13 +239,13 @@
 
     @Override
     public void openRoot(RootInfo root) {
-        Metrics.logRootVisited(mActivity, Metrics.PICKER_SCOPE, root);
+        Metrics.logRootVisited(MetricConsts.PICKER_SCOPE, root);
         mActivity.onRootPicked(root);
     }
 
     @Override
     public void openRoot(ResolveInfo info) {
-        Metrics.logAppVisited(mActivity, info);
+        Metrics.logAppVisited(info);
         final Intent intent = new Intent(mActivity.getIntent());
         intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);
         intent.setComponent(new ComponentName(
diff --git a/src/com/android/documentsui/services/CopyJob.java b/src/com/android/documentsui/services/CopyJob.java
index 5761fed..6053800 100644
--- a/src/com/android/documentsui/services/CopyJob.java
+++ b/src/com/android/documentsui/services/CopyJob.java
@@ -62,6 +62,7 @@
 import android.webkit.MimeTypeMap;
 
 import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
@@ -231,7 +232,7 @@
             }
         }
 
-        Metrics.logFileOperation(service, operationType, mResolvedDocs, mDstInfo);
+        Metrics.logFileOperation(operationType, mResolvedDocs, mDstInfo);
     }
 
     /**
@@ -323,15 +324,14 @@
                 try {
                     if (DocumentsContract.copyDocument(getClient(src), src.derivedUri,
                             dstDirInfo.derivedUri) != null) {
-                        Metrics.logFileOperated(
-                                appContext, operationType, Metrics.OPMODE_PROVIDER);
+                        Metrics.logFileOperated(operationType, MetricConsts.OPMODE_PROVIDER);
                         return;
                     }
                 } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                     Log.e(TAG, "Provider side copy failed for: " + src.derivedUri
                             + " due to an exception.", e);
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_QUICK_COPY, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_QUICK_COPY, src.derivedUri);
                 }
 
                 // If optimized copy fails, then fallback to byte-by-byte copy.
@@ -362,7 +362,7 @@
                 streamTypes = getContentResolver().getStreamTypes(src.derivedUri, "*/*");
             } catch (RuntimeException e) {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_OBTAIN_STREAM_TYPE, src.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_OBTAIN_STREAM_TYPE, src.derivedUri);
                 throw new ResourceException(
                         "Failed to obtain streamable types for %s due to an exception.",
                         src.derivedUri, e);
@@ -375,7 +375,7 @@
                         (extension != null ? "." + extension : src.displayName);
             } else {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_OBTAIN_STREAM_TYPE, src.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_OBTAIN_STREAM_TYPE, src.derivedUri);
                 throw new ResourceException("Cannot copy virtual file %s. No streamable formats "
                         + "available.", src.derivedUri);
             }
@@ -392,7 +392,7 @@
                     getClient(dest), dest.derivedUri, dstMimeType, dstDisplayName);
         } catch (FileNotFoundException | RemoteException | RuntimeException e) {
             Metrics.logFileOperationFailure(
-                    appContext, Metrics.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
+                    appContext, MetricConsts.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
             throw new ResourceException(
                     "Couldn't create destination document " + dstDisplayName + " in directory %s "
                     + "due to an exception.", dest.derivedUri, e);
@@ -400,7 +400,7 @@
         if (dstUri == null) {
             // If this is a directory, the entire subdir will not be copied over.
             Metrics.logFileOperationFailure(
-                    appContext, Metrics.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
+                    appContext, MetricConsts.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
             throw new ResourceException(
                     "Couldn't create destination document " + dstDisplayName + " in directory %s.",
                     dest.derivedUri);
@@ -411,7 +411,7 @@
             dstInfo = DocumentInfo.fromUri(getContentResolver(), dstUri);
         } catch (FileNotFoundException | RuntimeException e) {
             Metrics.logFileOperationFailure(
-                    appContext, Metrics.SUBFILEOP_QUERY_DOCUMENT, dstUri);
+                    appContext, MetricConsts.SUBFILEOP_QUERY_DOCUMENT, dstUri);
             throw new ResourceException("Could not load DocumentInfo for newly created file %s.",
                     dstUri);
         }
@@ -450,7 +450,7 @@
                 cursor = queryChildren(srcDir, queryColumns);
             } catch (RemoteException | RuntimeException e) {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_QUERY_CHILDREN, srcDir.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_QUERY_CHILDREN, srcDir.derivedUri);
                 throw new ResourceException("Failed to query children of %s due to an exception.",
                         srcDir.derivedUri, e);
             }
@@ -509,7 +509,7 @@
                                 src.derivedUri, mimeType, null, mSignal);
                 } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_OPEN_FILE, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_OPEN_FILE, src.derivedUri);
                     throw new ResourceException("Failed to open a file as asset for %s due to an "
                             + "exception.", src.derivedUri, e);
                 }
@@ -518,33 +518,31 @@
                     in = new AssetFileDescriptor.AutoCloseInputStream(srcFileAsAsset);
                 } catch (IOException e) {
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_OPEN_FILE, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_OPEN_FILE, src.derivedUri);
                     throw new ResourceException("Failed to open a file input stream for %s due "
                             + "an exception.", src.derivedUri, e);
                 }
 
-                Metrics.logFileOperated(
-                        appContext, operationType, Metrics.OPMODE_CONVERTED);
+                Metrics.logFileOperated(operationType, MetricConsts.OPMODE_CONVERTED);
             } else {
                 try {
                     srcFile = getClient(src).openFile(src.derivedUri, "r", mSignal);
                 } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_OPEN_FILE, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_OPEN_FILE, src.derivedUri);
                     throw new ResourceException(
                             "Failed to open a file for %s due to an exception.", src.derivedUri, e);
                 }
                 in = new ParcelFileDescriptor.AutoCloseInputStream(srcFile);
 
-                Metrics.logFileOperated(
-                        appContext, operationType, Metrics.OPMODE_CONVENTIONAL);
+                Metrics.logFileOperated(operationType, MetricConsts.OPMODE_CONVENTIONAL);
             }
 
             try {
                 dstFile = getClient(dest).openFile(dest.derivedUri, "w", mSignal);
             } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_OPEN_FILE, dest.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_OPEN_FILE, dest.derivedUri);
                 throw new ResourceException("Failed to open the destination file %s for writing "
                         + "due to an exception.", dest.derivedUri, e);
             }
@@ -595,7 +593,7 @@
             } catch (IOException e) {
                 Metrics.logFileOperationFailure(
                         appContext,
-                        Metrics.SUBFILEOP_WRITE_FILE,
+                        MetricConsts.SUBFILEOP_WRITE_FILE,
                         dest.derivedUri);
                 throw new ResourceException(
                         "Failed to copy bytes from %s to %s due to an IO exception.",
diff --git a/src/com/android/documentsui/services/DeleteJob.java b/src/com/android/documentsui/services/DeleteJob.java
index 82c6e13..b918ab7 100644
--- a/src/com/android/documentsui/services/DeleteJob.java
+++ b/src/com/android/documentsui/services/DeleteJob.java
@@ -26,6 +26,7 @@
 import android.net.Uri;
 import android.util.Log;
 
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
@@ -116,7 +117,7 @@
                 deleteDocument(doc, parentDoc);
             } catch (ResourceException e) {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_DELETE_DOCUMENT, doc.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_DELETE_DOCUMENT, doc.derivedUri);
                 Log.e(TAG, "Failed to delete document @ " + doc.derivedUri, e);
                 onFileFailed(doc);
             }
@@ -127,7 +128,7 @@
             }
         }
 
-        Metrics.logFileOperation(service, operationType, mResolvedDocs, null);
+        Metrics.logFileOperation(operationType, mResolvedDocs, null);
     }
 
     @Override
diff --git a/src/com/android/documentsui/services/Job.java b/src/com/android/documentsui/services/Job.java
index cc5208e..1e01410 100644
--- a/src/com/android/documentsui/services/Job.java
+++ b/src/com/android/documentsui/services/Job.java
@@ -160,7 +160,7 @@
             // No exceptions should be thrown here, as all calls to the provider must be
             // handled within Job implementations. However, just in case catch them here.
             Log.e(TAG, "Operation failed due to an unhandled runtime exception.", e);
-            Metrics.logFileOperationErrors(service, operationType, failedDocs, failedUris);
+            Metrics.logFileOperationErrors(operationType, failedDocs, failedUris);
         } finally {
             mState = (mState == STATE_STARTED || mState == STATE_SET_UP) ? STATE_COMPLETED : mState;
             finish();
@@ -221,7 +221,7 @@
     final void cancel() {
         mState = STATE_CANCELED;
         mSignal.cancel();
-        Metrics.logFileOperationCancelled(service, operationType);
+        Metrics.logFileOperationCancelled(operationType);
     }
 
     final boolean isCanceled() {
diff --git a/src/com/android/documentsui/services/MoveJob.java b/src/com/android/documentsui/services/MoveJob.java
index 10185e2..585cfe0 100644
--- a/src/com/android/documentsui/services/MoveJob.java
+++ b/src/com/android/documentsui/services/MoveJob.java
@@ -30,6 +30,7 @@
 import android.provider.DocumentsContract.Document;
 import android.util.Log;
 
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
@@ -149,13 +150,12 @@
                     if (DocumentsContract.moveDocument(getClient(src), src.derivedUri,
                             srcParent != null ? srcParent.derivedUri : mSrcParent.derivedUri,
                             dest.derivedUri) != null) {
-                        Metrics.logFileOperated(
-                                appContext, operationType, Metrics.OPMODE_PROVIDER);
+                        Metrics.logFileOperated(operationType, MetricConsts.OPMODE_PROVIDER);
                         return;
                     }
                 } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_QUICK_MOVE, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_QUICK_MOVE, src.derivedUri);
                     Log.e(TAG, "Provider side move failed for: " + src.derivedUri
                             + " due to an exception: ", e);
                 }
diff --git a/src/com/android/documentsui/sorting/SortController.java b/src/com/android/documentsui/sorting/SortController.java
index da6c3c3..c4ee018 100644
--- a/src/com/android/documentsui/sorting/SortController.java
+++ b/src/com/android/documentsui/sorting/SortController.java
@@ -21,6 +21,7 @@
 
 import android.view.View;
 
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.State;
@@ -64,13 +65,13 @@
         sortModel.setMetricRecorder((SortDimension dimension) -> {
             switch (dimension.getId()) {
                 case SortModel.SORT_DIMENSION_ID_TITLE:
-                    Metrics.logUserAction(activity, Metrics.USER_ACTION_SORT_NAME);
+                    Metrics.logUserAction(MetricConsts.USER_ACTION_SORT_NAME);
                     break;
                 case SortModel.SORT_DIMENSION_ID_SIZE:
-                    Metrics.logUserAction(activity, Metrics.USER_ACTION_SORT_SIZE);
+                    Metrics.logUserAction(MetricConsts.USER_ACTION_SORT_SIZE);
                     break;
                 case SortModel.SORT_DIMENSION_ID_DATE:
-                    Metrics.logUserAction(activity, Metrics.USER_ACTION_SORT_DATE);
+                    Metrics.logUserAction(MetricConsts.USER_ACTION_SORT_DATE);
                     break;
             }
         });