Merge "Grant default permissions to active LUI." into pi-dev am: 7c6ad52c65
am: 5558422125

Change-Id: I5ba9bbf3b56b3eaf3f7e1dfd6383e7a7271ee403
diff --git a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
index 8297c18..7c7b75d 100644
--- a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
+++ b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
@@ -15,12 +15,18 @@
  */
 package com.android.phone.euicc;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.service.euicc.EuiccService;
 import android.telephony.euicc.EuiccManager;
 import android.util.Log;
@@ -28,10 +34,22 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.euicc.EuiccConnector;
 
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 /** Trampoline activity to forward eUICC intents from apps to the active UI implementation. */
 public class EuiccUiDispatcherActivity extends Activity {
     private static final String TAG = "EuiccUiDispatcher";
 
+    /** Flags to use when querying PackageManager for Euicc component implementations. */
+    private static final int EUICC_QUERY_FLAGS =
+            PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DEBUG_TRIAGED_MISSING
+                    | PackageManager.GET_RESOLVED_FILTER;
+
+    private final IPackageManager mPackageManager = IPackageManager.Stub
+            .asInterface(ServiceManager.getService("package"));
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -66,12 +84,16 @@
             return null;
         }
 
+        revokePermissionFromLuiApps(euiccUiIntent);
+
         ActivityInfo activityInfo = findBestActivity(euiccUiIntent);
         if (activityInfo == null) {
             Log.w(TAG, "Could not resolve activity for intent: " + euiccUiIntent);
             return null;
         }
 
+        grantDefaultPermissionsToActiveLuiApp(activityInfo);
+
         euiccUiIntent.setComponent(activityInfo.getComponentName());
         return euiccUiIntent;
     }
@@ -110,4 +132,40 @@
     ActivityInfo findBestActivity(Intent euiccUiIntent) {
         return EuiccConnector.findBestActivity(getPackageManager(), euiccUiIntent);
     }
+
+    /** Grants default permissions to the active LUI app. */
+    @VisibleForTesting
+    protected void grantDefaultPermissionsToActiveLuiApp(ActivityInfo activityInfo) {
+        try {
+            mPackageManager.grantDefaultPermissionsToActiveLuiApp(
+                    activityInfo.packageName, getUserId());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to grant permissions to active LUI app.", e);
+        }
+    }
+
+    /** Cleans up all the packages that shouldn't have permission. */
+    @VisibleForTesting
+    protected void revokePermissionFromLuiApps(Intent intent) {
+        try {
+            Set<String> luiApps = getAllLuiAppPackageNames(intent);
+            String[] luiAppsArray = luiApps.toArray(new String[luiApps.size()]);
+            mPackageManager.revokeDefaultPermissionsFromLuiApps(luiAppsArray, getUserId());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to revoke LUI app permissions.");
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    @NonNull
+    private Set<String> getAllLuiAppPackageNames(Intent intent) {
+        List<ResolveInfo> luiPackages =
+                getPackageManager().queryIntentServices(intent, EUICC_QUERY_FLAGS);
+        HashSet<String> packageNames = new HashSet<>();
+        for (ResolveInfo info : luiPackages) {
+            if (info.serviceInfo == null) continue;
+            packageNames.add(info.serviceInfo.packageName);
+        }
+        return packageNames;
+    }
 }
diff --git a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
index 5ecebc3..57df097 100644
--- a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
+++ b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
@@ -118,5 +118,11 @@
         ActivityInfo findBestActivity(Intent euiccUiIntent) {
             return mActivityInfo;
         }
+
+        @Override
+        protected void grantDefaultPermissionsToActiveLuiApp(ActivityInfo activityInfo) {}
+
+        @Override
+        protected void revokePermissionFromLuiApps(Intent intent) {}
     }
 }