Loading core/api/test-current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -3172,5 +3172,12 @@ package android.window { method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void applyTransaction(@NonNull android.window.WindowContainerTransaction); } @UiContext public abstract class WindowProviderService extends android.app.Service { ctor public WindowProviderService(); method public final void attachToWindowToken(@NonNull android.os.IBinder); method @Nullable public android.os.Bundle getWindowContextOptions(); method public abstract int getWindowType(); } } core/java/android/app/ActivityThread.java +2 −1 Original line number Diff line number Diff line Loading @@ -4390,11 +4390,12 @@ public final class ActivityThread extends ClientTransactionHandler try { if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); ContextImpl context = ContextImpl.createAppContext(this, packageInfo); Application app = packageInfo.makeApplication(false, mInstrumentation); java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); final ContextImpl context = ContextImpl.getImpl(service .createServiceBaseContext(this, packageInfo)); // Service resources must be initialized with the same loaders as the application // context. context.getResources().addLoaders( Loading core/java/android/app/Service.java +13 −0 Original line number Diff line number Diff line Loading @@ -860,6 +860,19 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac setContentCaptureOptions(application.getContentCaptureOptions()); } /** * Creates the base {@link Context} of this {@link Service}. * Users may override this API to create customized base context. * * @see android.window.WindowProviderService WindowProviderService class for example * @see ContextWrapper#attachBaseContext(Context) * * @hide */ public Context createServiceBaseContext(ActivityThread mainThread, LoadedApk packageInfo) { return ContextImpl.createAppContext(mainThread, packageInfo); } /** * @hide * Clean up any references to avoid leaks. Loading core/java/android/window/WindowContextController.java +1 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ public class WindowContextController { * a {@link com.android.server.wm.DisplayArea} by * {@link #attachToDisplayArea(int, int, Bundle)}. * * @see WindowProviderService#attachToWindowToken(IBinder)) * @see IWindowManager#attachWindowContextToWindowToken(IBinder, IBinder) */ public void attachToWindowToken(IBinder windowToken) { Loading core/java/android/window/WindowProviderService.java 0 → 100644 +138 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.window; import static android.view.Display.DEFAULT_DISPLAY; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.TestApi; import android.annotation.UiContext; import android.app.ActivityThread; import android.app.LoadedApk; import android.app.Service; import android.content.Context; import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.IBinder; import android.view.Display; import android.view.WindowManager; import android.view.WindowManager.LayoutParams.WindowType; import android.view.WindowManagerImpl; // TODO(b/159767464): handle #onConfigurationChanged(Configuration) /** * A {@link Service} responsible for showing a non-activity window, such as software keyboards or * accessibility overlay windows. This {@link Service} has similar behavior to * {@link WindowContext}, but is represented as {@link Service}. * * @see android.inputmethodservice.InputMethodService * @see android.accessibilityservice.AccessibilityService * * @hide */ @TestApi @UiContext public abstract class WindowProviderService extends Service { private final WindowTokenClient mWindowToken = new WindowTokenClient(); private final WindowContextController mController = new WindowContextController(mWindowToken); private WindowManager mWindowManager; /** * Returns the type of this {@link WindowProviderService}. * Each inheriting class must implement this method to provide the type of the window. It is * used similar to {@code type} of {@link Context#createWindowContext(int, Bundle)} * * @see Context#createWindowContext(int, Bundle) * * @hide */ @TestApi @SuppressLint("OnNameExpected") // Suppress the lint because it is not a callback and users should provide window type // so we cannot make it final. public abstract @WindowType int getWindowType(); /** * Returns the option of this {@link WindowProviderService}. * Default is {@code null}. The inheriting class can implement this method to provide the * customization {@code option} of the window. It is used similar to {@code options} of * {@link Context#createWindowContext(int, Bundle)} * * @see Context#createWindowContext(int, Bundle) * * @hide */ @TestApi @SuppressLint({"OnNameExpected", "NullableCollection"}) // Suppress the lint because it is not a callback and users may override this API to provide // launch option. Also, the return value of this API is null by default. @Nullable public Bundle getWindowContextOptions() { return null; } /** * Attaches this WindowProviderService to the {@code windowToken}. * * @hide */ @TestApi public final void attachToWindowToken(@NonNull IBinder windowToken) { mController.attachToWindowToken(windowToken); } /** @hide */ @Override public final Context createServiceBaseContext(ActivityThread mainThread, LoadedApk packageInfo) { final Context context = super.createServiceBaseContext(mainThread, packageInfo); // Always associate with the default display at initialization. final Display defaultDisplay = context.getSystemService(DisplayManager.class) .getDisplay(DEFAULT_DISPLAY); return context.createTokenContext(mWindowToken, defaultDisplay); } @CallSuper @Override public void onCreate() { super.onCreate(); mWindowToken.attachContext(this); mController.attachToDisplayArea(getWindowType(), getDisplayId(), getWindowContextOptions()); mWindowManager = WindowManagerImpl.createWindowContextWindowManager(this); } @SuppressLint("OnNameExpected") @Override // Suppress the lint because ths is overridden from Context. public @Nullable Object getSystemService(@NonNull String name) { if (WINDOW_SERVICE.equals(name)) { return mWindowManager; } return super.getSystemService(name); } @CallSuper @Override public void onDestroy() { super.onDestroy(); mController.detachIfNeeded(); } } Loading
core/api/test-current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -3172,5 +3172,12 @@ package android.window { method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void applyTransaction(@NonNull android.window.WindowContainerTransaction); } @UiContext public abstract class WindowProviderService extends android.app.Service { ctor public WindowProviderService(); method public final void attachToWindowToken(@NonNull android.os.IBinder); method @Nullable public android.os.Bundle getWindowContextOptions(); method public abstract int getWindowType(); } }
core/java/android/app/ActivityThread.java +2 −1 Original line number Diff line number Diff line Loading @@ -4390,11 +4390,12 @@ public final class ActivityThread extends ClientTransactionHandler try { if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); ContextImpl context = ContextImpl.createAppContext(this, packageInfo); Application app = packageInfo.makeApplication(false, mInstrumentation); java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); final ContextImpl context = ContextImpl.getImpl(service .createServiceBaseContext(this, packageInfo)); // Service resources must be initialized with the same loaders as the application // context. context.getResources().addLoaders( Loading
core/java/android/app/Service.java +13 −0 Original line number Diff line number Diff line Loading @@ -860,6 +860,19 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac setContentCaptureOptions(application.getContentCaptureOptions()); } /** * Creates the base {@link Context} of this {@link Service}. * Users may override this API to create customized base context. * * @see android.window.WindowProviderService WindowProviderService class for example * @see ContextWrapper#attachBaseContext(Context) * * @hide */ public Context createServiceBaseContext(ActivityThread mainThread, LoadedApk packageInfo) { return ContextImpl.createAppContext(mainThread, packageInfo); } /** * @hide * Clean up any references to avoid leaks. Loading
core/java/android/window/WindowContextController.java +1 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ public class WindowContextController { * a {@link com.android.server.wm.DisplayArea} by * {@link #attachToDisplayArea(int, int, Bundle)}. * * @see WindowProviderService#attachToWindowToken(IBinder)) * @see IWindowManager#attachWindowContextToWindowToken(IBinder, IBinder) */ public void attachToWindowToken(IBinder windowToken) { Loading
core/java/android/window/WindowProviderService.java 0 → 100644 +138 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.window; import static android.view.Display.DEFAULT_DISPLAY; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.TestApi; import android.annotation.UiContext; import android.app.ActivityThread; import android.app.LoadedApk; import android.app.Service; import android.content.Context; import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.IBinder; import android.view.Display; import android.view.WindowManager; import android.view.WindowManager.LayoutParams.WindowType; import android.view.WindowManagerImpl; // TODO(b/159767464): handle #onConfigurationChanged(Configuration) /** * A {@link Service} responsible for showing a non-activity window, such as software keyboards or * accessibility overlay windows. This {@link Service} has similar behavior to * {@link WindowContext}, but is represented as {@link Service}. * * @see android.inputmethodservice.InputMethodService * @see android.accessibilityservice.AccessibilityService * * @hide */ @TestApi @UiContext public abstract class WindowProviderService extends Service { private final WindowTokenClient mWindowToken = new WindowTokenClient(); private final WindowContextController mController = new WindowContextController(mWindowToken); private WindowManager mWindowManager; /** * Returns the type of this {@link WindowProviderService}. * Each inheriting class must implement this method to provide the type of the window. It is * used similar to {@code type} of {@link Context#createWindowContext(int, Bundle)} * * @see Context#createWindowContext(int, Bundle) * * @hide */ @TestApi @SuppressLint("OnNameExpected") // Suppress the lint because it is not a callback and users should provide window type // so we cannot make it final. public abstract @WindowType int getWindowType(); /** * Returns the option of this {@link WindowProviderService}. * Default is {@code null}. The inheriting class can implement this method to provide the * customization {@code option} of the window. It is used similar to {@code options} of * {@link Context#createWindowContext(int, Bundle)} * * @see Context#createWindowContext(int, Bundle) * * @hide */ @TestApi @SuppressLint({"OnNameExpected", "NullableCollection"}) // Suppress the lint because it is not a callback and users may override this API to provide // launch option. Also, the return value of this API is null by default. @Nullable public Bundle getWindowContextOptions() { return null; } /** * Attaches this WindowProviderService to the {@code windowToken}. * * @hide */ @TestApi public final void attachToWindowToken(@NonNull IBinder windowToken) { mController.attachToWindowToken(windowToken); } /** @hide */ @Override public final Context createServiceBaseContext(ActivityThread mainThread, LoadedApk packageInfo) { final Context context = super.createServiceBaseContext(mainThread, packageInfo); // Always associate with the default display at initialization. final Display defaultDisplay = context.getSystemService(DisplayManager.class) .getDisplay(DEFAULT_DISPLAY); return context.createTokenContext(mWindowToken, defaultDisplay); } @CallSuper @Override public void onCreate() { super.onCreate(); mWindowToken.attachContext(this); mController.attachToDisplayArea(getWindowType(), getDisplayId(), getWindowContextOptions()); mWindowManager = WindowManagerImpl.createWindowContextWindowManager(this); } @SuppressLint("OnNameExpected") @Override // Suppress the lint because ths is overridden from Context. public @Nullable Object getSystemService(@NonNull String name) { if (WINDOW_SERVICE.equals(name)) { return mWindowManager; } return super.getSystemService(name); } @CallSuper @Override public void onDestroy() { super.onDestroy(); mController.detachIfNeeded(); } }