Fix ephemeral post-install launching
Provide the ephemeral installer with some additional pieces of information:
1) instead of de-referencing the URL a second time, give the installer the
exact package name
2) instead of relying on ephemeral apps to define verified links, give the
installer a pending intent to launch when the ephemeral is installed
3) give the installer a pending intent to launch if the installer fails,
for whatever reason, to install the ephemeral app
Bug: 25119046
Change-Id: I45f50481caee09d5d09451e4b2492e64b0faae82
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 90a5d3f..d2fc602 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3674,9 +3674,9 @@
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(new ComponentName(
ri.activityInfo.packageName, ri.activityInfo.name));
- mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
- null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
- null, null, null);
+ mStackSupervisor.startActivityLocked(null, intent, null /*ephemeralIntent*/,
+ null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
+ null, 0, 0, 0, null, false, false, null, null, null);
}
}
}
@@ -4285,9 +4285,10 @@
final long origId = Binder.clearCallingIdentity();
int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
- r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
- resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
- -1, r.launchedFromUid, 0, options, false, false, null, null, null);
+ null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
+ null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
+ r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
+ false, false, null, null, null);
Binder.restoreCallingIdentity(origId);
r.finishing = wasFinishing;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ffa6a4d..3f62cbc 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3349,9 +3349,10 @@
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
destIntent.getComponent(), 0, srec.userId);
int res = mStackSupervisor.startActivityLocked(srec.app.thread, destIntent,
- null, aInfo, null, null, parent.appToken, null,
- 0, -1, parent.launchedFromUid, parent.launchedFromPackage,
- -1, parent.launchedFromUid, 0, null, false, true, null, null, null);
+ null /*ephemeralIntent*/, null, aInfo, null /*rInfo*/, null, null,
+ parent.appToken, null, 0, -1, parent.launchedFromUid,
+ parent.launchedFromPackage, -1, parent.launchedFromUid, 0, null,
+ false, true, null, null, null);
foundParentInTask = res == ActivityManager.START_SUCCESS;
} catch (RemoteException e) {
foundParentInTask = false;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index e1bc580..f615613 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -920,21 +920,9 @@
}
}
- ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
- ProfilerInfo profilerInfo, int userId) {
- // Collect information about the target of the Intent.
- ActivityInfo aInfo;
- try {
- ResolveInfo rInfo =
- AppGlobals.getPackageManager().resolveIntent(
- intent, resolvedType,
- PackageManager.MATCH_DEFAULT_ONLY
- | ActivityManagerService.STOCK_PM_FLAGS, userId);
- aInfo = rInfo != null ? rInfo.activityInfo : null;
- } catch (RemoteException e) {
- aInfo = null;
- }
-
+ ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags,
+ ProfilerInfo profilerInfo) {
+ final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
// Store the found target back into the intent, because now that
// we have it we never want to do this again. For example, if the
@@ -961,15 +949,31 @@
return aInfo;
}
+ ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
+ try {
+ return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
+ PackageManager.MATCH_DEFAULT_ONLY
+ | ActivityManagerService.STOCK_PM_FLAGS, userId);
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
+ ProfilerInfo profilerInfo, int userId) {
+ final ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId);
+ return resolveActivity(intent, rInfo, startFlags, profilerInfo);
+ }
+
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
- startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
- null /* voiceSession */, null /* voiceInteractor */, null /* resultTo */,
- null /* resultWho */, 0 /* requestCode */, 0 /* callingPid */, 0 /* callingUid */,
- null /* callingPackage */, 0 /* realCallingPid */, 0 /* realCallingUid */,
- 0 /* startFlags */, null /* options */, false /* ignoreTargetSecurity */,
- false /* componentSpecified */,
- null /* outActivity */, null /* container */, null /* inTask */);
+ startActivityLocked(null /*caller*/, intent, null /*ephemeralIntent*/,
+ null /*resolvedType*/, aInfo, null /*rInfo*/, null /*voiceSession*/,
+ null /*voiceInteractor*/, null /*resultTo*/, null /*resultWho*/,
+ 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/, null /*callingPackage*/,
+ 0 /*realCallingPid*/, 0 /*realCallingUid*/, 0 /*startFlags*/, null /*options*/,
+ false /*ignoreTargetSecurity*/, false /*componentSpecified*/, null /*outActivity*/,
+ null /*container*/, null /*inTask*/);
if (inResumeTopActivity) {
// If we are in resume section already, home activity will be initialized, but not
// resumed (to avoid recursive resume) and will stay that way until something pokes it
@@ -991,12 +995,14 @@
}
boolean componentSpecified = intent.getComponent() != null;
+ // Save a copy in case ephemeral needs it
+ final Intent ephemeralIntent = new Intent(intent);
// Don't modify the client's object!
intent = new Intent(intent);
+ ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId);
// Collect information about the target of the Intent.
- ActivityInfo aInfo =
- resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
+ ActivityInfo aInfo = resolveActivity(intent, rInfo, startFlags, profilerInfo);
ActivityOptions options = ActivityOptions.fromBundle(bOptions);
ActivityContainer container = (ActivityContainer)iContainer;
@@ -1084,26 +1090,20 @@
callingUid = Binder.getCallingUid();
callingPid = Binder.getCallingPid();
componentSpecified = true;
- try {
- ResolveInfo rInfo =
- AppGlobals.getPackageManager().resolveIntent(
- intent, null,
- PackageManager.MATCH_DEFAULT_ONLY
- | ActivityManagerService.STOCK_PM_FLAGS, userId);
- aInfo = rInfo != null ? rInfo.activityInfo : null;
+ rInfo = resolveIntent(intent, null /*resolvedType*/, userId);
+ aInfo = rInfo != null ? rInfo.activityInfo : null;
+ if (aInfo != null) {
aInfo = mService.getActivityInfoForUser(aInfo, userId);
- } catch (RemoteException e) {
- aInfo = null;
}
}
}
}
- int res = startActivityLocked(caller, intent, resolvedType, aInfo,
- voiceSession, voiceInteractor, resultTo, resultWho,
- requestCode, callingPid, callingUid, callingPackage,
- realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
- componentSpecified, null, container, inTask);
+ int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
+ aInfo, rInfo, voiceSession, voiceInteractor,
+ resultTo, resultWho, requestCode, callingPid,
+ callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
+ options, ignoreTargetSecurity, componentSpecified, null, container, inTask);
Binder.restoreCallingIdentity(origId);
@@ -1211,10 +1211,10 @@
ActivityOptions options = ActivityOptions.fromBundle(
i == intents.length - 1 ? bOptions : null);
- int res = startActivityLocked(caller, intent, resolvedTypes[i],
- aInfo, null, null, resultTo, null, -1, callingPid, callingUid,
- callingPackage, callingPid, callingUid,
- 0, options, false, componentSpecified, outActivity, null, null);
+ int res = startActivityLocked(caller, intent, null /*ephemeralIntent*/,
+ resolvedTypes[i], aInfo, null /*rInfo*/, null, null, resultTo, null, -1,
+ callingPid, callingUid, callingPackage, callingPid, callingUid, 0,
+ options, false, componentSpecified, outActivity, null, null);
if (res < 0) {
return res;
}
@@ -1448,14 +1448,13 @@
"activity", r.intent.getComponent(), false, false, true);
}
- final int startActivityLocked(IApplicationThread caller,
- Intent intent, String resolvedType, ActivityInfo aInfo,
+ final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
+ String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- IBinder resultTo, String resultWho, int requestCode,
- int callingPid, int callingUid, String callingPackage,
- int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options,
- boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
- ActivityContainer container, TaskRecord inTask) {
+ IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
+ String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
+ ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
+ ActivityRecord[] outActivity, ActivityContainer container, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
ProcessRecord callerApp = null;
@@ -1625,23 +1624,23 @@
new String[]{ resolvedType },
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
| PendingIntent.FLAG_IMMUTABLE, null);
- int flags = intent.getFlags();
- Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, user.id);
+ final int flags = intent.getFlags();
+ final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, user.id);
if (newIntent != null) {
intent = newIntent;
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ intent.setFlags(flags
+ | Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
intent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
- intent.setFlags(flags);
resolvedType = null;
callingUid = realCallingUid;
callingPid = realCallingPid;
UserInfo parent = UserManager.get(mService.mContext).getProfileParent(userId);
- aInfo = resolveActivity(intent, null, PackageManager.MATCH_DEFAULT_ONLY
- | ActivityManagerService.STOCK_PM_FLAGS, null, parent.id);
+ rInfo = resolveIntent(intent, resolvedType, parent.id);
+ aInfo = resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
}
}
@@ -1668,22 +1667,23 @@
new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
| PendingIntent.FLAG_ONE_SHOT, null);
+ final int flags = intent.getFlags();
Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
- newIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ newIntent.setFlags(flags
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
if (resultRecord != null) {
newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
}
- newIntent.setFlags(intent.getFlags());
intent = newIntent;
resolvedType = null;
callingUid = realCallingUid;
callingPid = realCallingPid;
- aInfo = resolveActivity(intent, null, PackageManager.MATCH_DEFAULT_ONLY
- | ActivityManagerService.STOCK_PM_FLAGS, null, userId);
+ rInfo = resolveIntent(intent, resolvedType, userId);
+ aInfo = resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
if (DEBUG_PERMISSIONS_REVIEW) {
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
@@ -1696,6 +1696,47 @@
}
}
+ // If we have an ephemeral app, abort the process of launching the resolved intent.
+ // Instead, launch the ephemeral installer. Once the installer is finished, it
+ // starts either the intent we resolved here [on install error] or the ephemeral
+ // app [on install success].
+ if (rInfo != null && rInfo.ephemeralResolveInfo != null) {
+ // Create a pending intent to start the intent resolved here.
+ final IIntentSender failureTarget = mService.getIntentSenderLocked(
+ ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
+ Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent },
+ new String[]{ resolvedType },
+ PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
+ | PendingIntent.FLAG_IMMUTABLE, null);
+
+ // Create a pending intent to start the ephemeral application; force it to be
+ // directed to the ephemeral package.
+ ephemeralIntent.setPackage(rInfo.ephemeralResolveInfo.getPackageName());
+ final IIntentSender ephemeralTarget = mService.getIntentSenderLocked(
+ ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
+ Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ ephemeralIntent },
+ new String[]{ resolvedType },
+ PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
+ | PendingIntent.FLAG_IMMUTABLE, null);
+
+ int flags = intent.getFlags();
+ intent = new Intent();
+ intent.setFlags(flags
+ | Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME,
+ rInfo.ephemeralResolveInfo.getPackageName());
+ intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, new IntentSender(failureTarget));
+ intent.putExtra(Intent.EXTRA_EPHEMERAL_SUCCESS, new IntentSender(ephemeralTarget));
+
+ resolvedType = null;
+ callingUid = realCallingUid;
+ callingPid = realCallingPid;
+
+ rInfo = rInfo.ephemeralInstaller;
+ aInfo = resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
+ }
+
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
requestCode, componentSpecified, voiceSession != null, this, container, options);
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 628ad0e..fe6fb1f 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.EphemeralResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
@@ -30,7 +31,6 @@
import android.util.TimedRemoteCaller;
import com.android.internal.app.EphemeralResolverService;
-import com.android.internal.app.EphemeralResolveInfo;
import com.android.internal.app.IEphemeralResolver;
import java.io.FileDescriptor;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e0f85c5..cad3b3f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -105,6 +105,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.AppsQueryHelper;
+import android.content.pm.EphemeralResolveInfo;
import android.content.pm.EphemeralApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.IOnPermissionsChangeListener;
@@ -144,6 +145,7 @@
import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VerifierInfo;
+import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.hardware.display.DisplayManager;
@@ -210,7 +212,7 @@
import libcore.util.EmptyArray;
import com.android.internal.R;
-import com.android.internal.app.EphemeralResolveInfo;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
@@ -4418,7 +4420,21 @@
flags = augmentFlagsForUser(flags, userId);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
- return chooseBestActivity(intent, resolvedType, flags, query, userId);
+ final ResolveInfo bestChoice =
+ chooseBestActivity(intent, resolvedType, flags, query, userId);
+
+ if (isEphemeralAllowed(intent, query, userId)) {
+ final EphemeralResolveInfo ai =
+ getEphemeralResolveInfo(intent, resolvedType, userId);
+ if (ai != null) {
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "Returning an EphemeralResolveInfo");
+ }
+ bestChoice.ephemeralInstaller = mEphemeralInstallerInfo;
+ bestChoice.ephemeralResolveInfo = ai;
+ }
+ }
+ return bestChoice;
}
@Override
@@ -4453,13 +4469,61 @@
false, false, false, userId);
}
- private boolean isEphemeralAvailable(Intent intent, String resolvedType, int userId) {
+
+ private boolean isEphemeralAllowed(
+ Intent intent, List<ResolveInfo> resolvedActivites, int userId) {
+ // Short circuit and return early if possible.
+ final int callingUser = UserHandle.getCallingUserId();
+ if (callingUser != UserHandle.USER_SYSTEM) {
+ return false;
+ }
+ if (mEphemeralResolverConnection == null) {
+ return false;
+ }
+ if (intent.getComponent() != null) {
+ return false;
+ }
+ if (intent.getPackage() != null) {
+ return false;
+ }
+ final boolean isWebUri = hasWebURI(intent);
+ if (!isWebUri) {
+ return false;
+ }
+ // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
+ synchronized (mPackages) {
+ final int count = resolvedActivites.size();
+ for (int n = 0; n < count; n++) {
+ ResolveInfo info = resolvedActivites.get(n);
+ String packageName = info.activityInfo.packageName;
+ PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps != null) {
+ // Try to get the status from User settings first
+ long packedStatus = getDomainVerificationStatusLPr(ps, userId);
+ int status = (int) (packedStatus >> 32);
+ if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
+ || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "DENY ephemeral apps;"
+ + " pkg: " + packageName + ", status: " + status);
+ }
+ return false;
+ }
+ }
+ }
+ }
+ // We've exhausted all ways to deny ephemeral application; let the system look for them.
+ return true;
+ }
+
+ private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType,
+ int userId) {
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
// If we can't create a digest, ignore ephemeral apps.
- return false;
+ return null;
}
final byte[] hostBytes = intent.getData().getHost().getBytes();
@@ -4473,7 +4537,7 @@
mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix);
if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
// No hash prefix match; there are no ephemeral apps for this domain.
- return false;
+ return null;
}
for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) {
EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i);
@@ -4488,62 +4552,22 @@
// We have a domain match; resolve the filters to see if anything matches.
final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
for (int j = filters.size() - 1; j >= 0; --j) {
- ephemeralResolver.addFilter(filters.get(j));
+ final EphemeralResolveIntentInfo intentInfo =
+ new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
+ ephemeralResolver.addFilter(intentInfo);
}
- List<ResolveInfo> ephemeralResolveList = ephemeralResolver.queryIntent(
+ List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
intent, resolvedType, false /*defaultOnly*/, userId);
- return !ephemeralResolveList.isEmpty();
+ if (!matchedResolveInfoList.isEmpty()) {
+ return matchedResolveInfoList.get(0);
+ }
}
// Hash or filter mis-match; no ephemeral apps for this domain.
- return false;
+ return null;
}
private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
int flags, List<ResolveInfo> query, int userId) {
- final boolean isWebUri = hasWebURI(intent);
- // Check whether or not an ephemeral app exists to handle the URI.
- if (isWebUri && mEphemeralResolverConnection != null) {
- // Deny ephemeral apps if the user choose _ALWAYS or _ALWAYS_ASK for intent resolution.
- boolean hasAlwaysHandler = false;
- synchronized (mPackages) {
- final int count = query.size();
- for (int n=0; n<count; n++) {
- ResolveInfo info = query.get(n);
- String packageName = info.activityInfo.packageName;
- PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null) {
- // Try to get the status from User settings first
- long packedStatus = getDomainVerificationStatusLPr(ps, userId);
- int status = (int) (packedStatus >> 32);
- if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
- || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
- hasAlwaysHandler = true;
- break;
- }
- }
- }
- }
-
- // Only consider installing an ephemeral app if there isn't already a verified handler.
- // We've determined that there's an ephemeral app available for the URI, ignore any
- // ResolveInfo's and just return the ephemeral installer
- if (!hasAlwaysHandler && isEphemeralAvailable(intent, resolvedType, userId)) {
- if (DEBUG_EPHEMERAL) {
- Slog.v(TAG, "Resolving to the ephemeral installer");
- }
- // ditch the result and return a ResolveInfo to launch the ephemeral installer
- ResolveInfo ri = new ResolveInfo(mEphemeralInstallerInfo);
- ri.activityInfo = new ActivityInfo(ri.activityInfo);
- // make a deep copy of the applicationInfo
- ri.activityInfo.applicationInfo = new ApplicationInfo(
- ri.activityInfo.applicationInfo);
- if (userId != 0) {
- ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
- UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
- }
- return ri;
- }
- }
if (query != null) {
final int N = query.size();
if (N == 1) {
@@ -4559,7 +4583,7 @@
+ r1.activityInfo.name + "=" + r1.priority);
}
// If the first activity has a higher priority, or a different
- // default, then it is always desireable to pick it.
+ // default, then it is always desirable to pick it.
if (r0.priority != r1.priority
|| r0.preferredOrder != r1.preferredOrder
|| r0.isDefault != r1.isDefault) {
@@ -9737,23 +9761,24 @@
}
private static final class EphemeralIntentResolver
- extends IntentResolver<IntentFilter, ResolveInfo> {
+ extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
@Override
- protected IntentFilter[] newArray(int size) {
- return new IntentFilter[size];
+ protected EphemeralResolveIntentInfo[] newArray(int size) {
+ return new EphemeralResolveIntentInfo[size];
}
@Override
- protected boolean isPackageForFilter(String packageName, IntentFilter info) {
+ protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
return true;
}
@Override
- protected ResolveInfo newResult(IntentFilter info, int match, int userId) {
- if (!sUserManager.exists(userId)) return null;
- final ResolveInfo res = new ResolveInfo();
- res.filter = info;
- return res;
+ protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
+ int userId) {
+ if (!sUserManager.exists(userId)) {
+ return null;
+ }
+ return info.getEphemeralResolveInfo();
}
}