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

Commit 988759bc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Extract global configuration update"

parents f62aa63c 3a507b5d
Loading
Loading
Loading
Loading
+143 −114
Original line number Original line Diff line number Diff line
@@ -1125,11 +1125,14 @@ public final class ActivityManagerService extends ActivityManagerNative
     */
     */
    Configuration mGlobalConfiguration = new Configuration();
    Configuration mGlobalConfiguration = new Configuration();
    /** Current sequencing integer of the configuration, for skipping old configurations. */
    private int mConfigurationSeq;
    /**
    /**
     * Current sequencing integer of the configuration, for skipping old
     * Temp object used when global configuration is updated. It is also sent to outer world
     * configurations.
     * instead of {@link #mGlobalConfiguration} because we don't trust anyone...
     */
     */
    private int mConfigurationSeq;
    private Configuration mTempGlobalConfig = new Configuration();
    boolean mSuppressResizeConfigChanges;
    boolean mSuppressResizeConfigChanges;
@@ -18836,6 +18839,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        throw new SecurityException(msg);
        throw new SecurityException(msg);
    }
    }
    @Override
    public void updateConfiguration(Configuration values) {
    public void updateConfiguration(Configuration values) {
        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
                "updateConfiguration()");
                "updateConfiguration()");
@@ -18860,10 +18864,12 @@ public final class ActivityManagerService extends ActivityManagerNative
    }
    }
    void updateUserConfigurationLocked() {
    void updateUserConfigurationLocked() {
        Configuration configuration = new Configuration(mGlobalConfiguration);
        final Configuration configuration = new Configuration(mGlobalConfiguration);
        final int currentUserId = mUserController.getCurrentUserIdLocked();
        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
                currentUserId, Settings.System.canWrite(mContext));
        updateConfigurationLocked(configuration, null, false);
        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
                false /* persistent */, currentUserId, false /* deferResume */);
    }
    }
    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
@@ -18894,16 +18900,37 @@ public final class ActivityManagerService extends ActivityManagerNative
    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
        int changes = 0;
        int changes = 0;
        boolean kept = true;
        if (mWindowManager != null) {
        if (mWindowManager != null) {
            mWindowManager.deferSurfaceLayout();
            mWindowManager.deferSurfaceLayout();
        }
        }
        try {
            if (values != null) {
            if (values != null) {
            Configuration newConfig = new Configuration(mGlobalConfiguration);
                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
            changes = newConfig.updateFrom(values);
                        deferResume);
            if (changes != 0) {
            }
            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
        } finally {
            if (mWindowManager != null) {
                mWindowManager.continueSurfaceLayout();
            }
        }
        return kept;
    }
    /** Update default (global) configuration and notify listeners about changes. */
    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
            boolean persistent, int userId, boolean deferResume) {
        mTempGlobalConfig.setTo(mGlobalConfiguration);
        final int changes = mTempGlobalConfig.updateFrom(values);
        if (changes == 0) {
            return 0;
        }
        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
                        "Updating configuration to: " + values);
                "Updating global configuration to: " + values);
        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
@@ -18912,11 +18939,9 @@ public final class ActivityManagerService extends ActivityManagerNative
            int bestLocaleIndex = 0;
            int bestLocaleIndex = 0;
            if (locales.size() > 1) {
            if (locales.size() > 1) {
                if (mSupportedSystemLocales == null) {
                if (mSupportedSystemLocales == null) {
                            mSupportedSystemLocales =
                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
                                    Resources.getSystem().getAssets().getLocales();
                }
                }
                        bestLocaleIndex = Math.max(0,
                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
                                locales.getFirstMatchIndex(mSupportedSystemLocales));
            }
            }
            SystemProperties.set("persist.sys.locale",
            SystemProperties.set("persist.sys.locale",
                    locales.get(bestLocaleIndex).toLanguageTag());
                    locales.get(bestLocaleIndex).toLanguageTag());
