Merge changes from topic "sharedisolated"
* changes: Add allowedSharedIsolatedProcess attribute. Support shared isolated processes.
This commit is contained in:
committed by
Android (Google) Code Review
commit
4f869ffb43
@@ -363,6 +363,7 @@ package android {
|
||||
field public static final int allowGameFpsOverride = 16844378; // 0x101065a
|
||||
field public static final int allowNativeHeapPointerTagging = 16844306; // 0x1010612
|
||||
field public static final int allowParallelSyncs = 16843570; // 0x1010332
|
||||
field public static final int allowSharedIsolatedProcess;
|
||||
field public static final int allowSingleTap = 16843353; // 0x1010259
|
||||
field public static final int allowTaskReparenting = 16843268; // 0x1010204
|
||||
field public static final int allowUndo = 16843999; // 0x10104df
|
||||
@@ -9957,6 +9958,7 @@ package android.content {
|
||||
field public static final int BIND_INCLUDE_CAPABILITIES = 4096; // 0x1000
|
||||
field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
|
||||
field public static final int BIND_NOT_PERCEPTIBLE = 256; // 0x100
|
||||
field public static final int BIND_SHARED_ISOLATED_PROCESS = 8192; // 0x2000
|
||||
field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
|
||||
field public static final String BIOMETRIC_SERVICE = "biometric";
|
||||
field public static final String BLOB_STORE_SERVICE = "blob_store";
|
||||
@@ -12533,6 +12535,7 @@ package android.content.pm {
|
||||
method public void dump(android.util.Printer, String);
|
||||
method public int getForegroundServiceType();
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ServiceInfo> CREATOR;
|
||||
field public static final int FLAG_ALLOW_SHARED_ISOLATED_PROCESS = 16; // 0x10
|
||||
field public static final int FLAG_EXTERNAL_SERVICE = 4; // 0x4
|
||||
field public static final int FLAG_ISOLATED_PROCESS = 2; // 0x2
|
||||
field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000
|
||||
|
||||
@@ -277,7 +277,8 @@ public abstract class Context {
|
||||
BIND_IMPORTANT,
|
||||
BIND_ADJUST_WITH_ACTIVITY,
|
||||
BIND_NOT_PERCEPTIBLE,
|
||||
BIND_INCLUDE_CAPABILITIES
|
||||
BIND_INCLUDE_CAPABILITIES,
|
||||
BIND_SHARED_ISOLATED_PROCESS
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface BindServiceFlags {}
|
||||
@@ -394,6 +395,22 @@ public abstract class Context {
|
||||
*/
|
||||
public static final int BIND_INCLUDE_CAPABILITIES = 0x000001000;
|
||||
|
||||
/**
|
||||
* Flag for {@link #bindIsolatedService}: Bind the service into a shared isolated process.
|
||||
* Specifying this flag allows multiple isolated services to be running in a single shared
|
||||
* isolated process.
|
||||
*
|
||||
* The shared isolated process instance is identified by the <var>instanceName</var>
|
||||
* parameter in {@link #bindIsolatedService(Intent, int, String, Executor, ServiceConnection)}.
|
||||
*
|
||||
* Subsequent calls to {@link #bindIsolatedService} with the same <var>instanceName</var>
|
||||
* will cause the isolated service to be co-located in the same shared isolated process.
|
||||
*
|
||||
* Note that the shared isolated process is scoped to the calling app; once created, only
|
||||
* the calling app can bind additional isolated services into the shared process.
|
||||
*/
|
||||
public static final int BIND_SHARED_ISOLATED_PROCESS = 0x00002000;
|
||||
|
||||
/*********** Public flags above this line ***********/
|
||||
/*********** Hidden flags below this line ***********/
|
||||
|
||||
|
||||
@@ -78,6 +78,20 @@ public class ServiceInfo extends ComponentInfo
|
||||
*/
|
||||
public static final int FLAG_USE_APP_ZYGOTE = 0x0008;
|
||||
|
||||
/**
|
||||
* Bit in {@link #flags}: If set, and this is an {@link android.R.attr#isolatedProcess}
|
||||
* service, the service is allowed to be bound in a shared isolated process with other
|
||||
* isolated services. Note that these other isolated services can also belong to other
|
||||
* apps from different vendors.
|
||||
*
|
||||
* Shared isolated processes are created when using the
|
||||
* {@link android.content.Context#BIND_SHARED_ISOLATED_PROCESS) during service binding.
|
||||
*
|
||||
* Note that when this flag is used, the {@link android.R.attr#process} attribute is
|
||||
* ignored when the process is bound into a shared isolated process by a client.
|
||||
*/
|
||||
public static final int FLAG_ALLOW_SHARED_ISOLATED_PROCESS = 0x0010;
|
||||
|
||||
/**
|
||||
* Bit in {@link #flags} indicating if the service is visible to ephemeral applications.
|
||||
* @hide
|
||||
|
||||
@@ -2963,6 +2963,18 @@
|
||||
Context.createAttributionContext() using the first attribution tag
|
||||
contained here. -->
|
||||
<attr name="attributionTags" />
|
||||
<!-- If true, and this is an {@link android.R.attr#isolatedProcess} service, the service
|
||||
is allowed to be bound in a shared isolated process with other isolated services.
|
||||
Note that these other isolated services can also belong to other apps from different
|
||||
vendors.
|
||||
<p>
|
||||
Shared isolated processes are created when using the
|
||||
{@link android.content.Context#BIND_SHARED_ISOLATED_PROCESS) during service binding.
|
||||
<p>
|
||||
Note that when this flag is used, the {@link android.R.attr#process} attribute is
|
||||
ignored when the process is bound into a shared isolated process by a client.
|
||||
-->
|
||||
<attr name="allowSharedIsolatedProcess" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- @hide The <code>apex-system-service</code> tag declares an apex system service
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
<public name="visualQueryDetectionService" />
|
||||
<public name="physicalKeyboardHintLanguageTag" />
|
||||
<public name="physicalKeyboardHintLayoutType" />
|
||||
<public name="allowSharedIsolatedProcess" />
|
||||
</staging-public-group>
|
||||
|
||||
<staging-public-group type="id" first-id="0x01cd0000">
|
||||
|
||||
@@ -704,6 +704,26 @@ public final class ActiveServices {
|
||||
}
|
||||
}
|
||||
|
||||
static String getProcessNameForService(ServiceInfo sInfo, ComponentName name,
|
||||
String callingPackage, String instanceName, boolean isSdkSandbox,
|
||||
boolean inSharedIsolatedProcess) {
|
||||
if (isSdkSandbox) {
|
||||
// For SDK sandbox, the process name is passed in as the instanceName
|
||||
return instanceName;
|
||||
}
|
||||
if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
|
||||
// For regular processes, just the name in sInfo
|
||||
return sInfo.processName;
|
||||
}
|
||||
// Isolated processes remain.
|
||||
if (inSharedIsolatedProcess) {
|
||||
// Shared isolated processes are scoped to the calling package
|
||||
return callingPackage + ":ishared:" + instanceName;
|
||||
} else {
|
||||
return sInfo.processName + ":" + name.getClassName();
|
||||
}
|
||||
}
|
||||
|
||||
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
|
||||
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
|
||||
@Nullable String callingFeatureId, final int userId)
|
||||
@@ -736,7 +756,7 @@ public final class ActiveServices {
|
||||
|
||||
ServiceLookupResult res =
|
||||
retrieveServiceLocked(service, null, resolvedType, callingPackage,
|
||||
callingPid, callingUid, userId, true, callerFg, false, false);
|
||||
callingPid, callingUid, userId, true, callerFg, false, false, false);
|
||||
if (res == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -1338,7 +1358,8 @@ public final class ActiveServices {
|
||||
|
||||
// If this service is active, make sure it is stopped.
|
||||
ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, null,
|
||||
Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false, false);
|
||||
Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false, false,
|
||||
false);
|
||||
if (r != null) {
|
||||
if (r.record != null) {
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
@@ -1430,7 +1451,7 @@ public final class ActiveServices {
|
||||
IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
|
||||
ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, callingPackage,
|
||||
Binder.getCallingPid(), Binder.getCallingUid(),
|
||||
UserHandle.getCallingUserId(), false, false, false, false);
|
||||
UserHandle.getCallingUserId(), false, false, false, false, false);
|
||||
|
||||
IBinder ret = null;
|
||||
if (r != null) {
|
||||
@@ -3237,11 +3258,13 @@ public final class ActiveServices {
|
||||
!= ProcessList.SCHED_GROUP_BACKGROUND;
|
||||
final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
|
||||
final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0;
|
||||
final boolean inSharedIsolatedProcess = (flags & Context.BIND_SHARED_ISOLATED_PROCESS) != 0;
|
||||
|
||||
ServiceLookupResult res = retrieveServiceLocked(service, instanceName,
|
||||
isSdkSandboxService, sdkSandboxClientAppUid, sdkSandboxClientAppPackage,
|
||||
resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg,
|
||||
isBindExternal, allowInstant, null /* fgsDelegateOptions */);
|
||||
isBindExternal, allowInstant, null /* fgsDelegateOptions */,
|
||||
inSharedIsolatedProcess);
|
||||
if (res == null) {
|
||||
return 0;
|
||||
}
|
||||
@@ -3697,10 +3720,11 @@ public final class ActiveServices {
|
||||
String instanceName, String resolvedType, String callingPackage,
|
||||
int callingPid, int callingUid, int userId,
|
||||
boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
|
||||
boolean allowInstant) {
|
||||
return retrieveServiceLocked(service, instanceName, false, 0, null, resolvedType,
|
||||
boolean allowInstant, boolean inSharedIsolatedProcess) {
|
||||
return retrieveServiceLocked(service, instanceName, false, INVALID_UID, null, resolvedType,
|
||||
callingPackage, callingPid, callingUid, userId, createIfNeeded, callingFromFg,
|
||||
isBindExternal, allowInstant, null /* fgsDelegateOptions */);
|
||||
isBindExternal, allowInstant, null /* fgsDelegateOptions */,
|
||||
inSharedIsolatedProcess);
|
||||
}
|
||||
|
||||
private ServiceLookupResult retrieveServiceLocked(Intent service,
|
||||
@@ -3708,7 +3732,8 @@ public final class ActiveServices {
|
||||
String sdkSandboxClientAppPackage, String resolvedType,
|
||||
String callingPackage, int callingPid, int callingUid, int userId,
|
||||
boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
|
||||
boolean allowInstant, ForegroundServiceDelegationOptions fgsDelegateOptions) {
|
||||
boolean allowInstant, ForegroundServiceDelegationOptions fgsDelegateOptions,
|
||||
boolean inSharedIsolatedProcess) {
|
||||
if (isSdkSandboxService && instanceName == null) {
|
||||
throw new IllegalArgumentException("No instanceName provided for sdk sandbox process");
|
||||
}
|
||||
@@ -3803,11 +3828,15 @@ public final class ActiveServices {
|
||||
final Intent.FilterComparison filter =
|
||||
new Intent.FilterComparison(service.cloneFilter());
|
||||
final ServiceRestarter res = new ServiceRestarter();
|
||||
final String processName = getProcessNameForService(sInfo, cn, callingPackage,
|
||||
null /* instanceName */, false /* isSdkSandbox */,
|
||||
false /* inSharedIsolatedProcess */);
|
||||
r = new ServiceRecord(mAm, cn /* name */, cn /* instanceName */,
|
||||
sInfo.applicationInfo.packageName, sInfo.applicationInfo.uid, filter, sInfo,
|
||||
callingFromFg, res, null /* sdkSandboxProcessName */,
|
||||
callingFromFg, res, processName,
|
||||
INVALID_UID /* sdkSandboxClientAppUid */,
|
||||
null /* sdkSandboxClientAppPackage */);
|
||||
null /* sdkSandboxClientAppPackage */,
|
||||
false /* inSharedIsolatedProcess */);
|
||||
res.setService(r);
|
||||
smap.mServicesByInstanceName.put(cn, r);
|
||||
smap.mServicesByIntent.put(filter, r);
|
||||
@@ -3901,6 +3930,21 @@ public final class ActiveServices {
|
||||
throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
|
||||
" is not an externalService");
|
||||
}
|
||||
if (inSharedIsolatedProcess) {
|
||||
if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
|
||||
throw new SecurityException("BIND_SHARED_ISOLATED_PROCESS failed, "
|
||||
+ className + " is not an isolatedProcess");
|
||||
}
|
||||
if ((sInfo.flags & ServiceInfo.FLAG_ALLOW_SHARED_ISOLATED_PROCESS) == 0) {
|
||||
throw new SecurityException("BIND_SHARED_ISOLATED_PROCESS failed, "
|
||||
+ className + " has not set the allowSharedIsolatedProcess "
|
||||
+ " attribute.");
|
||||
}
|
||||
if (instanceName == null) {
|
||||
throw new IllegalArgumentException("instanceName must be provided for "
|
||||
+ "binding a service into a shared isolated process.");
|
||||
}
|
||||
}
|
||||
if (userId > 0) {
|
||||
if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
|
||||
sInfo.name, sInfo.flags)
|
||||
@@ -3934,12 +3978,12 @@ public final class ActiveServices {
|
||||
final Intent.FilterComparison filter
|
||||
= new Intent.FilterComparison(service.cloneFilter());
|
||||
final ServiceRestarter res = new ServiceRestarter();
|
||||
String sdkSandboxProcessName = isSdkSandboxService ? instanceName
|
||||
: null;
|
||||
String processName = getProcessNameForService(sInfo, name, callingPackage,
|
||||
instanceName, false, inSharedIsolatedProcess);
|
||||
r = new ServiceRecord(mAm, className, name, definingPackageName,
|
||||
definingUid, filter, sInfo, callingFromFg, res,
|
||||
sdkSandboxProcessName, sdkSandboxClientAppUid,
|
||||
sdkSandboxClientAppPackage);
|
||||
processName, sdkSandboxClientAppUid,
|
||||
sdkSandboxClientAppPackage, inSharedIsolatedProcess);
|
||||
res.setService(r);
|
||||
smap.mServicesByInstanceName.put(name, r);
|
||||
smap.mServicesByIntent.put(filter, r);
|
||||
@@ -4728,21 +4772,52 @@ public final class ActiveServices {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If this service runs in an isolated process, then each time
|
||||
// we call startProcessLocked() we will get a new isolated
|
||||
// process, starting another process if we are currently waiting
|
||||
// for a previous process to come up. To deal with this, we store
|
||||
// in the service any current isolated process it is running in or
|
||||
// waiting to have come up.
|
||||
app = r.isolationHostProc;
|
||||
if (WebViewZygote.isMultiprocessEnabled()
|
||||
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
|
||||
hostingRecord = HostingRecord.byWebviewZygote(r.instanceName, r.definingPackageName,
|
||||
r.definingUid, r.serviceInfo.processName);
|
||||
}
|
||||
if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
|
||||
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
|
||||
r.definingUid, r.serviceInfo.processName);
|
||||
if (r.inSharedIsolatedProcess) {
|
||||
app = mAm.mProcessList.getSharedIsolatedProcess(procName, r.appInfo.uid,
|
||||
r.appInfo.packageName);
|
||||
if (app != null) {
|
||||
final IApplicationThread thread = app.getThread();
|
||||
final int pid = app.getPid();
|
||||
final UidRecord uidRecord = app.getUidRecord();
|
||||
if (thread != null) {
|
||||
try {
|
||||
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
|
||||
"realStartServiceLocked: " + r.shortInstanceName);
|
||||
}
|
||||
realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg,
|
||||
enqueueOomAdj);
|
||||
return null;
|
||||
} catch (TransactionTooLargeException e) {
|
||||
throw e;
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Exception when starting service " + r.shortInstanceName,
|
||||
e);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
// If a dead object exception was thrown -- fall through to
|
||||
// restart the application.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If this service runs in an isolated process, then each time
|
||||
// we call startProcessLocked() we will get a new isolated
|
||||
// process, starting another process if we are currently waiting
|
||||
// for a previous process to come up. To deal with this, we store
|
||||
// in the service any current isolated process it is running in or
|
||||
// waiting to have come up.
|
||||
app = r.isolationHostProc;
|
||||
if (WebViewZygote.isMultiprocessEnabled()
|
||||
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
|
||||
hostingRecord = HostingRecord.byWebviewZygote(r.instanceName,
|
||||
r.definingPackageName,
|
||||
r.definingUid, r.serviceInfo.processName);
|
||||
}
|
||||
if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
|
||||
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
|
||||
r.definingUid, r.serviceInfo.processName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7649,7 +7724,7 @@ public final class ActiveServices {
|
||||
null /* sdkSandboxClientAppPackage */, null /* resolvedType */, callingPackage,
|
||||
callingPid, callingUid, userId, true /* createIfNeeded */,
|
||||
false /* callingFromFg */, false /* isBindExternal */, false /* allowInstant */ ,
|
||||
options);
|
||||
options, false /* inSharedIsolatedProcess */);
|
||||
if (res == null || res.record == null) {
|
||||
Slog.d(TAG,
|
||||
"startForegroundServiceDelegateLocked retrieveServiceLocked returns null");
|
||||
|
||||
@@ -13054,7 +13054,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
String resolvedType, IServiceConnection connection, int flags, String instanceName,
|
||||
String callingPackage, int userId) throws TransactionTooLargeException {
|
||||
return bindServiceInstance(caller, token, service, resolvedType, connection, flags,
|
||||
instanceName, false, 0, null, callingPackage, userId);
|
||||
instanceName, false, INVALID_UID, null, callingPackage, userId);
|
||||
}
|
||||
|
||||
private int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service,
|
||||
|
||||
@@ -3004,6 +3004,16 @@ public final class ProcessList {
|
||||
}
|
||||
}
|
||||
|
||||
ProcessRecord getSharedIsolatedProcess(String processName, int uid, String packageName) {
|
||||
for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
|
||||
final ProcessRecord app = mIsolatedProcesses.valueAt(i);
|
||||
if (app.info.uid == uid && app.info.packageName.equals(packageName)
|
||||
&& app.processName.equals(processName)) {
|
||||
return app;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Nullable
|
||||
@GuardedBy("mService")
|
||||
List<Integer> getIsolatedProcessesLocked(int uid) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.am;
|
||||
import static android.app.PendingIntent.FLAG_IMMUTABLE;
|
||||
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
|
||||
import static android.os.PowerExemptionManager.REASON_DENIED;
|
||||
import static android.os.Process.INVALID_UID;
|
||||
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
|
||||
@@ -118,6 +119,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
|
||||
boolean fgWaiting; // is a timeout for going foreground already scheduled?
|
||||
boolean isNotAppComponentUsage; // is service binding not considered component/package usage?
|
||||
boolean isForeground; // is service currently in foreground mode?
|
||||
boolean inSharedIsolatedProcess; // is the service in a shared isolated process
|
||||
int foregroundId; // Notification ID of last foreground req.
|
||||
Notification foregroundNoti; // Notification record of foreground state.
|
||||
long fgDisplayTime; // time at which the FGS notification should become visible
|
||||
@@ -723,6 +725,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
|
||||
isSdkSandbox = false;
|
||||
sdkSandboxClientAppUid = 0;
|
||||
sdkSandboxClientAppPackage = null;
|
||||
inSharedIsolatedProcess = false;
|
||||
}
|
||||
|
||||
public static ServiceRecord newEmptyInstanceForTest(ActivityManagerService ams) {
|
||||
@@ -734,14 +737,14 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
|
||||
Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
|
||||
Runnable restarter) {
|
||||
this(ams, name, instanceName, definingPackageName, definingUid, intent, sInfo, callerIsFg,
|
||||
restarter, null, 0, null);
|
||||
restarter, sInfo.processName, INVALID_UID, null, false);
|
||||
}
|
||||
|
||||
ServiceRecord(ActivityManagerService ams, ComponentName name,
|
||||
ComponentName instanceName, String definingPackageName, int definingUid,
|
||||
Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
|
||||
Runnable restarter, String sdkSandboxProcessName, int sdkSandboxClientAppUid,
|
||||
String sdkSandboxClientAppPackage) {
|
||||
Runnable restarter, String processName, int sdkSandboxClientAppUid,
|
||||
String sdkSandboxClientAppPackage, boolean inSharedIsolatedProcess) {
|
||||
this.ams = ams;
|
||||
this.name = name;
|
||||
this.instanceName = instanceName;
|
||||
@@ -752,16 +755,11 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
|
||||
serviceInfo = sInfo;
|
||||
appInfo = sInfo.applicationInfo;
|
||||
packageName = sInfo.applicationInfo.packageName;
|
||||
this.isSdkSandbox = sdkSandboxProcessName != null;
|
||||
this.isSdkSandbox = sdkSandboxClientAppUid != INVALID_UID;
|
||||
this.sdkSandboxClientAppUid = sdkSandboxClientAppUid;
|
||||
this.sdkSandboxClientAppPackage = sdkSandboxClientAppPackage;
|
||||
if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0) {
|
||||
processName = sInfo.processName + ":" + instanceName.getClassName();
|
||||
} else if (sdkSandboxProcessName != null) {
|
||||
processName = sdkSandboxProcessName;
|
||||
} else {
|
||||
processName = sInfo.processName;
|
||||
}
|
||||
this.inSharedIsolatedProcess = inSharedIsolatedProcess;
|
||||
this.processName = processName;
|
||||
permission = sInfo.permission;
|
||||
exported = sInfo.exported;
|
||||
this.restarter = restarter;
|
||||
|
||||
@@ -100,6 +100,8 @@ public class ParsedServiceUtils {
|
||||
R.styleable.AndroidManifestService_externalService, sa)
|
||||
| flag(ServiceInfo.FLAG_USE_APP_ZYGOTE,
|
||||
R.styleable.AndroidManifestService_useAppZygote, sa)
|
||||
| flag(ServiceInfo.FLAG_ALLOW_SHARED_ISOLATED_PROCESS,
|
||||
R.styleable.AndroidManifestService_allowSharedIsolatedProcess, sa)
|
||||
| flag(ServiceInfo.FLAG_SINGLE_USER,
|
||||
R.styleable.AndroidManifestService_singleUser, sa)));
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import android.app.compat.CompatChanges;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.os.SystemClock;
|
||||
@@ -40,6 +41,7 @@ import android.util.ArraySet;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -194,6 +196,47 @@ public class ActiveServicesTest {
|
||||
rd2 + btwn + extra, rd2 + (btwn + extra) * 2});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProcessNameForService() throws Exception {
|
||||
// Regular service
|
||||
final ServiceInfo regularService = new ServiceInfo();
|
||||
regularService.processName = "com.foo";
|
||||
String processName = ActiveServices.getProcessNameForService(regularService, null, null,
|
||||
null, false, false);
|
||||
assertEquals("com.foo", processName);
|
||||
|
||||
// Isolated service
|
||||
final ServiceInfo isolatedService = new ServiceInfo();
|
||||
isolatedService.processName = "com.foo";
|
||||
isolatedService.flags = ServiceInfo.FLAG_ISOLATED_PROCESS;
|
||||
final ComponentName component = new ComponentName("com.foo", "barService");
|
||||
processName = ActiveServices.getProcessNameForService(isolatedService, component,
|
||||
null, null, false, false);
|
||||
assertEquals("com.foo:barService", processName);
|
||||
|
||||
// Isolated service in shared isolated process
|
||||
final ServiceInfo isolatedServiceShared1 = new ServiceInfo();
|
||||
isolatedServiceShared1.flags = ServiceInfo.FLAG_ISOLATED_PROCESS;
|
||||
final String instanceName = "pool";
|
||||
final String callingPackage = "com.foo";
|
||||
final String sharedIsolatedProcessName1 = ActiveServices.getProcessNameForService(
|
||||
isolatedServiceShared1, null, callingPackage, instanceName, false, true);
|
||||
assertEquals("com.foo:ishared:pool", sharedIsolatedProcessName1);
|
||||
|
||||
// Bind another one in the same isolated process
|
||||
final ServiceInfo isolatedServiceShared2 = new ServiceInfo(isolatedServiceShared1);
|
||||
final String sharedIsolatedProcessName2 = ActiveServices.getProcessNameForService(
|
||||
isolatedServiceShared2, null, callingPackage, instanceName, false, true);
|
||||
assertEquals(sharedIsolatedProcessName1, sharedIsolatedProcessName2);
|
||||
|
||||
// Simulate another app trying to do the bind
|
||||
final ServiceInfo isolatedServiceShared3 = new ServiceInfo(isolatedServiceShared1);
|
||||
final String otherCallingPackage = "com.bar";
|
||||
final String sharedIsolatedProcessName3 = ActiveServices.getProcessNameForService(
|
||||
isolatedServiceShared3, null, otherCallingPackage, instanceName, false, true);
|
||||
Assert.assertNotEquals(sharedIsolatedProcessName2, sharedIsolatedProcessName3);
|
||||
}
|
||||
|
||||
private void prepareTestRescheduleServiceRestarts() {
|
||||
mService = mock(ActivityManagerService.class);
|
||||
mService.mConstants = mock(ActivityManagerConstants.class);
|
||||
|
||||
Reference in New Issue
Block a user