Loading core/java/android/window/WindowProviderService.java +3 −2 Original line number Diff line number Diff line Loading @@ -165,10 +165,11 @@ public abstract class WindowProviderService extends Service implements WindowPro } } // Suppress the lint because ths is overridden from Context. @SuppressLint("OnNameExpected") @Override // Suppress the lint because ths is overridden from Context. public @Nullable Object getSystemService(@NonNull String name) { @Nullable public Object getSystemService(@NonNull String name) { if (WINDOW_SERVICE.equals(name)) { return mWindowManager; } Loading core/java/android/window/WindowTokenClient.java +35 −14 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded; import static android.window.ConfigurationHelper.isDifferentDisplay; import static android.window.ConfigurationHelper.shouldUpdateResources; import android.annotation.AnyThread; import android.annotation.BinderThread; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.IWindowToken; Loading @@ -40,6 +40,7 @@ import android.view.IWindowManager; import android.view.WindowManager.LayoutParams.WindowType; import android.view.WindowManagerGlobal; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.lang.ref.WeakReference; Loading Loading @@ -68,6 +69,7 @@ public class WindowTokenClient extends IWindowToken.Stub { private IWindowManager mWms; @GuardedBy("itself") private final Configuration mConfiguration = new Configuration(); private boolean mShouldDumpConfigForIme; Loading @@ -91,7 +93,6 @@ public class WindowTokenClient extends IWindowToken.Stub { throw new IllegalStateException("Context is already attached."); } mContextRef = new WeakReference<>(context); mConfiguration.setTo(context.getResources().getConfiguration()); mShouldDumpConfigForIme = Build.IS_DEBUGGABLE && context instanceof AbstractInputMethodService; } Loading Loading @@ -137,8 +138,7 @@ public class WindowTokenClient extends IWindowToken.Stub { if (configuration == null) { return false; } mHandler.post(() -> onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */)); onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */); mAttachToWindowContainer = true; return true; } catch (RemoteException e) { Loading Loading @@ -199,8 +199,19 @@ public class WindowTokenClient extends IWindowToken.Stub { * * Similar to {@link #onConfigurationChanged(Configuration, int)}, but adds a flag to control * whether to dispatch configuration update or not. * <p> * Note that this method must be executed on the main thread if * {@code shouldReportConfigChange} is {@code true}, which is usually from * {@link IWindowToken#onConfigurationChanged(Configuration, int)} * directly, while this method could be run on any thread if it is used to initialize * Context's {@code Configuration} via {@link #attachToDisplayArea(int, int, Bundle)} * or {@link #attachToDisplayContent(int)}. * * @param shouldReportConfigChange {@code true} to indicate that the {@code Configuration} * should be dispatched to listeners. * */ @MainThread @AnyThread @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void onConfigurationChanged(Configuration newConfig, int newDisplayId, boolean shouldReportConfigChange) { Loading @@ -208,18 +219,29 @@ public class WindowTokenClient extends IWindowToken.Stub { if (context == null) { return; } final boolean displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId); final boolean shouldUpdateResources = shouldUpdateResources(this, mConfiguration, final boolean displayChanged; final boolean shouldUpdateResources; final int diff; final Configuration currentConfig; synchronized (mConfiguration) { displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId); shouldUpdateResources = shouldUpdateResources(this, mConfiguration, newConfig, newConfig /* overrideConfig */, displayChanged, null /* configChanged */); diff = mConfiguration.diffPublicOnly(newConfig); currentConfig = mShouldDumpConfigForIme ? new Configuration(mConfiguration) : null; if (shouldUpdateResources) { mConfiguration.setTo(newConfig); } } if (!shouldUpdateResources && mShouldDumpConfigForIme) { Log.d(TAG, "Configuration not dispatch to IME because configuration is up" + " to date. Current config=" + context.getResources().getConfiguration() + ", reported config=" + mConfiguration + ", reported config=" + currentConfig + ", updated config=" + newConfig); } if (shouldUpdateResources) { // TODO(ag/9789103): update resource manager logic to track non-activity tokens mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId); Loading @@ -229,7 +251,7 @@ public class WindowTokenClient extends IWindowToken.Stub { windowContext.dispatchConfigurationChanged(newConfig); } final int diff = mConfiguration.diffPublicOnly(newConfig); if (shouldReportConfigChange && diff != 0 && context instanceof WindowProviderService) { final WindowProviderService windowProviderService = (WindowProviderService) context; Loading @@ -244,11 +266,10 @@ public class WindowTokenClient extends IWindowToken.Stub { 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 + ", reported config=" + currentConfig + ", updated config=" + newConfig); } } mConfiguration.setTo(newConfig); } if (displayChanged) { context.updateDisplay(newDisplayId); Loading services/core/java/com/android/server/wm/ConfigurationContainer.java +9 −2 Original line number Diff line number Diff line Loading @@ -637,13 +637,20 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { } void registerConfigurationChangeListener(ConfigurationContainerListener listener) { registerConfigurationChangeListener(listener, true /* shouldDispatchConfig */); } void registerConfigurationChangeListener(ConfigurationContainerListener listener, boolean shouldDispatchConfig) { if (mChangeListeners.contains(listener)) { return; } mChangeListeners.add(listener); if (shouldDispatchConfig) { listener.onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration); listener.onMergedOverrideConfigurationChanged(mMergedOverrideConfiguration); } } void unregisterConfigurationChangeListener(ConfigurationContainerListener listener) { mChangeListeners.remove(listener); Loading services/core/java/com/android/server/wm/WindowContainer.java +9 −2 Original line number Diff line number Diff line Loading @@ -3747,14 +3747,21 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } void registerWindowContainerListener(WindowContainerListener listener) { registerWindowContainerListener(listener, true /* shouldPropConfig */); } void registerWindowContainerListener(WindowContainerListener listener, boolean shouldDispatchConfig) { if (mListeners.contains(listener)) { return; } mListeners.add(listener); // Also register to ConfigurationChangeListener to receive configuration changes. registerConfigurationChangeListener(listener); registerConfigurationChangeListener(listener, shouldDispatchConfig); if (shouldDispatchConfig) { listener.onDisplayChanged(getDisplayContent()); } } void unregisterWindowContainerListener(WindowContainerListener listener) { mListeners.remove(listener); Loading services/core/java/com/android/server/wm/WindowContextListenerController.java +20 −3 Original line number Diff line number Diff line Loading @@ -68,6 +68,16 @@ class WindowContextListenerController { @VisibleForTesting final ArrayMap<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>(); /** * @see #registerWindowContainerListener(IBinder, WindowContainer, int, int, Bundle, boolean) */ void registerWindowContainerListener(@NonNull IBinder clientToken, @NonNull WindowContainer<?> container, int ownerUid, @WindowType int type, @Nullable Bundle options) { registerWindowContainerListener(clientToken, container, ownerUid, type, options, true /* shouDispatchConfigWhenRegistering */); } /** * Registers the listener to a {@code container} which is associated with * a {@code clientToken}, which is a {@link android.window.WindowContext} representation. If the Loading @@ -80,15 +90,18 @@ class WindowContextListenerController { * @param ownerUid the caller UID * @param type the window type * @param options a bundle used to pass window-related options. * @param shouDispatchConfigWhenRegistering {@code true} to indicate the current * {@code container}'s config will dispatch to the client side when * registering the {@link WindowContextListenerImpl} */ void registerWindowContainerListener(@NonNull IBinder clientToken, @NonNull WindowContainer<?> container, int ownerUid, @WindowType int type, @Nullable Bundle options) { @Nullable Bundle options, boolean shouDispatchConfigWhenRegistering) { WindowContextListenerImpl listener = mListeners.get(clientToken); if (listener == null) { listener = new WindowContextListenerImpl(clientToken, container, ownerUid, type, options); listener.register(); listener.register(shouDispatchConfigWhenRegistering); } else { listener.updateContainer(container); } Loading Loading @@ -228,12 +241,16 @@ class WindowContextListenerController { } private void register() { register(true /* shouldDispatchConfig */); } private void register(boolean shouldDispatchConfig) { final IBinder token = mClientToken.asBinder(); if (mDeathRecipient == null) { throw new IllegalStateException("Invalid client token: " + token); } mListeners.putIfAbsent(token, this); mContainer.registerWindowContainerListener(this); mContainer.registerWindowContainerListener(this, shouldDispatchConfig); } private void unregister() { Loading Loading
core/java/android/window/WindowProviderService.java +3 −2 Original line number Diff line number Diff line Loading @@ -165,10 +165,11 @@ public abstract class WindowProviderService extends Service implements WindowPro } } // Suppress the lint because ths is overridden from Context. @SuppressLint("OnNameExpected") @Override // Suppress the lint because ths is overridden from Context. public @Nullable Object getSystemService(@NonNull String name) { @Nullable public Object getSystemService(@NonNull String name) { if (WINDOW_SERVICE.equals(name)) { return mWindowManager; } Loading
core/java/android/window/WindowTokenClient.java +35 −14 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded; import static android.window.ConfigurationHelper.isDifferentDisplay; import static android.window.ConfigurationHelper.shouldUpdateResources; import android.annotation.AnyThread; import android.annotation.BinderThread; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.IWindowToken; Loading @@ -40,6 +40,7 @@ import android.view.IWindowManager; import android.view.WindowManager.LayoutParams.WindowType; import android.view.WindowManagerGlobal; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.lang.ref.WeakReference; Loading Loading @@ -68,6 +69,7 @@ public class WindowTokenClient extends IWindowToken.Stub { private IWindowManager mWms; @GuardedBy("itself") private final Configuration mConfiguration = new Configuration(); private boolean mShouldDumpConfigForIme; Loading @@ -91,7 +93,6 @@ public class WindowTokenClient extends IWindowToken.Stub { throw new IllegalStateException("Context is already attached."); } mContextRef = new WeakReference<>(context); mConfiguration.setTo(context.getResources().getConfiguration()); mShouldDumpConfigForIme = Build.IS_DEBUGGABLE && context instanceof AbstractInputMethodService; } Loading Loading @@ -137,8 +138,7 @@ public class WindowTokenClient extends IWindowToken.Stub { if (configuration == null) { return false; } mHandler.post(() -> onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */)); onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */); mAttachToWindowContainer = true; return true; } catch (RemoteException e) { Loading Loading @@ -199,8 +199,19 @@ public class WindowTokenClient extends IWindowToken.Stub { * * Similar to {@link #onConfigurationChanged(Configuration, int)}, but adds a flag to control * whether to dispatch configuration update or not. * <p> * Note that this method must be executed on the main thread if * {@code shouldReportConfigChange} is {@code true}, which is usually from * {@link IWindowToken#onConfigurationChanged(Configuration, int)} * directly, while this method could be run on any thread if it is used to initialize * Context's {@code Configuration} via {@link #attachToDisplayArea(int, int, Bundle)} * or {@link #attachToDisplayContent(int)}. * * @param shouldReportConfigChange {@code true} to indicate that the {@code Configuration} * should be dispatched to listeners. * */ @MainThread @AnyThread @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void onConfigurationChanged(Configuration newConfig, int newDisplayId, boolean shouldReportConfigChange) { Loading @@ -208,18 +219,29 @@ public class WindowTokenClient extends IWindowToken.Stub { if (context == null) { return; } final boolean displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId); final boolean shouldUpdateResources = shouldUpdateResources(this, mConfiguration, final boolean displayChanged; final boolean shouldUpdateResources; final int diff; final Configuration currentConfig; synchronized (mConfiguration) { displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId); shouldUpdateResources = shouldUpdateResources(this, mConfiguration, newConfig, newConfig /* overrideConfig */, displayChanged, null /* configChanged */); diff = mConfiguration.diffPublicOnly(newConfig); currentConfig = mShouldDumpConfigForIme ? new Configuration(mConfiguration) : null; if (shouldUpdateResources) { mConfiguration.setTo(newConfig); } } if (!shouldUpdateResources && mShouldDumpConfigForIme) { Log.d(TAG, "Configuration not dispatch to IME because configuration is up" + " to date. Current config=" + context.getResources().getConfiguration() + ", reported config=" + mConfiguration + ", reported config=" + currentConfig + ", updated config=" + newConfig); } if (shouldUpdateResources) { // TODO(ag/9789103): update resource manager logic to track non-activity tokens mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId); Loading @@ -229,7 +251,7 @@ public class WindowTokenClient extends IWindowToken.Stub { windowContext.dispatchConfigurationChanged(newConfig); } final int diff = mConfiguration.diffPublicOnly(newConfig); if (shouldReportConfigChange && diff != 0 && context instanceof WindowProviderService) { final WindowProviderService windowProviderService = (WindowProviderService) context; Loading @@ -244,11 +266,10 @@ public class WindowTokenClient extends IWindowToken.Stub { 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 + ", reported config=" + currentConfig + ", updated config=" + newConfig); } } mConfiguration.setTo(newConfig); } if (displayChanged) { context.updateDisplay(newDisplayId); Loading
services/core/java/com/android/server/wm/ConfigurationContainer.java +9 −2 Original line number Diff line number Diff line Loading @@ -637,13 +637,20 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { } void registerConfigurationChangeListener(ConfigurationContainerListener listener) { registerConfigurationChangeListener(listener, true /* shouldDispatchConfig */); } void registerConfigurationChangeListener(ConfigurationContainerListener listener, boolean shouldDispatchConfig) { if (mChangeListeners.contains(listener)) { return; } mChangeListeners.add(listener); if (shouldDispatchConfig) { listener.onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration); listener.onMergedOverrideConfigurationChanged(mMergedOverrideConfiguration); } } void unregisterConfigurationChangeListener(ConfigurationContainerListener listener) { mChangeListeners.remove(listener); Loading
services/core/java/com/android/server/wm/WindowContainer.java +9 −2 Original line number Diff line number Diff line Loading @@ -3747,14 +3747,21 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } void registerWindowContainerListener(WindowContainerListener listener) { registerWindowContainerListener(listener, true /* shouldPropConfig */); } void registerWindowContainerListener(WindowContainerListener listener, boolean shouldDispatchConfig) { if (mListeners.contains(listener)) { return; } mListeners.add(listener); // Also register to ConfigurationChangeListener to receive configuration changes. registerConfigurationChangeListener(listener); registerConfigurationChangeListener(listener, shouldDispatchConfig); if (shouldDispatchConfig) { listener.onDisplayChanged(getDisplayContent()); } } void unregisterWindowContainerListener(WindowContainerListener listener) { mListeners.remove(listener); Loading
services/core/java/com/android/server/wm/WindowContextListenerController.java +20 −3 Original line number Diff line number Diff line Loading @@ -68,6 +68,16 @@ class WindowContextListenerController { @VisibleForTesting final ArrayMap<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>(); /** * @see #registerWindowContainerListener(IBinder, WindowContainer, int, int, Bundle, boolean) */ void registerWindowContainerListener(@NonNull IBinder clientToken, @NonNull WindowContainer<?> container, int ownerUid, @WindowType int type, @Nullable Bundle options) { registerWindowContainerListener(clientToken, container, ownerUid, type, options, true /* shouDispatchConfigWhenRegistering */); } /** * Registers the listener to a {@code container} which is associated with * a {@code clientToken}, which is a {@link android.window.WindowContext} representation. If the Loading @@ -80,15 +90,18 @@ class WindowContextListenerController { * @param ownerUid the caller UID * @param type the window type * @param options a bundle used to pass window-related options. * @param shouDispatchConfigWhenRegistering {@code true} to indicate the current * {@code container}'s config will dispatch to the client side when * registering the {@link WindowContextListenerImpl} */ void registerWindowContainerListener(@NonNull IBinder clientToken, @NonNull WindowContainer<?> container, int ownerUid, @WindowType int type, @Nullable Bundle options) { @Nullable Bundle options, boolean shouDispatchConfigWhenRegistering) { WindowContextListenerImpl listener = mListeners.get(clientToken); if (listener == null) { listener = new WindowContextListenerImpl(clientToken, container, ownerUid, type, options); listener.register(); listener.register(shouDispatchConfigWhenRegistering); } else { listener.updateContainer(container); } Loading Loading @@ -228,12 +241,16 @@ class WindowContextListenerController { } private void register() { register(true /* shouldDispatchConfig */); } private void register(boolean shouldDispatchConfig) { final IBinder token = mClientToken.asBinder(); if (mDeathRecipient == null) { throw new IllegalStateException("Invalid client token: " + token); } mListeners.putIfAbsent(token, this); mContainer.registerWindowContainerListener(this); mContainer.registerWindowContainerListener(this, shouldDispatchConfig); } private void unregister() { Loading