diff options
3 files changed, 70 insertions, 12 deletions
diff --git a/core/java/android/window/WindowProvider.java b/core/java/android/window/WindowProvider.java index b078b9362b90..dbdc68fbfd44 100644 --- a/core/java/android/window/WindowProvider.java +++ b/core/java/android/window/WindowProvider.java @@ -15,8 +15,10 @@ */ package android.window; +import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; +import android.os.IBinder; import android.view.WindowManager.LayoutParams.WindowType; /** @@ -36,4 +38,11 @@ public interface WindowProvider { /** Gets the launch options of this provider */ @Nullable Bundle getWindowContextOptions(); + + /** + * Gets the WindowContextToken of this provider. + * @see android.content.Context#getWindowContextToken + */ + @NonNull + IBinder getWindowContextToken(); } diff --git a/core/java/android/window/WindowProviderService.java b/core/java/android/window/WindowProviderService.java index 2d2c8de72646..fdc3e5af8d8b 100644 --- a/core/java/android/window/WindowProviderService.java +++ b/core/java/android/window/WindowProviderService.java @@ -27,7 +27,10 @@ import android.annotation.UiContext; import android.app.ActivityThread; import android.app.LoadedApk; import android.app.Service; +import android.content.ComponentCallbacks; +import android.content.ComponentCallbacksController; import android.content.Context; +import android.content.res.Configuration; import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.IBinder; @@ -54,6 +57,8 @@ public abstract class WindowProviderService extends Service implements WindowPro private final WindowContextController mController = new WindowContextController(mWindowToken); private WindowManager mWindowManager; private boolean mInitialized; + private final ComponentCallbacksController mCallbacksController = + new ComponentCallbacksController(); /** * Returns {@code true} if the {@code windowContextOptions} declares that it is a @@ -118,6 +123,48 @@ public abstract class WindowProviderService extends Service implements WindowPro return mOptions; } + @SuppressLint({"OnNameExpected", "ExecutorRegistration"}) + // Suppress lint because this is a legacy named function and doesn't have an optional param + // for executor. + // TODO(b/259347943): Update documentation for U. + /** + * Here we override to prevent WindowProviderService from invoking + * {@link Application.registerComponentCallback}, which will result in callback registered + * for process-level Configuration change updates. + */ + @Override + public void registerComponentCallbacks(@NonNull ComponentCallbacks callback) { + // For broadcasting Configuration Changes. + mCallbacksController.registerCallbacks(callback); + } + + @SuppressLint("OnNameExpected") + @Override + public void unregisterComponentCallbacks(@NonNull ComponentCallbacks callback) { + mCallbacksController.unregisterCallbacks(callback); + } + + @SuppressLint("OnNameExpected") + @Override + public void onConfigurationChanged(@Nullable Configuration configuration) { + // This is only called from WindowTokenClient. + mCallbacksController.dispatchConfigurationChanged(configuration); + } + + /** + * Override {@link Service}'s empty implementation and listen to {@link ActivityThread} for + * low memory and trim memory events. + */ + @Override + public void onLowMemory() { + mCallbacksController.dispatchLowMemory(); + } + + @Override + public void onTrimMemory(int level) { + mCallbacksController.dispatchTrimMemory(level); + } + /** * Returns the display ID to launch this {@link WindowProviderService}. * @@ -181,5 +228,6 @@ public abstract class WindowProviderService extends Service implements WindowPro public void onDestroy() { super.onDestroy(); mController.detachIfNeeded(); + mCallbacksController.clearCallbacks(); } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java index b516e1407b11..2192b5ca219c 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java @@ -36,6 +36,7 @@ import android.os.Bundle; import android.os.IBinder; import android.util.ArrayMap; import android.window.WindowContext; +import android.window.WindowProvider; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -71,7 +72,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { private final List<CommonFoldingFeature> mLastReportedFoldingFeatures = new ArrayList<>(); - private final Map<IBinder, WindowContextConfigListener> mWindowContextConfigListeners = + private final Map<IBinder, ConfigurationChangeListener> mConfigurationChangeListeners = new ArrayMap<>(); public WindowLayoutComponentImpl(@NonNull Context context) { @@ -121,21 +122,21 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } if (!context.isUiContext()) { throw new IllegalArgumentException("Context must be a UI Context, which should be" - + " an Activity or a WindowContext"); + + " an Activity, WindowContext or InputMethodService"); } mFoldingFeatureProducer.getData((features) -> { - // Get the WindowLayoutInfo from the activity and pass the value to the layoutConsumer. WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(context, features); consumer.accept(newWindowLayout); }); mWindowLayoutChangeListeners.put(context, consumer); - if (context instanceof WindowContext) { + // TODO(b/258065175) Further extend this to ContextWrappers. + if (context instanceof WindowProvider) { final IBinder windowContextToken = context.getWindowContextToken(); - final WindowContextConfigListener listener = - new WindowContextConfigListener(windowContextToken); + final ConfigurationChangeListener listener = + new ConfigurationChangeListener(windowContextToken); context.registerComponentCallbacks(listener); - mWindowContextConfigListeners.put(windowContextToken, listener); + mConfigurationChangeListeners.put(windowContextToken, listener); } } @@ -150,10 +151,10 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { if (!mWindowLayoutChangeListeners.get(context).equals(consumer)) { continue; } - if (context instanceof WindowContext) { + if (context instanceof WindowProvider) { final IBinder token = context.getWindowContextToken(); - context.unregisterComponentCallbacks(mWindowContextConfigListeners.get(token)); - mWindowContextConfigListeners.remove(token); + context.unregisterComponentCallbacks(mConfigurationChangeListeners.get(token)); + mConfigurationChangeListeners.remove(token); } break; } @@ -349,10 +350,10 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } } - private final class WindowContextConfigListener implements ComponentCallbacks { + private final class ConfigurationChangeListener implements ComponentCallbacks { final IBinder mToken; - WindowContextConfigListener(IBinder token) { + ConfigurationChangeListener(IBinder token) { mToken = token; } |