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

Commit 1d3db657 authored by Shivam Agrawal's avatar Shivam Agrawal
Browse files

Refactor ATMS and WMS methods

Moved updateDisplayOverrideConfiguration
updateDisplayOverrideConfigurationLocked, and
performDisplayOverrideConfigUpdate from ATMS to ActivityDisplay
because all calls to these methods have a reference to either a
DisplayContent or ActivityDisplay, so it is better that the methods
are called directly rather than going through a service that uses
displayId to get access to an object it already could have had access
to. Similarly, sendNewConfiguration has been moved from
WindowManagerService to DisplayContent. These changes are
necessary for situations where methods in ATMS and WMS want
to process ActivityDisplay and DisplayContent objects before they
are added to either hierarchy. These situations will arise when sending
new configurations happens synchronously as opposed to posting to a
handler (as is the current situation with
DisplayContent#sendNewConfiguration).

Bug: 130807132
Test: go/wm-smoke
Change-Id: Ie2bd6c32b2adc2c4c5d585e361defd6c98652f01
parent 37797b24
Loading
Loading
Loading
Loading
+0 −9
Original line number Original line Diff line number Diff line
@@ -386,15 +386,6 @@ interface IActivityTaskManager {
     */
     */
    void resizePinnedStack(in Rect pinnedBounds, in Rect tempPinnedTaskBounds);
    void resizePinnedStack(in Rect pinnedBounds, in Rect tempPinnedTaskBounds);


    /**
     * Updates override configuration applied to specific display.
     * @param values Update values for display configuration. If null is passed it will request the
     *               Window Manager to compute new config for the specified display.
     * @param displayId Id of the display to apply the config to.
     * @throws RemoteException
     * @return Returns true if the configuration was updated.
     */
    boolean updateDisplayOverrideConfiguration(in Configuration values, int displayId);
    void dismissKeyguard(in IBinder token, in IKeyguardDismissCallback callback,
    void dismissKeyguard(in IBinder token, in IKeyguardDismissCallback callback,
            in CharSequence message);
            in CharSequence message);


+93 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.os.Build.VERSION_CODES.N;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
@@ -55,18 +56,24 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;


import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.ActivityOptions;
import android.app.WindowConfiguration;
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Point;
import android.os.IBinder;
import android.os.IBinder;
import android.os.Message;
import android.os.UserHandle;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.IntArray;
import android.util.IntArray;
import android.util.Slog;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.Display;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.am.EventLogTags;
import com.android.server.am.EventLogTags;


import java.io.PrintWriter;
import java.io.PrintWriter;
@@ -156,6 +163,9 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
    // Used in updating the display size
    // Used in updating the display size
    private Point mTmpDisplaySize = new Point();
    private Point mTmpDisplaySize = new Point();


    // Used in updating override configurations
    private final Configuration mTempConfig = new Configuration();

    private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
    private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();


    ActivityDisplay(RootActivityContainer root, Display display) {
    ActivityDisplay(RootActivityContainer root, Display display) {
@@ -999,6 +1009,89 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        return mStacks.indexOf(stack);
        return mStacks.indexOf(stack);
    }
    }


    boolean updateDisplayOverrideConfigurationLocked() {
        Configuration values = new Configuration();
        mDisplayContent.computeScreenConfiguration(values);

        if (mService.mWindowManager != null) {
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::updateOomLevelsForDisplay, mService.mAmInternal,
                    mDisplayId);
            mService.mH.sendMessage(msg);
        }

        Settings.System.clearConfiguration(values);
        updateDisplayOverrideConfigurationLocked(values, null /* starting */,
                false /* deferResume */, mService.mTmpUpdateConfigurationResult);
        return mService.mTmpUpdateConfigurationResult.changes != 0;
    }

    /**
     * Updates override configuration specific for the selected display. If no config is provided,
     * new one will be computed in WM based on current display info.
     */
    boolean updateDisplayOverrideConfigurationLocked(Configuration values,
            ActivityRecord starting, boolean deferResume,
            ActivityTaskManagerService.UpdateConfigurationResult result) {

        int changes = 0;
        boolean kept = true;

        if (mService.mWindowManager != null) {
            mService.mWindowManager.deferSurfaceLayout();
        }
        try {
            if (values != null) {
                if (mDisplayId == DEFAULT_DISPLAY) {
                    // Override configuration of the default display duplicates global config, so
                    // we're calling global config update instead for default display. It will also
                    // apply the correct override config.
                    changes = mService.updateGlobalConfigurationLocked(values,
                            false /* initLocale */, false /* persistent */,
                            UserHandle.USER_NULL /* userId */, deferResume);
                } else {
                    changes = performDisplayOverrideConfigUpdate(values, deferResume);
                }
            }

            kept = mService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
        } finally {
            if (mService.mWindowManager != null) {
                mService.mWindowManager.continueSurfaceLayout();
            }
        }

        if (result != null) {
            result.changes = changes;
            result.activityRelaunched = !kept;
        }
        return kept;
    }

    int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume) {
        mTempConfig.setTo(getRequestedOverrideConfiguration());
        final int changes = mTempConfig.updateFrom(values);
        if (changes != 0) {
            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
                    + mTempConfig + " for displayId=" + mDisplayId);
            onRequestedOverrideConfigurationChanged(mTempConfig);

            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
            if (isDensityChange && mDisplayId == DEFAULT_DISPLAY) {
                mService.mAppWarnings.onDensityChanged();

                // Post message to start process to avoid possible deadlock of calling into AMS with
                // the ATMS lock held.
                final Message msg = PooledLambda.obtainMessage(
                        ActivityManagerInternal::killAllBackgroundProcessesExcept,
                        mService.mAmInternal, N,
                        ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
                mService.mH.sendMessage(msg);
            }
        }
        return changes;
    }

    @Override
    @Override
    public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
    public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
        final int currRotation =
        final int currRotation =