@@ -18925,44 +18950,40 @@ public final class ActivityManagerService extends ActivityManagerNative
                    locales.get(bestLocaleIndex)));
                    locales.get(bestLocaleIndex)));
        }
        }
                mConfigurationSeq++;
        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
                if (mConfigurationSeq <= 0) {
        mTempGlobalConfig.seq = mConfigurationSeq;
                    mConfigurationSeq = 1;
                }
                newConfig.seq = mConfigurationSeq;
                mGlobalConfiguration = newConfig;
                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
                mUsageStatsService.reportConfigurationChange(newConfig,
                        mUserController.getCurrentUserIdLocked());
                //mUsageStatsService.noteStartConfig(newConfig);
                final Configuration configCopy = new Configuration(mGlobalConfiguration);
        mGlobalConfiguration.setTo(mTempGlobalConfig);
        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempGlobalConfig);
        // TODO(multi-display): Update UsageEvents#Event to include displayId.
        mUsageStatsService.reportConfigurationChange(mTempGlobalConfig,
                mUserController.getCurrentUserIdLocked());
                // TODO: If our config changes, should we auto dismiss any currently
        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
                // showing dialogs?
        mShowDialogs = shouldShowDialogs(mTempGlobalConfig, mInVrMode);
                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
        AttributeCache ac = AttributeCache.instance();
        AttributeCache ac = AttributeCache.instance();
        if (ac != null) {
        if (ac != null) {
                    ac.updateConfiguration(configCopy);
            ac.updateConfiguration(mTempGlobalConfig);
        }
        }
                // Make sure all resources in our process are updated
        // Make sure all resources in our process are updated right now, so that anyone who is going
                // right now, so that anyone who is going to retrieve
        // to retrieve resource values after we return will be sure to get the new ones. This is
                // resource values after we return will be sure to get
        // especially important during boot, where the first config change needs to guarantee all
                // the new ones.  This is especially important during
        // resources have that config before following boot code is executed.
                // boot, where the first config change needs to guarantee
        mSystemThread.applyConfigurationToResources(mTempGlobalConfig);
                // all resources have that config before following boot
                // code is executed.
                mSystemThread.applyConfigurationToResources(configCopy);
        // We need another copy of global config because we're scheduling some calls instead of
        // running them in place. We need to be sure that object we send will be handled unchanged.
        final Configuration configCopy = new Configuration(mGlobalConfiguration);
        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
                    msg.obj = new Configuration(configCopy);
            msg.obj = configCopy;
            msg.arg1 = userId;
            msg.arg1 = userId;
            mHandler.sendMessage(msg);
            mHandler.sendMessage(msg);
        }
        }
        // TODO(multi-display): Clear also on secondary display density change?
        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
        if (isDensityChange) {
        if (isDensityChange) {
            // Reset the unsupported display size dialog.
            // Reset the unsupported display size dialog.
@@ -18977,47 +18998,49 @@ public final class ActivityManagerService extends ActivityManagerNative
            try {
            try {
                if (app.thread != null) {
                if (app.thread != null) {
                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
                                    + app.processName + " new config " + mGlobalConfiguration);
                            + app.processName + " new config " + configCopy);
                    app.thread.scheduleConfigurationChanged(configCopy);
                    app.thread.scheduleConfigurationChanged(configCopy);
                }
                }
            } catch (Exception e) {
            } catch (Exception e) {
            }
            }
        }
        }
        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
                | Intent.FLAG_RECEIVER_FOREGROUND);
                | Intent.FLAG_RECEIVER_FOREGROUND);
                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
                        null, AppOpsManager.OP_NONE, null, false, false,
                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
                UserHandle.USER_ALL);
        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
            if (!mProcessesReady) {
            if (!mProcessesReady) {
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
            }
            }
                    broadcastIntentLocked(null, null, intent,
            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
                    UserHandle.USER_ALL);
                }
        }
        }
            // Update the configuration with WM first and check if any of the stacks need to be
            // resized due to the configuration change. If so, resize the stacks now and do any
        // Update the configuration with WM first and check if any of the stacks need to be resized
            // relaunches if necessary. This way we don't need to relaunch again below in
        // due to the configuration change. If so, resize the stacks now and do any relaunches if
        // necessary. This way we don't need to relaunch again afterwards in
        // ensureActivityConfigurationLocked().
        // ensureActivityConfigurationLocked().
        if (mWindowManager != null) {
        if (mWindowManager != null) {
            final int[] resizedStacks =
            final int[] resizedStacks =
                        mWindowManager.setNewConfiguration(mGlobalConfiguration);
                    mWindowManager.setNewConfiguration(mTempGlobalConfig);
            if (resizedStacks != null) {
            if (resizedStacks != null) {
                for (int stackId : resizedStacks) {
                for (int stackId : resizedStacks) {
                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
                        mStackSupervisor.resizeStackLocked(
                                stackId, newBounds, null, null, false, false, deferResume);
                }
                }
            }
            }
        }
        }
        return changes;
    }
    }
    /** Applies latest configuration and/or visibility updates if needed. */
    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
        boolean kept = true;
        boolean kept = true;
        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
        // mainStack is null during startup.
        // mainStack is null during startup.
