Loading core/java/android/app/ContextImpl.java +4 −1 Original line number Diff line number Diff line Loading @@ -2721,10 +2721,13 @@ class ContextImpl extends Context { // need to override their display in ResourcesManager. baseContext.mForceDisplayOverrideInResources = false; baseContext.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT; baseContext.mDisplay = display; final Resources windowContextResources = createWindowContextResources(baseContext); baseContext.setResources(windowContextResources); // Associate the display with window context resources so that configuration update from // the server side will also apply to the display's metrics. baseContext.mDisplay = ResourcesManager.getInstance() .getAdjustedDisplay(display.getDisplayId(), windowContextResources); return baseContext; } Loading core/java/android/view/IWindowManager.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -814,9 +814,10 @@ interface IWindowManager * @param displayId The display associated with the window context * @param options A bundle used to pass window-related options and choose the right DisplayArea * * @return {@code true} if the WindowContext is attached to the DisplayArea successfully. * @return the DisplayArea's {@link android.app.res.Configuration} if the WindowContext is * attached to the DisplayArea successfully. {@code null}, otherwise. */ boolean attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId, Configuration attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId, in Bundle options); /** Loading core/java/android/window/WindowContext.java +1 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.content.Context; import android.content.ContextWrapper; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -73,7 +72,7 @@ public class WindowContext extends ContextWrapper { mType = type; mOptions = options; mWindowManager = createWindowContextWindowManager(this); IBinder token = getWindowContextToken(); WindowTokenClient token = (WindowTokenClient) getWindowContextToken(); mController = new WindowContextController(token); Reference.reachabilityFence(this); Loading core/java/android/window/WindowContextController.java +14 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.window; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; Loading Loading @@ -46,7 +47,7 @@ public class WindowContextController { @VisibleForTesting public boolean mAttachedToDisplayArea; @NonNull private final IBinder mToken; private final WindowTokenClient mToken; /** * Window Context Controller constructor Loading @@ -54,14 +55,13 @@ public class WindowContextController { * @param token The token used to attach to a window manager node. It is usually from * {@link Context#getWindowContextToken()}. */ public WindowContextController(@NonNull IBinder token) { mToken = token; mWms = WindowManagerGlobal.getWindowManagerService(); public WindowContextController(@NonNull WindowTokenClient token) { this(token, WindowManagerGlobal.getWindowManagerService()); } /** Used for test only. DO NOT USE it in production code. */ @VisibleForTesting public WindowContextController(@NonNull IBinder token, IWindowManager mockWms) { public WindowContextController(@NonNull WindowTokenClient token, IWindowManager mockWms) { mToken = token; mWms = mockWms; } Loading @@ -81,8 +81,15 @@ public class WindowContextController { + "a DisplayArea once."); } try { mAttachedToDisplayArea = mWms.attachWindowContextToDisplayArea(mToken, type, displayId, options); final Configuration configuration = mWms.attachWindowContextToDisplayArea(mToken, type, displayId, options); if (configuration != null) { mAttachedToDisplayArea = true; // Send the DisplayArea's configuration to WindowContext directly instead of // waiting for dispatching from WMS. mToken.onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading core/java/android/window/WindowTokenClient.java +41 −12 Original line number Diff line number Diff line Loading @@ -29,9 +29,12 @@ import android.content.res.Configuration; import android.inputmethodservice.AbstractInputMethodService; import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.IBinder; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import java.lang.ref.WeakReference; /** Loading Loading @@ -65,7 +68,7 @@ public class WindowTokenClient extends IWindowToken.Stub { * can only attach one {@link Context}. * <p>This method must be called before invoking * {@link android.view.IWindowManager#attachWindowContextToDisplayArea(IBinder, int, int, * Bundle, boolean)}.<p/> * Bundle)}.<p/> * * @param context context to be attached * @throws IllegalStateException if attached context has already existed. Loading @@ -80,8 +83,26 @@ public class WindowTokenClient extends IWindowToken.Stub { && context instanceof AbstractInputMethodService; } /** * Called when {@link Configuration} updates from the server side receive. * * @param newConfig the updated {@link Configuration} * @param newDisplayId the updated {@link android.view.Display} ID */ @Override public void onConfigurationChanged(Configuration newConfig, int newDisplayId) { onConfigurationChanged(newConfig, newDisplayId, true /* shouldReportConfigChange */); } /** * Called when {@link Configuration} updates from the server side receive. * * Similar to {@link #onConfigurationChanged(Configuration, int)}, but adds a flag to control * whether to dispatch configuration update or not. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void onConfigurationChanged(Configuration newConfig, int newDisplayId, boolean shouldReportConfigChange) { final Context context = mContextRef.get(); if (context == null) { return; Loading @@ -102,9 +123,10 @@ public class WindowTokenClient extends IWindowToken.Stub { // TODO(ag/9789103): update resource manager logic to track non-activity tokens mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId); if (context instanceof WindowContext) { if (shouldReportConfigChange && context instanceof WindowContext) { final WindowContext windowContext = (WindowContext) context; ActivityThread.currentActivityThread().getHandler().post( () -> ((WindowContext) context).dispatchConfigurationChanged(newConfig)); () -> windowContext.dispatchConfigurationChanged(newConfig)); } // Dispatch onConfigurationChanged only if there's a significant public change to Loading @@ -115,18 +137,25 @@ public class WindowTokenClient extends IWindowToken.Stub { ? new SizeConfigurationBuckets(sizeConfigurations) : null; final int diff = diffPublicWithSizeBuckets(mConfiguration, newConfig, buckets); if (context instanceof WindowProviderService && diff != 0) { ActivityThread.currentActivityThread().getHandler().post(() -> ((WindowProviderService) context).onConfigurationChanged(newConfig)); if (shouldReportConfigChange && diff != 0 && context instanceof WindowProviderService) { final WindowProviderService windowProviderService = (WindowProviderService) context; ActivityThread.currentActivityThread().getHandler().post( () -> windowProviderService.onConfigurationChanged(newConfig)); } freeTextLayoutCachesIfNeeded(diff); if (diff == 0 && mShouldDumpConfigForIme) { if (mShouldDumpConfigForIme) { if (!shouldReportConfigChange) { Log.d(TAG, "Only apply configuration update to Resources because " + "shouldReportConfigChange is false.\n" + Debug.getCallers(5)); } else if (diff == 0) { Log.d(TAG, "Configuration not dispatch to IME because configuration has no " + " public difference with updated config. " + " Current config=" + context.getResources().getConfiguration() + ", reported config=" + mConfiguration + ", updated config=" + newConfig); } } mConfiguration.setTo(newConfig); } if (displayChanged) { Loading Loading
core/java/android/app/ContextImpl.java +4 −1 Original line number Diff line number Diff line Loading @@ -2721,10 +2721,13 @@ class ContextImpl extends Context { // need to override their display in ResourcesManager. baseContext.mForceDisplayOverrideInResources = false; baseContext.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT; baseContext.mDisplay = display; final Resources windowContextResources = createWindowContextResources(baseContext); baseContext.setResources(windowContextResources); // Associate the display with window context resources so that configuration update from // the server side will also apply to the display's metrics. baseContext.mDisplay = ResourcesManager.getInstance() .getAdjustedDisplay(display.getDisplayId(), windowContextResources); return baseContext; } Loading
core/java/android/view/IWindowManager.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -814,9 +814,10 @@ interface IWindowManager * @param displayId The display associated with the window context * @param options A bundle used to pass window-related options and choose the right DisplayArea * * @return {@code true} if the WindowContext is attached to the DisplayArea successfully. * @return the DisplayArea's {@link android.app.res.Configuration} if the WindowContext is * attached to the DisplayArea successfully. {@code null}, otherwise. */ boolean attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId, Configuration attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId, in Bundle options); /** Loading
core/java/android/window/WindowContext.java +1 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.content.Context; import android.content.ContextWrapper; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -73,7 +72,7 @@ public class WindowContext extends ContextWrapper { mType = type; mOptions = options; mWindowManager = createWindowContextWindowManager(this); IBinder token = getWindowContextToken(); WindowTokenClient token = (WindowTokenClient) getWindowContextToken(); mController = new WindowContextController(token); Reference.reachabilityFence(this); Loading
core/java/android/window/WindowContextController.java +14 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.window; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; Loading Loading @@ -46,7 +47,7 @@ public class WindowContextController { @VisibleForTesting public boolean mAttachedToDisplayArea; @NonNull private final IBinder mToken; private final WindowTokenClient mToken; /** * Window Context Controller constructor Loading @@ -54,14 +55,13 @@ public class WindowContextController { * @param token The token used to attach to a window manager node. It is usually from * {@link Context#getWindowContextToken()}. */ public WindowContextController(@NonNull IBinder token) { mToken = token; mWms = WindowManagerGlobal.getWindowManagerService(); public WindowContextController(@NonNull WindowTokenClient token) { this(token, WindowManagerGlobal.getWindowManagerService()); } /** Used for test only. DO NOT USE it in production code. */ @VisibleForTesting public WindowContextController(@NonNull IBinder token, IWindowManager mockWms) { public WindowContextController(@NonNull WindowTokenClient token, IWindowManager mockWms) { mToken = token; mWms = mockWms; } Loading @@ -81,8 +81,15 @@ public class WindowContextController { + "a DisplayArea once."); } try { mAttachedToDisplayArea = mWms.attachWindowContextToDisplayArea(mToken, type, displayId, options); final Configuration configuration = mWms.attachWindowContextToDisplayArea(mToken, type, displayId, options); if (configuration != null) { mAttachedToDisplayArea = true; // Send the DisplayArea's configuration to WindowContext directly instead of // waiting for dispatching from WMS. mToken.onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading
core/java/android/window/WindowTokenClient.java +41 −12 Original line number Diff line number Diff line Loading @@ -29,9 +29,12 @@ import android.content.res.Configuration; import android.inputmethodservice.AbstractInputMethodService; import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.IBinder; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import java.lang.ref.WeakReference; /** Loading Loading @@ -65,7 +68,7 @@ public class WindowTokenClient extends IWindowToken.Stub { * can only attach one {@link Context}. * <p>This method must be called before invoking * {@link android.view.IWindowManager#attachWindowContextToDisplayArea(IBinder, int, int, * Bundle, boolean)}.<p/> * Bundle)}.<p/> * * @param context context to be attached * @throws IllegalStateException if attached context has already existed. Loading @@ -80,8 +83,26 @@ public class WindowTokenClient extends IWindowToken.Stub { && context instanceof AbstractInputMethodService; } /** * Called when {@link Configuration} updates from the server side receive. * * @param newConfig the updated {@link Configuration} * @param newDisplayId the updated {@link android.view.Display} ID */ @Override public void onConfigurationChanged(Configuration newConfig, int newDisplayId) { onConfigurationChanged(newConfig, newDisplayId, true /* shouldReportConfigChange */); } /** * Called when {@link Configuration} updates from the server side receive. * * Similar to {@link #onConfigurationChanged(Configuration, int)}, but adds a flag to control * whether to dispatch configuration update or not. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void onConfigurationChanged(Configuration newConfig, int newDisplayId, boolean shouldReportConfigChange) { final Context context = mContextRef.get(); if (context == null) { return; Loading @@ -102,9 +123,10 @@ public class WindowTokenClient extends IWindowToken.Stub { // TODO(ag/9789103): update resource manager logic to track non-activity tokens mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId); if (context instanceof WindowContext) { if (shouldReportConfigChange && context instanceof WindowContext) { final WindowContext windowContext = (WindowContext) context; ActivityThread.currentActivityThread().getHandler().post( () -> ((WindowContext) context).dispatchConfigurationChanged(newConfig)); () -> windowContext.dispatchConfigurationChanged(newConfig)); } // Dispatch onConfigurationChanged only if there's a significant public change to Loading @@ -115,18 +137,25 @@ public class WindowTokenClient extends IWindowToken.Stub { ? new SizeConfigurationBuckets(sizeConfigurations) : null; final int diff = diffPublicWithSizeBuckets(mConfiguration, newConfig, buckets); if (context instanceof WindowProviderService && diff != 0) { ActivityThread.currentActivityThread().getHandler().post(() -> ((WindowProviderService) context).onConfigurationChanged(newConfig)); if (shouldReportConfigChange && diff != 0 && context instanceof WindowProviderService) { final WindowProviderService windowProviderService = (WindowProviderService) context; ActivityThread.currentActivityThread().getHandler().post( () -> windowProviderService.onConfigurationChanged(newConfig)); } freeTextLayoutCachesIfNeeded(diff); if (diff == 0 && mShouldDumpConfigForIme) { if (mShouldDumpConfigForIme) { if (!shouldReportConfigChange) { Log.d(TAG, "Only apply configuration update to Resources because " + "shouldReportConfigChange is false.\n" + Debug.getCallers(5)); } else if (diff == 0) { Log.d(TAG, "Configuration not dispatch to IME because configuration has no " + " public difference with updated config. " + " Current config=" + context.getResources().getConfiguration() + ", reported config=" + mConfiguration + ", updated config=" + newConfig); } } mConfiguration.setTo(newConfig); } if (displayChanged) { Loading