+11 −117
Original line number Original line Diff line number Diff line
@@ -459,7 +459,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {


    boolean mSuppressResizeConfigChanges;
    boolean mSuppressResizeConfigChanges;


    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
    final UpdateConfigurationResult mTmpUpdateConfigurationResult =
            new UpdateConfigurationResult();
            new UpdateConfigurationResult();


    static final class UpdateConfigurationResult {
    static final class UpdateConfigurationResult {
@@ -631,7 +631,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    /** If non-null, we are tracking the time the user spends in the currently focused app. */
    /** If non-null, we are tracking the time the user spends in the currently focused app. */
    AppTimeTracker mCurAppTimeTracker;
    AppTimeTracker mCurAppTimeTracker;


    private AppWarnings mAppWarnings;
    AppWarnings mAppWarnings;


    /**
    /**
     * Packages that the user has asked to have run in screen size
     * Packages that the user has asked to have run in screen size
@@ -4376,46 +4376,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        }
        }
    }
    }


    @Override
    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
        mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");

        synchronized (mGlobalLock) {
            // Check if display is initialized in AM.
            if (!mRootActivityContainer.isDisplayAdded(displayId)) {
                // Call might come when display is not yet added or has already been removed.
                if (DEBUG_CONFIGURATION) {
                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
                            + displayId);
                }
                return false;
            }

            if (values == null && mWindowManager != null) {
                // sentinel: fetch the current configuration from the window manager
                values = mWindowManager.computeNewConfiguration(displayId);
            }

            if (mWindowManager != null) {
                final Message msg = PooledLambda.obtainMessage(
                        ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
                mH.sendMessage(msg);
            }

            final long origId = Binder.clearCallingIdentity();
            try {
                if (values != null) {
                    Settings.System.clearConfiguration(values);
                }
                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
                return mTmpUpdateConfigurationResult.changes != 0;
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
        }
    }

    @Override
    @Override
    public boolean updateConfiguration(Configuration values) {
    public boolean updateConfiguration(Configuration values) {
        mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
        mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
@@ -5160,8 +5120,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    }
    }


    /** Update default (global) configuration and notify listeners about changes. */
    /** Update default (global) configuration and notify listeners about changes. */
    private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
    int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
            boolean persistent, int userId, boolean deferResume) {
            boolean persistent, int userId, boolean deferResume) {

        final ActivityDisplay defaultDisplay =
                mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY);

        mTempConfig.setTo(getGlobalConfiguration());
        mTempConfig.setTo(getGlobalConfiguration());
        final int changes = mTempConfig.updateFrom(values);
        final int changes = mTempConfig.updateFrom(values);
        if (changes == 0) {
        if (changes == 0) {
@@ -5169,7 +5133,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
            // performDisplayOverrideConfigUpdate in order to send the new display configuration
            // performDisplayOverrideConfigUpdate in order to send the new display configuration
            // (even if there are no actual changes) to unfreeze the window.
            // (even if there are no actual changes) to unfreeze the window.
            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
            defaultDisplay.performDisplayOverrideConfigUpdate(values, deferResume);
            return 0;
            return 0;
        }
        }


@@ -5267,79 +5231,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {


        // Override configuration of the default display duplicates global config, so we need to
        // Override configuration of the default display duplicates global config, so we need to
        // update it also. This will also notify WindowManager about changes.
        // update it also. This will also notify WindowManager about changes.
        performDisplayOverrideConfigUpdate(mRootActivityContainer.getConfiguration(), deferResume,
        defaultDisplay.performDisplayOverrideConfigUpdate(mRootActivityContainer.getConfiguration(),
                DEFAULT_DISPLAY);
                deferResume);

        return changes;
    }

    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
            boolean deferResume, int displayId) {
        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
                displayId, null /* result */);
    }

    /**
     * Updates override configuration specific for the selected display. If no config is provided,
     * new one will be computed in WM based on current display info.
     */
    boolean updateDisplayOverrideConfigurationLocked(Configuration values,
            ActivityRecord starting, boolean deferResume, int displayId,
            ActivityTaskManagerService.UpdateConfigurationResult result) {
        int changes = 0;
        boolean kept = true;

        if (mWindowManager != null) {
            mWindowManager.deferSurfaceLayout();
        }
        try {
            if (values != null) {
                if (displayId == DEFAULT_DISPLAY) {
                    // Override configuration of the default display duplicates global config, so
                    // we're calling global config update instead for default display. It will also
                    // apply the correct override config.
                    changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
                } else {
                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
                }
            }

            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
        } finally {
            if (mWindowManager != null) {
                mWindowManager.continueSurfaceLayout();
            }
        }

        if (result != null) {
            result.changes = changes;
            result.activityRelaunched = !kept;
        }
        return kept;
    }

    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
            int displayId) {
        mTempConfig.setTo(mRootActivityContainer.getDisplayOverrideConfiguration(displayId));
        final int changes = mTempConfig.updateFrom(values);
        if (changes != 0) {
            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
                    + mTempConfig + " for displayId=" + displayId);
            mRootActivityContainer.setDisplayOverrideConfiguration(mTempConfig, displayId);

            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
                mAppWarnings.onDensityChanged();


                // Post message to start process to avoid possible deadlock of calling into AMS with
                // the ATMS lock held.
                final Message msg = PooledLambda.obtainMessage(
                        ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
                        N, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
                mH.sendMessage(msg);
            }
        }
        return changes;
        return changes;
    }
    }


