Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cd2c859 authored by Mohammed Rashidy's avatar Mohammed Rashidy
Browse files

Call sandbox API to get SDK details to use them to create context for

sandbox activity.

When launching sandbox activity, sandbox new API (in the same topic)
should be called to provide a SDK details to use it to build the base
context.

Test: Same topic should contain CTS.
Bug: 290324851

Change-Id: I76d3ae2a6f7eb26fd6b6fc69fda027f805d4231f
parent 72dbcc03
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ java_defaults {
        ":android.view.inputmethod.flags-aconfig-java{.generated_srcjars}",
        ":android.widget.flags-aconfig-java{.generated_srcjars}",
        ":com.android.media.flags.bettertogether-aconfig-java{.generated_srcjars}",
        ":sdk_sandbox_flags_lib{.generated_srcjars}",
    ],
    // Add aconfig-annotations-lib as a dependency for the optimization
    libs: ["aconfig-annotations-lib"],
+8 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.inMultiWindowMode;
import static android.os.Process.myUid;

import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext;
import static java.lang.Character.MIN_VALUE;

import android.annotation.AnimRes;
@@ -8631,6 +8631,12 @@ public class Activity extends ContextThemeWrapper
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
            IBinder shareableActivityToken) {
        if (sandboxActivitySdkBasedContext()) {
            // Sandbox activities extract a token from the intent's extra to identify the related
            // SDK as part of overriding attachBaseContext, then it wraps the passed context in an
            // SDK ContextWrapper, so mIntent has to be set before calling attachBaseContext.
            mIntent = intent;
        }
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);
@@ -8656,6 +8662,7 @@ public class Activity extends ContextThemeWrapper
        mShareableActivityToken = shareableActivityToken;
        mIdent = ident;
        mApplication = application;
        //TODO(b/300059435): do not set the mIntent again as part of the flag clean up.
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
+71 −7
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import static android.window.ConfigurationHelper.isDifferentDisplay;
import static android.window.ConfigurationHelper.shouldUpdateResources;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.os.SafeZipPathValidatorCallback.VALIDATE_ZIP_PATH_FOR_PATH_TRAVERSAL;
import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -53,6 +54,8 @@ import android.app.backup.BackupAgent;
import android.app.backup.BackupAnnotations.BackupDestination;
import android.app.backup.BackupAnnotations.OperationType;
import android.app.compat.CompatChanges;
import android.app.sdksandbox.sandboxactivity.ActivityContextInfo;
import android.app.sdksandbox.sandboxactivity.ActivityContextInfoProvider;
import android.app.servertransaction.ActivityLifecycleItem;
import android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
import android.app.servertransaction.ActivityRelaunchItem;
@@ -3734,16 +3737,38 @@ public final class ActivityThread extends ClientTransactionHandler
                    r.activityInfo.targetActivity);
        }

        ContextImpl appContext = createBaseContextForActivity(r);
        boolean isSandboxActivityContext = sandboxActivitySdkBasedContext()
                && r.intent.isSandboxActivity(mSystemContext);
        boolean isSandboxedSdkContextUsed = false;
        ContextImpl activityBaseContext;
        if (isSandboxActivityContext) {
            activityBaseContext = createBaseContextForSandboxActivity(r);
            if (activityBaseContext == null) {
                // Failed to retrieve the SDK based sandbox activity context, falling back to the
                // app based context.
                activityBaseContext = createBaseContextForActivity(r);
            } else {
                isSandboxedSdkContextUsed = true;
            }
        } else {
            activityBaseContext = createBaseContextForActivity(r);
        }
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            java.lang.ClassLoader cl;
            if (isSandboxedSdkContextUsed) {
                // In case of sandbox activity, the context refers to the an SDK with no visibility
                // on the SandboxedActivity java class, the App context should be used instead.
                cl = activityBaseContext.getApplicationContext().getClassLoader();
            } else {
                cl = activityBaseContext.getClassLoader();
            }
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                    appContext.getAttributionSource());
                    activityBaseContext.getAttributionSource());
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
@@ -3774,7 +3799,8 @@ public final class ActivityThread extends ClientTransactionHandler
            }

            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                CharSequence title =
                        r.activityInfo.loadLabel(activityBaseContext.getPackageManager());
                Configuration config =
                        new Configuration(mConfigurationController.getCompatConfiguration());
                if (r.overrideConfig != null) {
@@ -3791,11 +3817,11 @@ public final class ActivityThread extends ClientTransactionHandler

                // Activity resources must be initialized with the same loaders as the
                // application context.
                appContext.getResources().addLoaders(
                activityBaseContext.getResources().addLoaders(
                        app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

                appContext.setOuterContext(activity);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                activityBaseContext.setOuterContext(activity);
                activity.attach(activityBaseContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
@@ -3951,6 +3977,44 @@ public final class ActivityThread extends ClientTransactionHandler
        return appContext;
    }

    /**
     * Creates the base context for the sandbox activity based on its corresponding SDK {@link
     * ApplicationInfo} and flags.
     */
    @Nullable
    private ContextImpl createBaseContextForSandboxActivity(@NonNull ActivityClientRecord r) {
        ActivityContextInfoProvider contextInfoProvider = ActivityContextInfoProvider.getInstance();

        ActivityContextInfo contextInfo;
        try {
            contextInfo = contextInfoProvider.getActivityContextInfo(r.intent);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Passed intent does not match an expected sandbox activity", e);
            return null;
        } catch (IllegalStateException e) {
            Log.e(TAG, "SDK customized context flag is disabled", e);
            return null;
        } catch (Exception e) { // generic catch to unexpected exceptions
            Log.e(TAG, "Failed to create context for sandbox activity", e);
            return null;
        }

        final int displayId = ActivityClient.getInstance().getDisplayId(r.token);
        final LoadedApk sdkApk = getPackageInfo(
                contextInfo.getSdkApplicationInfo(),
                r.packageInfo.getCompatibilityInfo(),
                ActivityContextInfo.CONTEXT_FLAGS);

        final ContextImpl activityContext = ContextImpl.createActivityContext(
                this, sdkApk, r.activityInfo, r.token, displayId, r.overrideConfig);

        // Set sandbox app's context as the application context for sdk context
        activityContext.mPackageInfo.makeApplicationInner(
                /*forceDefaultAppClass=*/false, mInstrumentation);

        return activityContext;
    }

    /**
     * Extended implementation of activity launch. Used when server requests a launch or relaunch.
     */