Merge "Introduce WindowProviderService" into sc-dev
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
138
core/java/android/window/WindowProviderService.java
Normal file
138
core/java/android/window/WindowProviderService.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user