From aa49cb86e6d5f23d82c97db32c848bc4ea2b81bc Mon Sep 17 00:00:00 2001 From: Chad Brubaker Date: Fri, 24 Mar 2017 15:53:09 -0700 Subject: [PATCH] Add ACTION_EPHEMERAL_RESOLVER_SETTINGS This Intent will be used in Settings to show the settings UI for the Ephemeral resolver. Settings can get the correct component to send the Intent to by calling PackageManager.getInstantAppResolverSettingsComponent Bug: 35918998 Test: Boots Change-Id: I0edcf85704f2c19e0ee27f91b6ef057d52e32778 --- api/system-current.txt | 2 + .../app/ApplicationPackageManager.java | 9 +++++ core/java/android/content/Intent.java | 13 +++++++ .../android/content/pm/IPackageManager.aidl | 2 + .../android/content/pm/PackageManager.java | 10 +++++ .../server/pm/PackageManagerService.java | 39 +++++++++++++++++++ .../android/test/mock/MockPackageManager.java | 8 ++++ .../bridge/android/BridgePackageManager.java | 5 +++ 8 files changed, 88 insertions(+) diff --git a/api/system-current.txt b/api/system-current.txt index 48b878ec699f9..d2329a92bf5f4 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -11171,6 +11171,7 @@ package android.content.pm { method public abstract byte[] getInstantAppCookie(); method public abstract int getInstantAppCookieMaxSize(); method public abstract android.graphics.drawable.Drawable getInstantAppIcon(java.lang.String); + method public abstract android.content.ComponentName getInstantAppResolverSettingsComponent(); method public abstract java.util.List getInstantApps(); method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract java.util.List getIntentFilterVerifications(java.lang.String); @@ -44203,6 +44204,7 @@ package android.test.mock { method public byte[] getInstantAppCookie(); method public int getInstantAppCookieMaxSize(); method public android.graphics.drawable.Drawable getInstantAppIcon(java.lang.String); + method public android.content.ComponentName getInstantAppResolverSettingsComponent(); method public java.util.List getInstantApps(); method public android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; method public java.util.List getIntentFilterVerifications(java.lang.String); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 286f8570f55cc..461f9cc351256 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2630,4 +2630,13 @@ public class ApplicationPackageManager extends PackageManager { throw e.rethrowAsRuntimeException(); } } + + @Override + public ComponentName getInstantAppResolverSettingsComponent() { + try { + return mPM.getInstantAppResolverSettingsComponent(); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index fb86791a509c0..7890a96079324 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1531,6 +1531,19 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_RESOLVE_EPHEMERAL_PACKAGE = "android.intent.action.RESOLVE_EPHEMERAL_PACKAGE"; + /** + * Activity Action: Launch ephemeral settings. + * + *

+ * This is a protected intent that can only be sent by the system. + *

+ * + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_EPHEMERAL_RESOLVER_SETTINGS + = "android.intent.action.EPHEMERAL_RESOLVER_SETTINGS"; + /** * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} to install a * package. Specifies the installer package name; this package will receive the diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 59b022ded9bfb..147df763fce28 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -630,4 +630,6 @@ interface IPackageManager { boolean canRequestPackageInstalls(String packageName, int userId); void deletePreloadsFileCache(); + + ComponentName getInstantAppResolverSettingsComponent(); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 71db5d311bd6b..2edcb0f8842be 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -6233,4 +6233,14 @@ public abstract class PackageManager { * @see {@link android.provider.Settings#ACTION_MANAGE_EXTERNAL_SOURCES} */ public abstract boolean canRequestPackageInstalls(); + + /** + * Return the {@link ComponentName} of the activity providing Settings for the Instant App + * resolver. + * + * @see {@link android.content.intent#ACTION_EPHEMERAL_RESOLVER_SETTINGS} + * @hide + */ + @SystemApi + public abstract ComponentName getInstantAppResolverSettingsComponent(); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 8cc9375025926..600ceb8814c92 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -842,6 +842,8 @@ public class PackageManagerService extends IPackageManager.Stub { /** Component used to install ephemeral applications */ ComponentName mInstantAppInstallerComponent; + /** Component used to show resolver settings for Instant Apps */ + ComponentName mInstantAppResolverSettingsComponent; ActivityInfo mInstantAppInstallerActivity; final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo(); @@ -2890,6 +2892,7 @@ public class PackageManagerService extends IPackageManager.Stub { mInstantAppResolverConnection = null; } updateInstantAppInstallerLocked(); + mInstantAppResolverSettingsComponent = getEphemeralResolverSettingsLPr(); // Read and update the usage of dex files. // Do this at the end of PM init so that all the packages have their @@ -3196,6 +3199,37 @@ public class PackageManagerService extends IPackageManager.Stub { } } + private @Nullable ComponentName getEphemeralResolverSettingsLPr() { + final Intent intent = new Intent(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS); + intent.addCategory(Intent.CATEGORY_DEFAULT); + final int resolveFlags = + MATCH_DIRECT_BOOT_AWARE + | MATCH_DIRECT_BOOT_UNAWARE + | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); + final List matches = queryIntentActivitiesInternal(intent, null, + resolveFlags, UserHandle.USER_SYSTEM); + Iterator iter = matches.iterator(); + while (iter.hasNext()) { + final ResolveInfo rInfo = iter.next(); + final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); + if (ps != null) { + final PermissionsState permissionsState = ps.getPermissionsState(); + if (permissionsState.hasPermission(Manifest.permission.ACCESS_INSTANT_APPS, 0)) { + continue; + } + } + iter.remove(); + } + if (matches.size() == 0) { + return null; + } else if (matches.size() == 1) { + return matches.get(0).getComponentInfo().getComponentName(); + } else { + throw new RuntimeException( + "There must be at most one ephemeral resolver settings; found " + matches); + } + } + private void primeDomainVerificationsLPw(int userId) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Priming domain verifications in user " + userId); @@ -23313,4 +23347,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED; } + + @Override + public ComponentName getInstantAppResolverSettingsComponent() { + return mInstantAppResolverSettingsComponent; + } } diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index 506f406c333f4..960a2d9fd726a 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -1118,4 +1118,12 @@ public class MockPackageManager extends PackageManager { public int getInstallReason(String packageName, UserHandle user) { throw new UnsupportedOperationException(); } + + /** + * @hide + */ + @Override + public ComponentName getInstantAppResolverSettingsComponent() { + throw new UnsupportedOperationException(); + } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java index 906ebb1fe39eb..53c3f90e0137a 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java @@ -916,4 +916,9 @@ public class BridgePackageManager extends PackageManager { public boolean canRequestPackageInstalls() { return false; } + + @Override + public ComponentName getInstantAppResolverSettingsComponent() { + return null; + } }