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

Commit e36d6e27 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Work on issue #2263557: PMF3000 showing hybrid of portrait and landscape modes

This is a bunch of reworking of how configuration changes are handled:

- When orientation is changing (for whatever reason), the window manager no
  longer tries to pre-emptively compute a new configuration.  Instead, it
  just determines  change is happening and tells the window manager.
- The activity manager is now responsible for giving the window manager the
  final configuration it is using.  This is both so it knows whem the
  activity manager is done with its configuration updates, and so the window
  manager can use the "real" configuration.
- When an orientation or other configuration change is happening, freeze the
  screen and keep it frozen until the activity manager has given us the
  final configuration.
- The window manager can now send new configurations to its clients during
  its layout pass, as part of a resize, if it has determined that it has
  changed.  This allows for a new View.onConfigurationChanged() API for any
  view to easily find out when the configuration has changed.
- ViewRoot now also works with the activity thread to make sure the process's
  current resources are updated to the new configuration when it receives one
  from a window.  This ensures that at the time onConfigurationChanged() and
  other view callbacks are happening, the correct configuration is in force.
- There is now a sequence number associated with Configuration, which
  ActivityThread uses to avoid using stale configurations.  This is needed now
  that it can receive configurations asynchronously from both the window
  manager and activity manager.
- The hack for keeping the locale has been removed, and underlying problem
  fixed by having Configuration initialize its locale to "unknown" instead of
  a valid default value.
parent a696f5d6
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -173008,6 +173008,19 @@
 visibility="public"
>
</method>
<method name="dispatchConfigurationChanged"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="newConfig" type="android.content.res.Configuration">
</parameter>
</method>
<method name="dispatchDisplayHint"
 return="void"
 abstract="false"
@@ -174699,6 +174712,19 @@
 visibility="public"
>
</method>
<method name="onConfigurationChanged"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="protected"
>
<parameter name="newConfig" type="android.content.res.Configuration">
</parameter>
</method>
<method name="onCreateContextMenu"
 return="void"
 abstract="false"
