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

Commit fa23a9ee authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Override process config to match activity config

Some apps use Application context to get display configuration and
metrics for their activities. This leads to incorrect configuration
used for activities on secondary screens. This is an issue on the
application side, but the framework can provide some compatibility -
override process-level config to match the display where the first
activity was launched.

This CL makes the process follow the activity configuration.
For simplicity, it will always follow the configuration of the
activity that was last added to the process. Additional optimizations
might be added in future.

This CL also adds new merged override configuration listener
interface to report the combined config overrides from the current
node and its parents. This is necessary for cases like sending
a config override to WindowProcessController, when the subscriber is
interested in a complete override vs the override on the current
level of the hierarchy. E.g. when an Activity is registered as a
config override provider for WPC, then we should also send the
overrides from Task, Stack and Display levels.

Bug: 131179060
Bug: 132986140
Bug: 131915789
Test: atest WmTests:ActivityRecordTests#testSetProcessOverridesConfig
Test: Launch GMail on secondary screen
Change-Id: I5c4342646858a77aeebc274265aab41dc753fbca
parent 60ebe763
Loading
Loading
Loading
Loading
+8 −2
Original line number Original line Diff line number Diff line
@@ -1673,6 +1673,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        if (root == this) {
        if (root == this) {
            task.setRootProcess(proc);
            task.setRootProcess(proc);
        }
        }
        proc.addActivityIfNeeded(this);
    }
    }


    boolean hasProcess() {
    boolean hasProcess() {
@@ -6901,7 +6902,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // Update last reported values.
        // Update last reported values.
        final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
        final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();


        setLastReportedConfiguration(mAtmService.getGlobalConfiguration(), newMergedOverrideConfig);
        setLastReportedConfiguration(getProcessGlobalConfiguration(), newMergedOverrideConfig);


        if (mState == INITIALIZING) {
        if (mState == INITIALIZING) {
            // No need to relaunch or schedule new config for activity that hasn't been launched
            // No need to relaunch or schedule new config for activity that hasn't been launched
@@ -7000,6 +7001,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return true;
        return true;
    }
    }


    /** Get process configuration, or global config if the process is not set. */
    private Configuration getProcessGlobalConfiguration() {
        return app != null ? app.getConfiguration() : mAtmService.getGlobalConfiguration();
    }

    /**
    /**
     * When assessing a configuration change, decide if the changes flags and the new configurations
     * When assessing a configuration change, decide if the changes flags and the new configurations
     * should cause the Activity to relaunch.
     * should cause the Activity to relaunch.
@@ -7112,7 +7118,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            startRelaunching();
            startRelaunching();
            final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
            final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
                    pendingNewIntents, configChangeFlags,
                    pendingNewIntents, configChangeFlags,
                    new MergedConfiguration(mAtmService.getGlobalConfiguration(),
                    new MergedConfiguration(getProcessGlobalConfiguration(),
                            getMergedOverrideConfiguration()),
                            getMergedOverrideConfiguration()),
                    preserveWindow);
                    preserveWindow);
            final ActivityLifecycleItem lifecycleItem;
            final ActivityLifecycleItem lifecycleItem;
+0 −2
Original line number Original line Diff line number Diff line
@@ -848,8 +848,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {


            if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
            if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);


            proc.addActivityIfNeeded(r);

            final LockTaskController lockTaskController = mService.getLockTaskController();
            final LockTaskController lockTaskController = mService.getLockTaskController();
            if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
            if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
                    || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV
                    || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV
+1 −2
Original line number Original line Diff line number Diff line
@@ -248,7 +248,6 @@ import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -6697,7 +6696,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                    return;
                    return;
                }
                }
                process.mIsImeProcess = true;
                process.mIsImeProcess = true;
                process.registerDisplayConfigurationListenerLocked(displayContent);
                process.registerDisplayConfigurationListener(displayContent);
            }
            }
        }
        }


+6 −1
Original line number Original line Diff line number Diff line
@@ -134,8 +134,8 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
        resolveOverrideConfiguration(newParentConfig);
        resolveOverrideConfiguration(newParentConfig);
        mFullConfiguration.setTo(newParentConfig);
        mFullConfiguration.setTo(newParentConfig);
        mFullConfiguration.updateFrom(mResolvedOverrideConfiguration);
        mFullConfiguration.updateFrom(mResolvedOverrideConfiguration);
        if (!mResolvedTmpConfig.equals(mResolvedOverrideConfiguration)) {
        onMergedOverrideConfigurationChanged();
        onMergedOverrideConfigurationChanged();
        if (!mResolvedTmpConfig.equals(mResolvedOverrideConfiguration)) {
            // This depends on the assumption that change-listeners don't do
            // This depends on the assumption that change-listeners don't do
            // their own override resolution. This way, dependent hierarchies
            // their own override resolution. This way, dependent hierarchies
            // can stay properly synced-up with a primary hierarchy's constraints.
            // can stay properly synced-up with a primary hierarchy's constraints.
@@ -147,6 +147,10 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
                        mResolvedOverrideConfiguration);
                        mResolvedOverrideConfiguration);
            }
            }
        }
        }
        for (int i = mChangeListeners.size() - 1; i >= 0; --i) {
            mChangeListeners.get(i).onMergedOverrideConfigurationChanged(
                    mMergedOverrideConfiguration);
        }
        if (forwardToChildren) {
        if (forwardToChildren) {
            for (int i = getChildCount() - 1; i >= 0; --i) {
            for (int i = getChildCount() - 1; i >= 0; --i) {
                final ConfigurationContainer child = getChildAt(i);
                final ConfigurationContainer child = getChildAt(i);
@@ -545,6 +549,7 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
        }
        }
        mChangeListeners.add(listener);
        mChangeListeners.add(listener);
        listener.onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration);
        listener.onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration);
        listener.onMergedOverrideConfigurationChanged(mMergedOverrideConfiguration);
    }
    }


    void unregisterConfigurationChangeListener(ConfigurationContainerListener listener) {
    void unregisterConfigurationChangeListener(ConfigurationContainerListener listener) {
+4 −1
Original line number Original line Diff line number Diff line
@@ -24,5 +24,8 @@ import android.content.res.Configuration;
public interface ConfigurationContainerListener {
public interface ConfigurationContainerListener {


    /** {@see ConfigurationContainer#onRequestedOverrideConfigurationChanged} */
    /** {@see ConfigurationContainer#onRequestedOverrideConfigurationChanged} */
    void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration);
    default void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {}

    /** Called when new merged override configuration is reported. */
    default void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfiguration) {}
}
}
Loading