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

Commit 2b72add7 authored by Winson Chung's avatar Winson Chung
Browse files

1/ Add mechanism to expose shell feature directly (for Pip)

- Also split impl and controller for ShellInit/ShellCommandHandler
  (as with ag/13502602)
- Example implementation of exposing a subset of the Pip interface to
  Launcher directly.  This has the benefit of reducing unnecessary code
  in SysUI just to pipe calls to the Shell.

  The controller implements the binder interface which is collected
  and exposed to Launcher when it binds to the overview  service
  and Launcher can call through the binders directly.

  Note: this requires the shared lib to also build with the Shell
  interfaces so changes to the Shell aidls will still require updating
  the shared lib (until the shared lib prebuilt can removed).

Bug: 180074017
Test: atest WMShellUnitTests
Test: Verify Pip calls from Launcher work
Change-Id: Id74114da6a6a73d32c957f84fce5bbe23e87ba01
parent 932239de
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -38,6 +38,14 @@ filegroup {
    path: "src",
}

filegroup {
    name: "wm_shell-aidls",
    srcs: [
        "src/**/*.aidl",
    ],
    path: "src",
}

// TODO(b/168581922) protologtool do not support kotlin(*.kt)
filegroup {
    name: "wm_shell-sources-kt",
@@ -98,7 +106,7 @@ android_library {
        ":wm_shell_protolog_src",
        // TODO(b/168581922) protologtool do not support kotlin(*.kt)
        ":wm_shell-sources-kt",
        "src/**/I*.aidl",
        ":wm_shell-aidls",
    ],
    resource_dirs: [
        "res",
+5 −15
Original line number Diff line number Diff line
@@ -47,21 +47,7 @@ public final class ShellCommandHandlerImpl {
    private final ShellExecutor mMainExecutor;
    private final HandlerImpl mImpl = new HandlerImpl();

    public static ShellCommandHandler create(
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreenController> legacySplitScreenOptional,
            Optional<SplitScreenController> splitScreenOptional,
            Optional<Pip> pipOptional,
            Optional<OneHandedController> oneHandedOptional,
            Optional<HideDisplayCutoutController> hideDisplayCutout,
            Optional<AppPairsController> appPairsOptional,
            ShellExecutor mainExecutor) {
        return new ShellCommandHandlerImpl(shellTaskOrganizer, legacySplitScreenOptional,
                splitScreenOptional, pipOptional, oneHandedOptional, hideDisplayCutout,
                appPairsOptional, mainExecutor).mImpl;
    }

    private ShellCommandHandlerImpl(
    public ShellCommandHandlerImpl(
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreenController> legacySplitScreenOptional,
            Optional<SplitScreenController> splitScreenOptional,
@@ -80,6 +66,10 @@ public final class ShellCommandHandlerImpl {
        mMainExecutor = mainExecutor;
    }

    public ShellCommandHandler asShellCommandHandler() {
        return mImpl;
    }

    /** Dumps WM Shell internal state. */
    private void dump(PrintWriter pw) {
        mShellTaskOrganizer.dump(pw, "");
+5 −25
Original line number Diff line number Diff line
@@ -51,31 +51,7 @@ public class ShellInitImpl {

    private final InitImpl mImpl = new InitImpl();

    public static ShellInit create(DisplayImeController displayImeController,
            DragAndDropController dragAndDropController,
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreenController> legacySplitScreenOptional,
            Optional<SplitScreenController> splitScreenOptional,
            Optional<AppPairsController> appPairsOptional,
            Optional<StartingSurface> startingSurfaceOptional,
            Optional<PipTouchHandler> pipTouchHandlerOptional,
            FullscreenTaskListener fullscreenTaskListener,
            Transitions transitions,
            ShellExecutor mainExecutor) {
        return new ShellInitImpl(displayImeController,
                dragAndDropController,
                shellTaskOrganizer,
                legacySplitScreenOptional,
                splitScreenOptional,
                appPairsOptional,
                startingSurfaceOptional,
                pipTouchHandlerOptional,
                fullscreenTaskListener,
                transitions,
                mainExecutor).mImpl;
    }

    private ShellInitImpl(DisplayImeController displayImeController,
    public ShellInitImpl(DisplayImeController displayImeController,
            DragAndDropController dragAndDropController,
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreenController> legacySplitScreenOptional,
@@ -99,6 +75,10 @@ public class ShellInitImpl {
        mStartingSurfaceOptional = startingSurfaceOptional;
    }

    public ShellInit asShellInit() {
        return mImpl;
    }

    private void init() {
        // Start listening for display changes
        mDisplayImeController.startMonitorDisplays();
+64 −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 com.android.wm.shell.common;

import android.Manifest;
import android.util.Slog;

import java.util.function.Consumer;

/**
 * Helpers for working with executors
 */
public class ExecutorUtils {

    /**
     * Checks that the caller has the MANAGE_ACTIVITY_TASKS permission and executes the given
     * callback.
     */
    public static <T> void executeRemoteCallWithTaskPermission(RemoteCallable<T> controllerInstance,
            String log, Consumer<T> callback) {
        executeRemoteCallWithTaskPermission(controllerInstance, log, callback,
                false /* blocking */);
    }

    /**
     * Checks that the caller has the MANAGE_ACTIVITY_TASKS permission and executes the given
     * callback.
     */
    public static <T> void executeRemoteCallWithTaskPermission(RemoteCallable<T> controllerInstance,
            String log, Consumer<T> callback, boolean blocking) {
        if (controllerInstance == null) return;

        final RemoteCallable<T> controller = controllerInstance;
        controllerInstance.getContext().enforceCallingPermission(
                Manifest.permission.MANAGE_ACTIVITY_TASKS, log);
        if (blocking) {
            try {
                controllerInstance.getRemoteCallExecutor().executeBlocking(() -> {
                    callback.accept((T) controller);
                });
            } catch (InterruptedException e) {
                Slog.e("ExecutorUtils", "Remote call failed", e);
            }
        } else {
            controllerInstance.getRemoteCallExecutor().execute(() -> {
                callback.accept((T) controller);
            });
        }
    }
}
+34 −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 com.android.wm.shell.common;

import android.content.Context;

/**
 * An interface for controllers that can receive remote calls.
 */
public interface RemoteCallable<T> {
    /**
     * Returns a context used for permission checking.
     */
    Context getContext();

    /**
     * Returns the executor to post the handler callback to.
     */
    ShellExecutor getRemoteCallExecutor();
}
 No newline at end of file
Loading