Loading src/com/android/documentsui/DevicePolicyMetricConsts.java 0 → 100644 +54 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2020 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/devicepolicy/device_policy_enums.proto. */ public class DevicePolicyMetricConsts { public static final int ATOM_DEVICE_POLICY_EVENT = 103; @IntDef(flag = true, value = { ATOM_DEVICE_POLICY_EVENT, }) @Retention(RetentionPolicy.SOURCE) public @interface Atom { } // Codes representing DocsUI event id. public static final int EVENT_ID_DOCSUI_EMPTY_STATE_NO_PERMISSION = 173; public static final int EVENT_ID_DOCSUI_EMPTY_STATE_QUIET_MODE = 174; public static final int EVENT_ID_DOCSUI_LAUNCH_OTHER_APP = 175; public static final int EVENT_ID_DOCSUI_PICK_RESULT = 176; @IntDef(flag = true, value = { EVENT_ID_DOCSUI_EMPTY_STATE_NO_PERMISSION, EVENT_ID_DOCSUI_EMPTY_STATE_QUIET_MODE, EVENT_ID_DOCSUI_LAUNCH_OTHER_APP, EVENT_ID_DOCSUI_PICK_RESULT, }) @Retention(RetentionPolicy.SOURCE) public @interface EventId { } } src/com/android/documentsui/Metrics.java +43 −0 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.provider.DocumentsContract; import android.provider.DocumentsContract.Path; import android.provider.DocumentsContract.Path; import android.provider.DocumentsProvider; import android.provider.DocumentsProvider; import android.util.Log; import android.util.Log; import android.util.StatsEvent; import android.util.StatsLog; import androidx.annotation.Nullable; import androidx.annotation.Nullable; Loading Loading @@ -89,6 +91,24 @@ public final class Metrics { DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_ROOT_VISITED, scope, sanitizeRoot(info)); DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_ROOT_VISITED, scope, sanitizeRoot(info)); } } public static void logLaunchOtherApp(boolean acrossProfile) { DevicePolicyEventLogger.write(DevicePolicyMetricConsts.EVENT_ID_DOCSUI_LAUNCH_OTHER_APP, acrossProfile); } public static void logCrossProfileEmptyState(CrossProfileException e) { int eventId; if (e instanceof CrossProfileQuietModeException) { eventId = DevicePolicyMetricConsts.EVENT_ID_DOCSUI_EMPTY_STATE_QUIET_MODE; } else if (e instanceof CrossProfileNoPermissionException) { eventId = DevicePolicyMetricConsts.EVENT_ID_DOCSUI_EMPTY_STATE_NO_PERMISSION; } else { Log.d(TAG, "logCrossProfileEmptyState: Unexpected exception " + e); return; } DevicePolicyEventLogger.write(eventId, /* booleanValue= */ true); } /** /** * Logs an app visited event in file pickers. Call this when the user visits * Logs an app visited event in file pickers. Call this when the user visits * on an app in the RootsFragment. * on an app in the RootsFragment. Loading Loading @@ -331,6 +351,9 @@ public final class Metrics { result.getRoot(), result.getRoot(), result.getMimeType(), result.getMimeType(), result.getRepeatedPickTimes()); result.getRepeatedPickTimes()); DevicePolicyEventLogger.write(DevicePolicyMetricConsts.EVENT_ID_DOCSUI_PICK_RESULT, result.hasCrossProfileUri()); } } private static void logStorageFileOperationFailure( private static void logStorageFileOperationFailure( Loading Loading @@ -612,4 +635,24 @@ public final class Metrics { } } return null; return null; } } /** * The implementation is copied from StatsLogInternal for the DEVICE_POLICY_EVENT. */ private static class DevicePolicyEventLogger { public static void write(@DevicePolicyMetricConsts.EventId int eventId, boolean booleanValue) { final StatsEvent.Builder builder = StatsEvent.newBuilder(); builder.setAtomId(DevicePolicyMetricConsts.ATOM_DEVICE_POLICY_EVENT); builder.writeInt(eventId); // eventId builder.writeString(null); // adminPackageName builder.writeInt(0); // intValue builder.writeBoolean(booleanValue); // booleanValue builder.writeLong(0); // timePeriodMs builder.writeByteArray(new byte[0]); // bytes builder.usePooledBuffer(); StatsLog.write(builder.build()); } } } } src/com/android/documentsui/dirlist/Message.java +5 −1 Original line number Original line Diff line number Diff line Loading @@ -24,9 +24,11 @@ import android.graphics.drawable.Drawable; import androidx.annotation.Nullable; import androidx.annotation.Nullable; import com.android.documentsui.CrossProfileException; import com.android.documentsui.CrossProfileNoPermissionException; import com.android.documentsui.CrossProfileNoPermissionException; import com.android.documentsui.CrossProfileQuietModeException; import com.android.documentsui.CrossProfileQuietModeException; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.Metrics; import com.android.documentsui.Model.Update; import com.android.documentsui.Model.Update; import com.android.documentsui.R; import com.android.documentsui.R; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.RootInfo; Loading Loading @@ -192,7 +194,9 @@ abstract class Message { void update(Update event) { void update(Update event) { reset(); reset(); if (event.hasCrossProfileException()) { if (event.hasCrossProfileException()) { if (event.getException() instanceof CrossProfileQuietModeException) { CrossProfileException e = (CrossProfileException) event.getException(); Metrics.logCrossProfileEmptyState(e); if (e instanceof CrossProfileQuietModeException) { updateToQuietModeErrorMessage( updateToQuietModeErrorMessage( ((CrossProfileQuietModeException) event.getException()).mUserId); ((CrossProfileQuietModeException) event.getException()).mUserId); } else if (event.getException() instanceof CrossProfileNoPermissionException) { } else if (event.getException() instanceof CrossProfileNoPermissionException) { Loading src/com/android/documentsui/picker/ActionHandler.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -286,6 +286,7 @@ class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionH } else { } else { userId.startActivityAsUser(mActivity, intent); userId.startActivityAsUser(mActivity, intent); } } Metrics.logLaunchOtherApp(!UserId.CURRENT_USER.equals(userId)); mActivity.finish(); mActivity.finish(); } catch (SecurityException | ActivityNotFoundException e) { } catch (SecurityException | ActivityNotFoundException e) { Log.e(TAG, "Caught error: " + e.getLocalizedMessage()); Log.e(TAG, "Caught error: " + e.getLocalizedMessage()); Loading src/com/android/documentsui/picker/PickActivity.java +11 −2 Original line number Original line Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.view.MenuItem; import android.view.View; import android.view.View; import androidx.annotation.CallSuper; import androidx.annotation.CallSuper; import androidx.core.util.Preconditions; import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager; Loading @@ -57,6 +58,7 @@ import com.android.documentsui.base.MimeTypes; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.Shared; import com.android.documentsui.base.Shared; import com.android.documentsui.base.State; import com.android.documentsui.base.State; import com.android.documentsui.base.UserId; import com.android.documentsui.dirlist.AppsRowManager; import com.android.documentsui.dirlist.AppsRowManager; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.services.FileOperationService; import com.android.documentsui.services.FileOperationService; Loading Loading @@ -387,6 +389,7 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons { mInjector.dialogs.showActionNotAllowed(); mInjector.dialogs.showActionNotAllowed(); return; return; } } mInjector.pickResult.setHasCrossProfileUri(!UserId.CURRENT_USER.equals(doc.userId)); mInjector.actions.finishPicking(doc.getDocumentUri()); mInjector.actions.finishPicking(doc.getDocumentUri()); mSearchManager.recordHistory(); mSearchManager.recordHistory(); } else if (mState.action == ACTION_CREATE) { } else if (mState.action == ACTION_CREATE) { Loading @@ -406,9 +409,15 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons { } } final int size = docs.size(); final int size = docs.size(); final Uri[] uris = new Uri[size]; final Uri[] uris = new Uri[size]; for (int i = 0; i < size; i++) { boolean hasCrossProfileUri = false; uris[i] = docs.get(i).getDocumentUri(); for (int i = 0; i < docs.size(); i++) { DocumentInfo doc = docs.get(i); uris[i] = doc.getDocumentUri(); if (!UserId.CURRENT_USER.equals(doc.userId)) { hasCrossProfileUri = true; } } } mInjector.pickResult.setHasCrossProfileUri(hasCrossProfileUri); mInjector.actions.finishPicking(uris); mInjector.actions.finishPicking(uris); mSearchManager.recordHistory(); mSearchManager.recordHistory(); } } Loading Loading
src/com/android/documentsui/DevicePolicyMetricConsts.java 0 → 100644 +54 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2020 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/devicepolicy/device_policy_enums.proto. */ public class DevicePolicyMetricConsts { public static final int ATOM_DEVICE_POLICY_EVENT = 103; @IntDef(flag = true, value = { ATOM_DEVICE_POLICY_EVENT, }) @Retention(RetentionPolicy.SOURCE) public @interface Atom { } // Codes representing DocsUI event id. public static final int EVENT_ID_DOCSUI_EMPTY_STATE_NO_PERMISSION = 173; public static final int EVENT_ID_DOCSUI_EMPTY_STATE_QUIET_MODE = 174; public static final int EVENT_ID_DOCSUI_LAUNCH_OTHER_APP = 175; public static final int EVENT_ID_DOCSUI_PICK_RESULT = 176; @IntDef(flag = true, value = { EVENT_ID_DOCSUI_EMPTY_STATE_NO_PERMISSION, EVENT_ID_DOCSUI_EMPTY_STATE_QUIET_MODE, EVENT_ID_DOCSUI_LAUNCH_OTHER_APP, EVENT_ID_DOCSUI_PICK_RESULT, }) @Retention(RetentionPolicy.SOURCE) public @interface EventId { } }
src/com/android/documentsui/Metrics.java +43 −0 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.provider.DocumentsContract; import android.provider.DocumentsContract.Path; import android.provider.DocumentsContract.Path; import android.provider.DocumentsProvider; import android.provider.DocumentsProvider; import android.util.Log; import android.util.Log; import android.util.StatsEvent; import android.util.StatsLog; import androidx.annotation.Nullable; import androidx.annotation.Nullable; Loading Loading @@ -89,6 +91,24 @@ public final class Metrics { DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_ROOT_VISITED, scope, sanitizeRoot(info)); DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_ROOT_VISITED, scope, sanitizeRoot(info)); } } public static void logLaunchOtherApp(boolean acrossProfile) { DevicePolicyEventLogger.write(DevicePolicyMetricConsts.EVENT_ID_DOCSUI_LAUNCH_OTHER_APP, acrossProfile); } public static void logCrossProfileEmptyState(CrossProfileException e) { int eventId; if (e instanceof CrossProfileQuietModeException) { eventId = DevicePolicyMetricConsts.EVENT_ID_DOCSUI_EMPTY_STATE_QUIET_MODE; } else if (e instanceof CrossProfileNoPermissionException) { eventId = DevicePolicyMetricConsts.EVENT_ID_DOCSUI_EMPTY_STATE_NO_PERMISSION; } else { Log.d(TAG, "logCrossProfileEmptyState: Unexpected exception " + e); return; } DevicePolicyEventLogger.write(eventId, /* booleanValue= */ true); } /** /** * Logs an app visited event in file pickers. Call this when the user visits * Logs an app visited event in file pickers. Call this when the user visits * on an app in the RootsFragment. * on an app in the RootsFragment. Loading Loading @@ -331,6 +351,9 @@ public final class Metrics { result.getRoot(), result.getRoot(), result.getMimeType(), result.getMimeType(), result.getRepeatedPickTimes()); result.getRepeatedPickTimes()); DevicePolicyEventLogger.write(DevicePolicyMetricConsts.EVENT_ID_DOCSUI_PICK_RESULT, result.hasCrossProfileUri()); } } private static void logStorageFileOperationFailure( private static void logStorageFileOperationFailure( Loading Loading @@ -612,4 +635,24 @@ public final class Metrics { } } return null; return null; } } /** * The implementation is copied from StatsLogInternal for the DEVICE_POLICY_EVENT. */ private static class DevicePolicyEventLogger { public static void write(@DevicePolicyMetricConsts.EventId int eventId, boolean booleanValue) { final StatsEvent.Builder builder = StatsEvent.newBuilder(); builder.setAtomId(DevicePolicyMetricConsts.ATOM_DEVICE_POLICY_EVENT); builder.writeInt(eventId); // eventId builder.writeString(null); // adminPackageName builder.writeInt(0); // intValue builder.writeBoolean(booleanValue); // booleanValue builder.writeLong(0); // timePeriodMs builder.writeByteArray(new byte[0]); // bytes builder.usePooledBuffer(); StatsLog.write(builder.build()); } } } }
src/com/android/documentsui/dirlist/Message.java +5 −1 Original line number Original line Diff line number Diff line Loading @@ -24,9 +24,11 @@ import android.graphics.drawable.Drawable; import androidx.annotation.Nullable; import androidx.annotation.Nullable; import com.android.documentsui.CrossProfileException; import com.android.documentsui.CrossProfileNoPermissionException; import com.android.documentsui.CrossProfileNoPermissionException; import com.android.documentsui.CrossProfileQuietModeException; import com.android.documentsui.CrossProfileQuietModeException; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.Metrics; import com.android.documentsui.Model.Update; import com.android.documentsui.Model.Update; import com.android.documentsui.R; import com.android.documentsui.R; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.RootInfo; Loading Loading @@ -192,7 +194,9 @@ abstract class Message { void update(Update event) { void update(Update event) { reset(); reset(); if (event.hasCrossProfileException()) { if (event.hasCrossProfileException()) { if (event.getException() instanceof CrossProfileQuietModeException) { CrossProfileException e = (CrossProfileException) event.getException(); Metrics.logCrossProfileEmptyState(e); if (e instanceof CrossProfileQuietModeException) { updateToQuietModeErrorMessage( updateToQuietModeErrorMessage( ((CrossProfileQuietModeException) event.getException()).mUserId); ((CrossProfileQuietModeException) event.getException()).mUserId); } else if (event.getException() instanceof CrossProfileNoPermissionException) { } else if (event.getException() instanceof CrossProfileNoPermissionException) { Loading
src/com/android/documentsui/picker/ActionHandler.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -286,6 +286,7 @@ class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionH } else { } else { userId.startActivityAsUser(mActivity, intent); userId.startActivityAsUser(mActivity, intent); } } Metrics.logLaunchOtherApp(!UserId.CURRENT_USER.equals(userId)); mActivity.finish(); mActivity.finish(); } catch (SecurityException | ActivityNotFoundException e) { } catch (SecurityException | ActivityNotFoundException e) { Log.e(TAG, "Caught error: " + e.getLocalizedMessage()); Log.e(TAG, "Caught error: " + e.getLocalizedMessage()); Loading
src/com/android/documentsui/picker/PickActivity.java +11 −2 Original line number Original line Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.view.MenuItem; import android.view.View; import android.view.View; import androidx.annotation.CallSuper; import androidx.annotation.CallSuper; import androidx.core.util.Preconditions; import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager; Loading @@ -57,6 +58,7 @@ import com.android.documentsui.base.MimeTypes; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.Shared; import com.android.documentsui.base.Shared; import com.android.documentsui.base.State; import com.android.documentsui.base.State; import com.android.documentsui.base.UserId; import com.android.documentsui.dirlist.AppsRowManager; import com.android.documentsui.dirlist.AppsRowManager; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.services.FileOperationService; import com.android.documentsui.services.FileOperationService; Loading Loading @@ -387,6 +389,7 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons { mInjector.dialogs.showActionNotAllowed(); mInjector.dialogs.showActionNotAllowed(); return; return; } } mInjector.pickResult.setHasCrossProfileUri(!UserId.CURRENT_USER.equals(doc.userId)); mInjector.actions.finishPicking(doc.getDocumentUri()); mInjector.actions.finishPicking(doc.getDocumentUri()); mSearchManager.recordHistory(); mSearchManager.recordHistory(); } else if (mState.action == ACTION_CREATE) { } else if (mState.action == ACTION_CREATE) { Loading @@ -406,9 +409,15 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons { } } final int size = docs.size(); final int size = docs.size(); final Uri[] uris = new Uri[size]; final Uri[] uris = new Uri[size]; for (int i = 0; i < size; i++) { boolean hasCrossProfileUri = false; uris[i] = docs.get(i).getDocumentUri(); for (int i = 0; i < docs.size(); i++) { DocumentInfo doc = docs.get(i); uris[i] = doc.getDocumentUri(); if (!UserId.CURRENT_USER.equals(doc.userId)) { hasCrossProfileUri = true; } } } mInjector.pickResult.setHasCrossProfileUri(hasCrossProfileUri); mInjector.actions.finishPicking(uris); mInjector.actions.finishPicking(uris); mSearchManager.recordHistory(); mSearchManager.recordHistory(); } } Loading