Merge "Resolve a metrics conflict." into arc-apps
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 52971c8..388a8ea 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -156,8 +156,8 @@
       <item quantity="other">قالب این فایل‌ها تغییر داده شد: <xliff:g id="LIST_1">%1$s</xliff:g></item>
     </plurals>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="139644798886220070">
-      <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل در کلیپ‌بورد کپی شد.</item>
-      <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل در کلیپ‌بورد کپی شد.</item>
+      <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل در بریده‌دان کپی شد.</item>
+      <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل در بریده‌دان کپی شد.</item>
     </plurals>
     <string name="file_operation_rejected" msgid="4301554203329008794">"عملکرد فایل پشتیبانی نمی‌شود."</string>
     <string name="file_operation_error" msgid="2234357335716533795">"عملکرد فایل ناموفق بود."</string>
diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml
index 8eca6e2..be01ee8 100644
--- a/res/values-pt-rBR/strings.xml
+++ b/res/values-pt-rBR/strings.xml
@@ -47,7 +47,7 @@
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"Copiar"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"Colar"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"Colar na pasta"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"Mostrar armaz. interno"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"Armazenamento interno"</string>
     <string name="menu_advanced_hide" msgid="6488381508009246334">"Ocultar armaz. interno"</string>
     <string name="button_select" msgid="240863497069321364">"Selecionar"</string>
     <string name="button_copy" msgid="8219059853840996027">"Copiar"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 8eca6e2..be01ee8 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -47,7 +47,7 @@
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"Copiar"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"Colar"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"Colar na pasta"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"Mostrar armaz. interno"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"Armazenamento interno"</string>
     <string name="menu_advanced_hide" msgid="6488381508009246334">"Ocultar armaz. interno"</string>
     <string name="button_select" msgid="240863497069321364">"Selecionar"</string>
     <string name="button_copy" msgid="8219059853840996027">"Copiar"</string>
diff --git a/src/com/android/documentsui/Metrics.java b/src/com/android/documentsui/Metrics.java
index b9a9e18..5d938c0 100644
--- a/src/com/android/documentsui/Metrics.java
+++ b/src/com/android/documentsui/Metrics.java
@@ -85,6 +85,8 @@
             = "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
@@ -352,6 +354,16 @@
     @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
@@ -514,6 +526,18 @@
         }
     }
 
+    public static void logFileOperated(
+            Context context, @OpType int operationType, @FileOpMode int approach) {
+        switch (operationType) {
+            case FileOperationService.OPERATION_COPY:
+                logHistogram(context, COUNT_FILE_COPIED, approach);
+                break;
+            case FileOperationService.OPERATION_MOVE:
+                logHistogram(context, COUNT_FILE_MOVED, approach);
+                break;
+        }
+    }
+
     /**
      * 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
diff --git a/src/com/android/documentsui/services/CopyJob.java b/src/com/android/documentsui/services/CopyJob.java
index 2315209..89d4260 100644
--- a/src/com/android/documentsui/services/CopyJob.java
+++ b/src/com/android/documentsui/services/CopyJob.java
@@ -28,7 +28,6 @@
 import static com.android.documentsui.services.FileOperationService.EXTRA_DIALOG_TYPE;
 import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION_TYPE;
 import static com.android.documentsui.services.FileOperationService.EXTRA_FAILED_DOCS;
-import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_LIST;
 import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
 import static com.android.documentsui.services.FileOperationService.MESSAGE_FINISH;
 import static com.android.documentsui.services.FileOperationService.MESSAGE_PROGRESS;
@@ -377,6 +376,8 @@
                 try {
                     if (DocumentsContract.copyDocument(getClient(src), src.derivedUri,
                             dstDirInfo.derivedUri) != null) {
+                        Metrics.logFileOperated(
+                                appContext, operationType, Metrics.OPMODE_PROVIDER);
                         return;
                     }
                 } catch (RemoteException | RuntimeException e) {
@@ -569,6 +570,9 @@
                     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);
             } else {
                 try {
                     srcFile = getClient(src).openFile(src.derivedUri, "r", canceller);
@@ -579,6 +583,9 @@
                             "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);
             }
 
             try {
diff --git a/src/com/android/documentsui/services/MoveJob.java b/src/com/android/documentsui/services/MoveJob.java
index b24bc67..431180a 100644
--- a/src/com/android/documentsui/services/MoveJob.java
+++ b/src/com/android/documentsui/services/MoveJob.java
@@ -149,6 +149,8 @@
                     if (DocumentsContract.moveDocument(getClient(src), src.derivedUri,
                             srcParent != null ? srcParent.derivedUri : mSrcParent.derivedUri,
                             dest.derivedUri) != null) {
+                        Metrics.logFileOperated(
+                                appContext, operationType, Metrics.OPMODE_PROVIDER);
                         return;
                     }
                 } catch (RemoteException | RuntimeException e) {