@@ -19037,12 +19060,18 @@ public final class ActivityManagerService extends ActivityManagerNative
                        !PRESERVE_WINDOWS);
                        !PRESERVE_WINDOWS);
            }
            }
        }
        }
        if (mWindowManager != null) {
            mWindowManager.continueSurfaceLayout();
        }
        return kept;
        return kept;
    }
    }
    /** Helper method that requests bounds from WM and applies them to stack. */
    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
        mStackSupervisor.resizeStackLocked(
                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
    }
    /**
    /**
     * Decide based on the configuration whether we should show the ANR,
     * Decide based on the configuration whether we should show the ANR,
     * crash, etc dialogs.  The idea is that if there is no affordance to
     * crash, etc dialogs.  The idea is that if there is no affordance to
+3 −0
Original line number Original line Diff line number Diff line
@@ -1932,6 +1932,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    public void setInitialDisplaySize(Display display, int width, int height, int density) {
    public void setInitialDisplaySize(Display display, int width, int height, int density) {
        // This method might be called before the policy has been fully initialized
        // This method might be called before the policy has been fully initialized
        // or for other displays we don't care about.
        // or for other displays we don't care about.
        // TODO(multi-display): Define policy for secondary displays.
        if (mContext == null || display.getDisplayId() != Display.DEFAULT_DISPLAY) {
        if (mContext == null || display.getDisplayId() != Display.DEFAULT_DISPLAY) {
            return;
            return;
        }
        }
@@ -2027,6 +2028,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {


    @Override
    @Override
    public void setDisplayOverscan(Display display, int left, int top, int right, int bottom) {
    public void setDisplayOverscan(Display display, int left, int top, int right, int bottom) {
        // TODO(multi-display): Define policy for secondary displays.
        if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
        if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
            mOverscanLeft = left;
            mOverscanLeft = left;
            mOverscanTop = top;
            mOverscanTop = top;
@@ -2428,6 +2430,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {


    @Override
    @Override
    public void onConfigurationChanged() {
    public void onConfigurationChanged() {
        // TODO(multi-display): Define policy for secondary displays.
        final Resources res = mContext.getResources();
        final Resources res = mContext.getResources();


        mStatusBarHeight =
        mStatusBarHeight =
+19 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;


import android.annotation.NonNull;
import android.app.ActivityManager.StackId;
import android.app.ActivityManager.StackId;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Region;
@@ -60,6 +61,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.List;


class DisplayContentList extends ArrayList<DisplayContent> {
class DisplayContentList extends ArrayList<DisplayContent> {
}
}
@@ -212,6 +214,23 @@ class DisplayContent {
        return null;
        return null;
    }
    }


    /** Callback used to notify about configuration changes. */
    void onConfigurationChanged(@NonNull List<Integer> changedStackList) {
        // The display size information is heavily dependent on the resources in the current
        // configuration, so we need to reconfigure it every time the configuration changes.
        // See {@link PhoneWindowManager#setInitialDisplaySize}...sigh...
        mService.reconfigureDisplayLocked(this);

        getDockedDividerController().onConfigurationChanged();

        for (int i = 0; i < mStacks.size(); i++) {
            final TaskStack stack = mStacks.get(i);
            if (stack.onConfigurationChanged()) {
                changedStackList.add(stack.mStackId);
            }
        }
    }

    void checkAppWindowsReadyToShow() {
    void checkAppWindowsReadyToShow() {
        for (int i = mStacks.size() - 1; i >= 0; --i) {
        for (int i = mStacks.size() - 1; i >= 0; --i) {
            final TaskStack stack = mStacks.get(i);
            final TaskStack stack = mStacks.get(i);
+9 −32
Original line number Original line Diff line number Diff line
@@ -886,13 +886,6 @@ public class WindowManagerService extends IWindowManager.Stub
    // since they won't be notified through the app window animator.
    // since they won't be notified through the app window animator.
    final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
    final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();


    // List of displays to reconfigure after configuration changes.
    // Some of the information reported for a display is dependent on resources to do the right
    // calculations. For example, {@link DisplayInfo#smallestNominalAppWidth} and company are
    // dependent on the height and width of the status and nav bar which change depending on the
    // current configuration.
    private final DisplayContentList mReconfigureOnConfigurationChanged = new DisplayContentList();

    // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
    // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
    // instances will be replaced with an instance that writes a binary representation of all
    // instances will be replaced with an instance that writes a binary representation of all
    // commands to mSurfaceTraceFd.
    // commands to mSurfaceTraceFd.
@@ -3168,30 +3161,19 @@ public class WindowManagerService extends IWindowManager.Stub
        }
        }


    }
    }

    private int[] onConfigurationChanged() {
    private int[] onConfigurationChanged() {
        mPolicy.onConfigurationChanged();
        mPolicy.onConfigurationChanged();


        final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
        if (!mReconfigureOnConfigurationChanged.contains(defaultDisplayContent)) {
            // The default display size information is heavily dependent on the resources in the
            // current configuration, so we need to reconfigure it everytime the configuration
            // changes. See {@link PhoneWindowManager#setInitialDisplaySize}...sigh...
            mReconfigureOnConfigurationChanged.add(defaultDisplayContent);
        }
        for (int i = mReconfigureOnConfigurationChanged.size() - 1; i >= 0; i--) {
            reconfigureDisplayLocked(mReconfigureOnConfigurationChanged.remove(i));
        }

        defaultDisplayContent.getDockedDividerController().onConfigurationChanged();
        mChangedStackList.clear();
        mChangedStackList.clear();
        for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; stackNdx--) {

            final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
        final int numDisplays = mDisplayContents.size();
            if (stack.onConfigurationChanged()) {
        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                mChangedStackList.add(stack.mStackId);
            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
            }
            displayContent.onConfigurationChanged(mChangedStackList);
        }
        }
        return mChangedStackList.isEmpty() ?

                null : ArrayUtils.convertToIntArray(mChangedStackList);
        return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
    }
    }


    @Override
    @Override
@@ -8130,9 +8112,7 @@ public class WindowManagerService extends IWindowManager.Stub
        reconfigureDisplayLocked(displayContent);
        reconfigureDisplayLocked(displayContent);
    }
    }


    // displayContent must not be null
    void reconfigureDisplayLocked(@NonNull DisplayContent displayContent) {
    private void reconfigureDisplayLocked(DisplayContent displayContent) {
        // TODO: Multidisplay: for now only use with default display.
        if (!mDisplayReady) {
        if (!mDisplayReady) {
            return;
            return;
        }
        }
@@ -8148,9 +8128,6 @@ public class WindowManagerService extends IWindowManager.Stub
            mWaitingForConfig = true;
            mWaitingForConfig = true;
            startFreezingDisplayLocked(false, 0, 0);
            startFreezingDisplayLocked(false, 0, 0);
            mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
            mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
            if (!mReconfigureOnConfigurationChanged.contains(displayContent)) {
                mReconfigureOnConfigurationChanged.add(displayContent);
            }
        }
        }


        mWindowPlacerLocked.performSurfacePlacement();
        mWindowPlacerLocked.performSurfacePlacement();