Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eba41ae4 authored by Charles Chen's avatar Charles Chen Committed by Automerger Merge Worker
Browse files

Merge "Introduce WindowProviderService" into sc-dev am: ac8d924d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13496467

Change-Id: Ie6bb1b4753d75c87b7a0e0469f2c0a47ef774824
parents feff3494 ac8d924d
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3177,5 +3177,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();
  }

}
+2 −1
Original line number Diff line number Diff line
@@ -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(
+13 −0
Original line number Diff line number Diff line
@@ -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.
+1 −0
Original line number Diff line number Diff line
@@ -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 −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();
    }
}