summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ActivityThread.java3
-rw-r--r--core/java/android/app/Service.java13
-rw-r--r--core/java/android/window/WindowContextController.java1
-rw-r--r--core/java/android/window/WindowProviderService.java138
4 files changed, 154 insertions, 1 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 35890c811428..b0235b031e03 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4385,11 +4385,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(
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 2ceea7f1a6a8..0ab3f2f4be46 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -861,6 +861,19 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
}
/**
+ * 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.
*/
diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java
index 88584f4b2571..d84f571931fd 100644
--- a/core/java/android/window/WindowContextController.java
+++ b/core/java/android/window/WindowContextController.java
@@ -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) {
diff --git a/core/java/android/window/WindowProviderService.java b/core/java/android/window/WindowProviderService.java
new file mode 100644
index 000000000000..b8619fbcf334
--- /dev/null
+++ b/core/java/android/window/WindowProviderService.java
@@ -0,0 +1,138 @@
+/*
+ * 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();
+ }
+}