@@ -5763,7 +5657,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    }
    }


    /** Applies latest configuration and/or visibility updates if needed. */
    /** Applies latest configuration and/or visibility updates if needed. */
    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
    boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
        boolean kept = true;
        boolean kept = true;
        final ActivityStack mainStack = mRootActivityContainer.getTopDisplayFocusedStack();
        final ActivityStack mainStack = mRootActivityContainer.getTopDisplayFocusedStack();
        // mainStack is null during startup.
        // mainStack is null during startup.
+27 −8
Original line number Original line Diff line number Diff line
@@ -1204,10 +1204,29 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    }
    }


    /** Notify the configuration change of this display. */
    /** Notify the configuration change of this display. */
    void sendNewConfiguration() {
    void postNewConfigurationToHandler() {
        mWmService.mH.obtainMessage(SEND_NEW_CONFIGURATION, this).sendToTarget();
        mWmService.mH.obtainMessage(SEND_NEW_CONFIGURATION, this).sendToTarget();
    }
    }


    void sendNewConfiguration() {
        synchronized (mWmService.mGlobalLock) {
            final boolean configUpdated = mAcitvityDisplay
                    .updateDisplayOverrideConfigurationLocked();
            if (!configUpdated) {
                // Something changed (E.g. device rotation), but no configuration update is needed.
                // E.g. changing device rotation by 180 degrees. Go ahead and perform surface
                // placement to unfreeze the display since we froze it when the rotation was updated
                // in DisplayContent#updateRotationUnchecked.
                if (mWaitingForConfig) {
                    mWaitingForConfig = false;
                    mWmService.mLastFinishedFreezeSource = "config-unchanged";
                    setLayoutNeeded();
                    mWmService.mWindowPlacerLocked.performSurfacePlacement();
                }
            }
        }
    }

    @Override
    @Override
    boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
    boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
            ConfigurationContainer requestingContainer) {
            ConfigurationContainer requestingContainer) {
@@ -1223,8 +1242,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo


        if (handled && requestingContainer instanceof ActivityRecord) {
        if (handled && requestingContainer instanceof ActivityRecord) {
            final ActivityRecord activityRecord = (ActivityRecord) requestingContainer;
            final ActivityRecord activityRecord = (ActivityRecord) requestingContainer;
            final boolean kept = mWmService.mAtmService.updateDisplayOverrideConfigurationLocked(
            final boolean kept = mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(
                    config, activityRecord, false /* deferResume */, getDisplayId());
                    config, activityRecord, false /* deferResume */, null /* result */);
            activityRecord.frozenBeforeDestroy = true;
            activityRecord.frozenBeforeDestroy = true;
            if (!kept) {
            if (!kept) {
                mWmService.mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
                mWmService.mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
@@ -1232,8 +1251,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        } else {
        } else {
            // We have a new configuration to push so we need to update ATMS for now.
            // We have a new configuration to push so we need to update ATMS for now.
            // TODO: Clean up display configuration push between ATMS and WMS after unification.
            // TODO: Clean up display configuration push between ATMS and WMS after unification.
            mWmService.mAtmService.updateDisplayOverrideConfigurationLocked(
            mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(
                    config, null /* starting */, false /* deferResume */, getDisplayId());
                    config, null /* starting */, false /* deferResume */, null);
        }
        }
        return handled;
        return handled;
    }
    }
@@ -1323,7 +1342,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    boolean updateRotationAndSendNewConfigIfNeeded() {
    boolean updateRotationAndSendNewConfigIfNeeded() {
        final boolean changed = updateRotationUnchecked(false /* forceUpdate */);
        final boolean changed = updateRotationUnchecked(false /* forceUpdate */);
        if (changed) {
        if (changed) {
            sendNewConfiguration();
            postNewConfigurationToHandler();
        }
        }
        return changed;
        return changed;
    }
    }
@@ -1342,7 +1361,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
     * Update rotation of the DisplayContent with an option to force the update. This updates
     * Update rotation of the DisplayContent with an option to force the update. This updates
     * the container's perception of rotation and, depending on the top activities, will freeze
     * the container's perception of rotation and, depending on the top activities, will freeze
     * the screen or start seamless rotation. The display itself gets rotated in
     * the screen or start seamless rotation. The display itself gets rotated in
     * {@link #applyRotationLocked} during {@link WindowManagerService#sendNewConfiguration}.
     * {@link #applyRotationLocked} during {@link DisplayContent#sendNewConfiguration}.
     *
     *
     * @param forceUpdate Force the rotation update. Sometimes in WM we might skip updating
     * @param forceUpdate Force the rotation update. Sometimes in WM we might skip updating
     *                    orientation because we're waiting for some rotation to finish or display
     *                    orientation because we're waiting for some rotation to finish or display
@@ -3688,7 +3707,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
                if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
                if (updateOrientationFromAppTokens()) {
                if (updateOrientationFromAppTokens()) {
                    setLayoutNeeded();
                    setLayoutNeeded();
                    sendNewConfiguration();
                    postNewConfigurationToHandler();
                }
                }
            }
            }


+1 −1
Original line number Original line Diff line number Diff line
@@ -133,7 +133,7 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
    @Override
    @Override
    public void notifyConfigurationChanged() {
    public void notifyConfigurationChanged() {
        // TODO(multi-display): Notify proper displays that are associated with this input device.
        // TODO(multi-display): Notify proper displays that are associated with this input device.
        mService.sendNewConfiguration(DEFAULT_DISPLAY);
        mService.mRoot.getDisplayContent(DEFAULT_DISPLAY).sendNewConfiguration();


        synchronized (mInputDevicesReadyMonitor) {
        synchronized (mInputDevicesReadyMonitor) {
            if (!mInputDevicesReady) {
            if (!mInputDevicesReady) {
Loading