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

Commit c3b097b7 authored by Jiaming Liu's avatar Jiaming Liu
Browse files

Add property to allow activity state sharing in untrusted embedding

We choose to use a string property instead of a boolean property because
we might need to add new values for fine-grained control in the future,
and string property gives us the flexibility.

Bug: 297887697
Test: atest TaskFragmentOrganizerControllerTest
Change-Id: I29d4fe945bcbce4c9cbbde37fe7e1581cbb00f32
parent 3b8bcbc9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -53870,6 +53870,7 @@ package android.view {
    method @FlaggedApi("com.android.window.flags.trusted_presentation_listener_for_window") public default void unregisterTrustedPresentationListener(@NonNull java.util.function.Consumer<java.lang.Boolean>);
    field public static final String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE = "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE";
    field public static final String PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED = "android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED";
    field @FlaggedApi("com.android.window.flags.untrusted_embedding_state_sharing") public static final String PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING = "android.window.PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING";
    field public static final String PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION = "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION";
    field public static final String PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH = "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH";
    field public static final String PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE = "android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE";
+28 −0
Original line number Diff line number Diff line
@@ -1471,6 +1471,34 @@ public interface WindowManager extends ViewManager {
    String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE =
            "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE";

    /**
     * Activity-level {@link android.content.pm.PackageManager.Property PackageManager.Property}
     * that declares whether this (embedded) activity allows the system to share its state with the
     * host app when it is embedded in a different process in
     * {@link android.R.attr#allowUntrustedActivityEmbedding untrusted mode}.
     *
     * <p>If this property is "true", the host app may receive event callbacks for the activity
     * state change, including the reparent event and the component name of the activity, which are
     * required to restore the embedding state after the embedded activity exits picture-in-picture
     * mode. This property does not share any of the activity content with the host. Note that, for
     * {@link android.R.attr#knownActivityEmbeddingCerts trusted embedding}, the reparent event and
     * the component name are always shared with the host regardless of the value of this property.
     *
     * <p>The default value is {@code false}.
     *
     * <p><b>Syntax:</b>
     * <pre>
     * &lt;activity&gt;
     *   &lt;property
     *     android:name="android.window.PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING"
     *     android:value="true|false"/&gt;
     * &lt;/activity&gt;
     * </pre>
     */
    @FlaggedApi(Flags.FLAG_UNTRUSTED_EMBEDDING_STATE_SHARING)
    String PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING =
            "android.window.PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING";

    /**
     * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property}
     * that an app can specify to inform the system that the app is activity embedding split feature
+8 −0
Original line number Diff line number Diff line
@@ -56,6 +56,14 @@ flag {
    is_fixed_read_only: true
}

flag {
    namespace: "windowing_sdk"
    name: "untrusted_embedding_state_sharing"
    description: "Feature flag to enable state sharing in untrusted embedding when apps opt in."
    bug: "293647332"
    is_fixed_read_only: true
}

flag {
    namespace: "windowing_sdk"
    name: "embedded_activity_back_nav_flag"
+32 −0
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED;
import static android.view.WindowManager.PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_UNSET;
@@ -386,6 +387,7 @@ import com.android.server.wm.ActivityMetricsLogger.TransitionInfoSnapshot;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.WindowManagerService.H;
import com.android.server.wm.utils.InsetUtils;
import com.android.window.flags.Flags;

import dalvik.annotation.optimization.NeverCompile;

@@ -986,6 +988,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    // Whether the ActivityEmbedding is enabled on the app.
    private final boolean mAppActivityEmbeddingSplitsEnabled;

    // Whether the Activity allows state sharing in untrusted embedding
    private final boolean mAllowUntrustedEmbeddingStateSharing;

    // Records whether client has overridden the WindowAnimation_(Open/Close)(Enter/Exit)Animation.
    private CustomAppTransition mCustomOpenTransition;
    private CustomAppTransition mCustomCloseTransition;
@@ -2223,6 +2228,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            // No such property name.
        }
        mAppActivityEmbeddingSplitsEnabled = appActivityEmbeddingEnabled;
        mAllowUntrustedEmbeddingStateSharing = getAllowUntrustedEmbeddingStateSharingProperty();

        mOptInOnBackInvoked = WindowOnBackInvokedDispatcher
                .isOnBackInvokedCallbackEnabled(info, info.applicationInfo,
@@ -3078,6 +3084,32 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return parent != null && parent.isEmbedded();
    }

    /**
     * Returns {@code true} if the system is allowed to share this activity's state with the host
     * app when this activity is embedded in untrusted mode.
     */
    boolean isUntrustedEmbeddingStateSharingAllowed() {
        if (!Flags.untrustedEmbeddingStateSharing()) {
            return false;
        }
        return mAllowUntrustedEmbeddingStateSharing;
    }

    private boolean getAllowUntrustedEmbeddingStateSharingProperty() {
        if (!Flags.untrustedEmbeddingStateSharing()) {
            return false;
        }
        try {
            return mAtmService.mContext.getPackageManager()
                    .getProperty(PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING,
                            mActivityComponent)
                    .getBoolean();
        } catch (PackageManager.NameNotFoundException e) {
            // No such property name.
            return false;
        }
    }

    @Override
    @Nullable
    TaskDisplayArea getDisplayArea() {
+8 −3
Original line number Diff line number Diff line
@@ -376,10 +376,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
                        + " is not in a task belong to the organizer app.");
                return null;
            }
            if (task.isAllowedToEmbedActivity(activity, mOrganizerUid) != EMBEDDING_ALLOWED
                    || !task.isAllowedToEmbedActivityInTrustedMode(activity, mOrganizerUid)) {
            if (task.isAllowedToEmbedActivity(activity, mOrganizerUid) != EMBEDDING_ALLOWED) {
                Slog.d(TAG, "Reparent activity=" + activity.token
                        + " is not allowed to be embedded in trusted mode.");
                        + " is not allowed to be embedded.");
                return null;
            }
            if (!task.isAllowedToEmbedActivityInTrustedMode(activity, mOrganizerUid)
                    && !activity.isUntrustedEmbeddingStateSharingAllowed()) {
                Slog.d(TAG, "Reparent activity=" + activity.token
                        + " is not allowed to be shared with untrusted host.");
                return null;
            }

Loading