Add an API to create customized context for Sdk in Sandbox
SdkSandbox needs to load multiple sdk libraries in its process. This is somewhat analogous to multiple apps sharing the same process, where apps get their own specific context. SdkSandbox however currently does not provide sdk-specific contexts to sdks. Each sdk gets a context wrapper with the sdksandbox's context as its base. The base context does not represent SDK correctly and any component using the base context, such as managers for system service, is thus using wrong information. The new API allows us to create sdk specific context using sdk's ApplicationInfo. By modifing the base context directly, instead of wrapper, we ensure manager components get the correct information. Ideally, the context should return the sdk's package name when `Context#getPackageName()` is called, but that breaks permission checking logic. We therefore keep it same as before and set sandbox app name as the package name so that SDK get the same permission as sandbox app. Since a new LoadedApk instance is generated when the new API is called, we need to populate the Application context on it. While it would be ideal to have each sdk context to return their own instance of application context, since all the context share the same package name, we opted for the status quo and returned the original unmodified sandbox context as the application context. We may change this behavior in future after more investigation. Only Sandbox process should be using this API, so we guard it using the process uid. I have verified that while our module code can use this API, sdk code is unable to find it. Bug: 255937439 Test: atest SandboxedSdkContextTest (see topic) Change-Id: I0d96f915c4dac46b760812b616cab635f7159c66
This commit is contained in:
@@ -82,6 +82,7 @@ package android.content {
|
||||
}
|
||||
|
||||
public abstract class Context {
|
||||
method @NonNull public android.content.Context createContextForSdkInSandbox(@NonNull android.content.pm.ApplicationInfo, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||
method @NonNull public android.os.IBinder getIApplicationThreadBinder();
|
||||
method @NonNull public android.os.UserHandle getUser();
|
||||
field public static final String PAC_PROXY_SERVICE = "pac_proxy";
|
||||
|
||||
@@ -2640,7 +2640,7 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
|
||||
boolean registerPackage) {
|
||||
return getPackageInfo(aInfo, compatInfo, baseLoader, securityViolation, includeCode,
|
||||
registerPackage, /*isSdkSandbox=*/false);
|
||||
registerPackage, Process.isSdkSandbox());
|
||||
}
|
||||
|
||||
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
|
||||
|
||||
@@ -2583,6 +2583,22 @@ class ContextImpl extends Context {
|
||||
"Application package " + application.packageName + " not found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context createContextForSdkInSandbox(ApplicationInfo sdkInfo, int flags)
|
||||
throws NameNotFoundException {
|
||||
if (!Process.isSdkSandbox()) {
|
||||
throw new SecurityException("API can only be called from SdkSandbox process");
|
||||
}
|
||||
|
||||
ContextImpl ctx = (ContextImpl) createApplicationContext(sdkInfo, flags);
|
||||
|
||||
// Set sandbox app's context as the application context for sdk context
|
||||
ctx.mPackageInfo.makeApplicationInner(/*forceDefaultAppClass=*/false,
|
||||
/*instrumentation=*/null);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context createPackageContext(String packageName, int flags)
|
||||
throws NameNotFoundException {
|
||||
|
||||
@@ -6852,6 +6852,26 @@ public abstract class Context {
|
||||
public abstract Context createApplicationContext(ApplicationInfo application,
|
||||
@CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
|
||||
|
||||
/**
|
||||
* Creates a context given an {@link android.content.pm.ApplicationInfo}.
|
||||
*
|
||||
* Context created is for an sdk library that is being loaded in sdk sandbox.
|
||||
*
|
||||
* @param sdkInfo information regarding the sdk library being loaded.
|
||||
*
|
||||
* @throws PackageManager.NameNotFoundException if there is no application with
|
||||
* the given package name.
|
||||
* @throws SecurityException if caller is not a SdkSandbox process.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@NonNull
|
||||
public Context createContextForSdkInSandbox(@NonNull ApplicationInfo sdkInfo,
|
||||
@CreatePackageOptions int flags) throws PackageManager.NameNotFoundException {
|
||||
throw new RuntimeException("Not implemented. Must override in a subclass.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new Context object for the given split name. The new Context has a ClassLoader and
|
||||
* Resources object that can access the split's and all of its dependencies' code/resources.
|
||||
|
||||
@@ -1071,6 +1071,15 @@ public class ContextWrapper extends Context {
|
||||
return mBase.createApplicationContext(application, flags);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@NonNull
|
||||
public Context createContextForSdkInSandbox(@NonNull ApplicationInfo sdkInfo, int flags)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
return mBase.createContextForSdkInSandbox(sdkInfo, flags);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
public Context createContextForSplit(String splitName)
|
||||
|
||||
Reference in New Issue
Block a user