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

Commit 51c1b670 authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Fix activity move between displays

1. ActivityConfigCallback might not have been registered
because DecorView was not yet attached to window and ViewRootImpl
was not available. In this CL the callback is set as soon as a
DecorView is attached to window.
2. When private display was removed from system, its stacks were
moved to bottom in AM but moved to top in WM.
3. When reparenting stack visibility of activities should be updated
before reparenting in WM, because otherwise WM will be resizing
windows that should no longer visible and reporting it to clients.

Bug: 34164473
Test: android.server.cts.ActivityManagerDisplayTests
Test: #testOnMovedToDisplayCallback
Test: #testContentDestroyOnDisplayRemoved
Change-Id: I6ccc27d873d0d60d7650659fb25cbfcaaeb0fd07
parent 4567c1a1
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.app;

import android.metrics.LogMaker;
import android.graphics.Rect;
import android.view.ViewRootImpl.ActivityConfigCallback;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillPopupWindow;
@@ -6778,12 +6779,12 @@ public class Activity extends ContextThemeWrapper
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
            Window window, ActivityConfigCallback activityConfigCallback) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window);
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
+3 −14
Original line number Diff line number Diff line
@@ -2748,7 +2748,7 @@ public final class ActivityThread {
                activity.attach(appContext, 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.referrer, r.voiceInteractor, window, r.configCallback);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
@@ -3774,12 +3774,6 @@ public final class ActivityThread {
                if (r.activity.mVisibleFromClient) {
                    r.activity.makeVisible();
                }
                final ViewRootImpl viewRoot = r.activity.mDecor.getViewRootImpl();
                if (viewRoot != null) {
                    // TODO: Figure out the best place to set the callback.
                    // This looks like a place where decor view is already initialized.
                    viewRoot.setActivityConfigCallback(r.configCallback);
                }
            }

            if (!r.onlyLocalRequest) {
@@ -5147,13 +5141,8 @@ public final class ActivityThread {
            if (DEBUG_CONFIGURATION) Slog.w(TAG, "Not found target activity to report to: " + r);
            return;
        }
        final boolean movedToDifferentDisplay = displayId != INVALID_DISPLAY;
        if (movedToDifferentDisplay) {
            if (r.activity.getDisplay().getDisplayId() == displayId) {
                throw new IllegalArgumentException("Activity is already on the target display: "
                        + displayId);
            }
        }
        final boolean movedToDifferentDisplay = displayId != INVALID_DISPLAY
                && displayId != r.activity.getDisplay().getDisplayId();

        // Perform updates.
        r.overrideConfig = data.overrideConfig;
+3 −2
Original line number Diff line number Diff line
@@ -1146,10 +1146,11 @@ public class Instrumentation {
            IllegalAccessException {
        Activity activity = (Activity)clazz.newInstance();
        ActivityThread aThread = null;
        activity.attach(context, aThread, this, token, 0, application, intent,
        activity.attach(context, aThread, this, token, 0 /* ident */, application, intent,
                info, title, parent, id,
                (Activity.NonConfigurationInstances)lastNonConfigurationInstance,
                new Configuration(), null, null, null);
                new Configuration(), null /* referrer */, null /* voiceInteractor */,
                null /* window */, null /* activityConfigCallback */);
        return activity;
    }

+1 −0
Original line number Diff line number Diff line
@@ -1498,6 +1498,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
            // renderer about it.
            mBackdropFrameRenderer.onConfigurationChange();
        }
        mWindow.onViewRootImplSet(getViewRootImpl());
    }

    @Override
+12 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.view.ViewGroup;
import android.view.ViewManager;
import android.view.ViewParent;
import android.view.ViewRootImpl;
import android.view.ViewRootImpl.ActivityConfigCallback;
import android.view.Window;
import android.view.WindowManager;
import com.android.internal.R;
@@ -287,6 +288,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {

    private boolean mUseDecorContext = false;

    /** @see ViewRootImpl#mActivityConfigCallback */
    private ActivityConfigCallback mActivityConfigCallback;

    static class WindowManagerHolder {
        static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
                ServiceManager.getService("window"));
@@ -302,7 +306,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
    /**
     * Constructor for main window of an activity.
     */
    public PhoneWindow(Context context, Window preservedWindow) {
    public PhoneWindow(Context context, Window preservedWindow,
            ActivityConfigCallback activityConfigCallback) {
        this(context);
        // Only main activity windows use decor context, all the other windows depend on whatever
        // context that was given to them.
@@ -323,6 +328,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
                DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
        mSupportsPictureInPicture = forceResizable || context.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_PICTURE_IN_PICTURE);
        mActivityConfigCallback = activityConfigCallback;
    }

    @Override
@@ -2060,6 +2066,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
        return mDecor;
    }

    /** Notify when decor view is attached to window and {@link ViewRootImpl} is available. */
    void onViewRootImplSet(ViewRootImpl viewRoot) {
        viewRoot.setActivityConfigCallback(mActivityConfigCallback);
    }

    static private final String FOCUSED_ID_TAG = "android:focusedViewId";
    static private final String VIEWS_TAG = "android:views";
    static private final String PANELS_TAG = "android:Panels";
Loading