Protect usage data with OP_GET_USAGE_STATS.

APIs that return package usage data (such as the new ArtManager)
must ensure that callers hold both the PACKAGE_USAGE_STATS permission
and the OP_GET_USAGE_STATS app-op.

Bug: 77662908
Test: atest vendor/xts/gts-tests/hostsidetests/dexapis/host/
Change-Id: I7a85d959f1682d2bd5cf3684415e368fece88101
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 1084b42..0e44833 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2831,7 +2831,7 @@
         synchronized (mLock) {
             if (mArtManager == null) {
                 try {
-                    mArtManager = new ArtManager(mPM.getArtManager());
+                    mArtManager = new ArtManager(mContext, mPM.getArtManager());
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 }
diff --git a/core/java/android/content/pm/dex/ArtManager.java b/core/java/android/content/pm/dex/ArtManager.java
index 4129398..b0970f4 100644
--- a/core/java/android/content/pm/dex/ArtManager.java
+++ b/core/java/android/content/pm/dex/ArtManager.java
@@ -16,12 +16,16 @@
 
 package android.content.pm.dex;
 
+import static android.Manifest.permission.PACKAGE_USAGE_STATS;
+import static android.Manifest.permission.READ_RUNTIME_PROFILES;
+
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.content.Context;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
@@ -62,13 +66,14 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface ProfileType {}
 
-
-    private IArtManager mArtManager;
+    private final Context mContext;
+    private final IArtManager mArtManager;
 
     /**
      * @hide
      */
-    public ArtManager(@NonNull IArtManager manager) {
+    public ArtManager(@NonNull Context context, @NonNull IArtManager manager) {
+        mContext = context;
         mArtManager = manager;
     }
 
@@ -99,7 +104,7 @@
      * @param callback the callback which should be used for the result
      * @param executor the executor which should be used to post the result
      */
-    @RequiresPermission(android.Manifest.permission.READ_RUNTIME_PROFILES)
+    @RequiresPermission(allOf = { READ_RUNTIME_PROFILES, PACKAGE_USAGE_STATS })
     public void snapshotRuntimeProfile(@ProfileType int profileType, @Nullable String packageName,
             @Nullable String codePath, @NonNull @CallbackExecutor Executor executor,
             @NonNull SnapshotRuntimeProfileCallback callback) {
@@ -108,9 +113,10 @@
         SnapshotRuntimeProfileCallbackDelegate delegate =
                 new SnapshotRuntimeProfileCallbackDelegate(callback, executor);
         try {
-            mArtManager.snapshotRuntimeProfile(profileType, packageName, codePath, delegate);
+            mArtManager.snapshotRuntimeProfile(profileType, packageName, codePath, delegate,
+                    mContext.getOpPackageName());
         } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
+            throw e.rethrowAsRuntimeException();
         }
     }
 
@@ -122,14 +128,13 @@
      * @param profileType can be either {@link ArtManager#PROFILE_APPS}
      *                    or {@link ArtManager#PROFILE_BOOT_IMAGE}
      */
-    @RequiresPermission(android.Manifest.permission.READ_RUNTIME_PROFILES)
+    @RequiresPermission(allOf = { READ_RUNTIME_PROFILES, PACKAGE_USAGE_STATS })
     public boolean isRuntimeProfilingEnabled(@ProfileType int profileType) {
         try {
-            return mArtManager.isRuntimeProfilingEnabled(profileType);
+            return mArtManager.isRuntimeProfilingEnabled(profileType, mContext.getOpPackageName());
         } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
+            throw e.rethrowAsRuntimeException();
         }
-        return false;
     }
 
     /**
diff --git a/core/java/android/content/pm/dex/IArtManager.aidl b/core/java/android/content/pm/dex/IArtManager.aidl
index 6abfdba..7f0de7e 100644
--- a/core/java/android/content/pm/dex/IArtManager.aidl
+++ b/core/java/android/content/pm/dex/IArtManager.aidl
@@ -44,8 +44,8 @@
      * {@link ArtManager#isRuntimeProfilingEnabled(int)} does not return true for the given
      * {@code profileType}.
      */
-    oneway void snapshotRuntimeProfile(int profileType, in String packageName,
-        in String codePath, in ISnapshotRuntimeProfileCallback callback);
+    void snapshotRuntimeProfile(int profileType, in String packageName,
+        in String codePath, in ISnapshotRuntimeProfileCallback callback, String callingPackage);
 
      /**
        * Returns true if runtime profiles are enabled for the given type, false otherwise.
@@ -54,5 +54,5 @@
        *
        * @param profileType
        */
-    boolean isRuntimeProfilingEnabled(int profileType);
+    boolean isRuntimeProfilingEnabled(int profileType, String callingPackage);
 }