+97 −56
Original line number Diff line number Diff line
@@ -1392,7 +1392,7 @@ public final class ActivityThread {
            r.startsNotResumed = notResumed;
            r.createdConfig = config;

            synchronized (mRelaunchingActivities) {
            synchronized (mPackages) {
                mRelaunchingActivities.add(r);
            }

@@ -1523,9 +1523,12 @@ public final class ActivityThread {
        }

        public void scheduleConfigurationChanged(Configuration config) {
            synchronized (mRelaunchingActivities) {
            synchronized (mPackages) {
                if (mPendingConfiguration == null ||
                        mPendingConfiguration.isOtherSeqNewer(config)) {
                    mPendingConfiguration = config;
                }
            }
            queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
        }

@@ -2060,6 +2063,7 @@ public final class ActivityThread {
            = new HashMap<IBinder, Service>();
    AppBindData mBoundApplication;
    Configuration mConfiguration;
    Configuration mResConfiguration;
    Application mInitialApplication;
    final ArrayList<Application> mAllApplications
            = new ArrayList<Application>();
@@ -2073,14 +2077,6 @@ public final class ActivityThread {
    boolean mSystemThread = false;
    boolean mJitEnabled = false;

    /**
     * Activities that are enqueued to be relaunched.  This list is accessed
     * by multiple threads, so you must synchronize on it when accessing it.
     */
    final ArrayList<ActivityRecord> mRelaunchingActivities
            = new ArrayList<ActivityRecord>();
    Configuration mPendingConfiguration = null;

    // These can be accessed by multiple threads; mPackages is the lock.
    // XXX For now we keep around information about all packages we have
    // seen, not removing entries from this map.
@@ -2092,6 +2088,9 @@ public final class ActivityThread {
    DisplayMetrics mDisplayMetrics = null;
    HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
        = new HashMap<ResourcesKey, WeakReference<Resources> >();
    final ArrayList<ActivityRecord> mRelaunchingActivities
            = new ArrayList<ActivityRecord>();
        Configuration mPendingConfiguration = null;

    // The lock of mProviderMap protects the following variables.
    final HashMap<String, ProviderRecord> mProviderMap
@@ -3555,7 +3554,7 @@ public final class ActivityThread {
        // First: make sure we have the most recent configuration and most
        // recent version of the activity, or skip it if some previous call
        // had taken a more recent version.
        synchronized (mRelaunchingActivities) {
        synchronized (mPackages) {
            int N = mRelaunchingActivities.size();
            IBinder token = tmp.token;
            tmp = null;
@@ -3585,10 +3584,14 @@ public final class ActivityThread {
            // assume that is really what we want regardless of what we
            // may have pending.
            if (mConfiguration == null
                    || mConfiguration.diff(tmp.createdConfig) != 0) {
                    || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
                            && mConfiguration.diff(tmp.createdConfig) != 0)) {
                if (changedConfig == null
                        || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
                    changedConfig = tmp.createdConfig;
                }
            }
        }
        
        if (DEBUG_CONFIGURATION) Log.v(TAG, "Relaunching activity "
                + tmp.token + ": changedConfig=" + changedConfig);
@@ -3761,26 +3764,14 @@ public final class ActivityThread {
        }
    }

    final void handleConfigurationChanged(Configuration config) {

        synchronized (mRelaunchingActivities) {
            if (mPendingConfiguration != null) {
                config = mPendingConfiguration;
                mPendingConfiguration = null;
            }
    final void applyConfigurationToResourcesLocked(Configuration config) {
        if (mResConfiguration == null) {
            mResConfiguration = new Configuration();
        }

        ArrayList<ComponentCallbacks> callbacks
                = new ArrayList<ComponentCallbacks>();

        if (DEBUG_CONFIGURATION) Log.v(TAG, "Handle configuration changed: "
                + config);
        
        synchronized(mPackages) {
            if (mConfiguration == null) {
                mConfiguration = new Configuration();
        if (!mResConfiguration.isOtherSeqNewer(config)) {
            return;
        }
            mConfiguration.updateFrom(config);
        mResConfiguration.updateFrom(config);
        DisplayMetrics dm = getDisplayMetricsLocked(true);

        // set it for java, this also affects newly created Resources
@@ -3792,7 +3783,7 @@ public final class ActivityThread {

        ContextImpl.ApplicationPackageManager.configurationChanged();
        //Log.i(TAG, "Configuration changed in " + currentPackageName());
            {
        
        Iterator<WeakReference<Resources>> it =
            mActiveResources.values().iterator();
        //Iterator<Map.Entry<String, WeakReference<Resources>>> it =
@@ -3811,14 +3802,45 @@ public final class ActivityThread {
        }
    }
    
    final void handleConfigurationChanged(Configuration config) {

        ArrayList<ComponentCallbacks> callbacks = null;

        synchronized (mPackages) {
            if (mPendingConfiguration != null) {
                if (!mPendingConfiguration.isOtherSeqNewer(config)) {
                    config = mPendingConfiguration;
                }
                mPendingConfiguration = null;
            }

            if (config == null) {
                return;
            }
            
            if (DEBUG_CONFIGURATION) Log.v(TAG, "Handle configuration changed: "
                    + config);
        
            applyConfigurationToResourcesLocked(config);
            
            if (mConfiguration == null) {
                mConfiguration = new Configuration();
            }
            if (!mConfiguration.isOtherSeqNewer(config)) {
                return;
            }
            mConfiguration.updateFrom(config);

            callbacks = collectComponentCallbacksLocked(false, config);
        }

        if (callbacks != null) {
            final int N = callbacks.size();
            for (int i=0; i<N; i++) {
                performConfigurationChanged(callbacks.get(i), config);
            }
        }
    }

    final void handleActivityConfigurationChanged(IBinder token) {
        ActivityRecord r = mActivities.get(token);
@@ -4348,6 +4370,25 @@ public final class ActivityThread {
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }
        
        ViewRoot.addConfigCallback(new ComponentCallbacks() {
            public void onConfigurationChanged(Configuration newConfig) {
                synchronized (mPackages) {
                    if (mPendingConfiguration == null ||
                            mPendingConfiguration.isOtherSeqNewer(newConfig)) {
                        mPendingConfiguration = newConfig;
                        
                        // We need to apply this change to the resources
                        // immediately, because upon returning the view
                        // hierarchy will be informed about it.
                        applyConfigurationToResourcesLocked(newConfig);
                    }
                }
                queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
            }
            public void onLowMemory() {
            }
        });
    }

    private final void detach()
+47 −1
Original line number Diff line number Diff line
@@ -192,6 +192,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration
     */
    public int uiMode;

    /**
     * @hide Internal book-keeping.
     */
    public int seq;
    
    /**
     * Construct an invalid Configuration.  You must call {@link #setToDefaults}
     * for this object to be valid.  {@more}
@@ -220,6 +225,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        orientation = o.orientation;
        screenLayout = o.screenLayout;
        uiMode = o.uiMode;
        seq = o.seq;
    }

    public String toString() {
@@ -250,6 +256,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        sb.append(screenLayout);
        sb.append(" uiMode=");
        sb.append(uiMode);
        if (seq != 0) {
            sb.append(" seq=");
            sb.append(seq);
        }
        sb.append('}');
        return sb.toString();
    }
@@ -260,7 +270,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
    public void setToDefaults() {
        fontScale = 1;
        mcc = mnc = 0;
        locale = Locale.getDefault();
        locale = null;
        userSetLocale = false;
        touchscreen = TOUCHSCREEN_UNDEFINED;
        keyboard = KEYBOARD_UNDEFINED;
@@ -271,6 +281,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        orientation = ORIENTATION_UNDEFINED;
        screenLayout = SCREENLAYOUT_SIZE_UNDEFINED;
        uiMode = UI_MODE_TYPE_NORMAL;
        seq = 0;
    }

    /** {@hide} */
@@ -357,6 +368,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
            uiMode = delta.uiMode;
        }
        
        if (delta.seq != 0) {
            seq = delta.seq;
        }
        
        return changed;
    }

@@ -455,6 +470,35 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0;
    }
    
    /**
     * @hide Return true if the sequence of 'other' is better than this.  Assumes
     * that 'this' is your current sequence and 'other' is a new one you have
     * received some how and want to compare with what you have.
     */
    public boolean isOtherSeqNewer(Configuration other) {
        if (other == null) {
            // Sanity check.
            return false;
        }
        if (other.seq == 0) {
            // If the other sequence is not specified, then we must assume
            // it is newer since we don't know any better.
            return true;
        }
        if (seq == 0) {
            // If this sequence is not specified, then we also consider the
            // other is better.  Yes we have a preference for other.  Sue us.
            return true;
        }
        int diff = other.seq - seq;
        if (diff > 0x10000) {
            // If there has been a sufficiently large jump, assume the
            // sequence has wrapped around.
            return false;
        }
        return diff > 0;
    }
    
    /**
     * Parcelable methods
     */
@@ -488,6 +532,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        dest.writeInt(orientation);
        dest.writeInt(screenLayout);
        dest.writeInt(uiMode);
        dest.writeInt(seq);
    }

    public static final Parcelable.Creator<Configuration> CREATOR
@@ -522,6 +567,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        orientation = source.readInt();
        screenLayout = source.readInt();
        uiMode = source.readInt();
        seq = source.readInt();
    }

    public int compareTo(Configuration that) {
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.view.Display;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.Locale;

/**
 * Class for accessing an application's resources.  This sits on top of the
@@ -1259,6 +1260,9 @@ public class Resources {
            if (config != null) {
                configChanges = mConfiguration.updateFrom(config);
            }
            if (mConfiguration.locale == null) {
                mConfiguration.locale = Locale.getDefault();
            }
            if (metrics != null) {
                mMetrics.setTo(metrics);
                mMetrics.updateMetrics(mCompatibilityInfo,
+2 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
@@ -226,7 +227,7 @@ public abstract class WallpaperService extends Service {
            
            @Override
            public void resized(int w, int h, Rect coveredInsets,
                    Rect visibleInsets, boolean reportDraw) {
                    Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
                Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
                        reportDraw ? 1 : 0);
                mCaller.sendMessage(msg);
Loading