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

Commit feb8ef30 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "2/ Migrate some common shell classes to use executors"

parents 6a0895d4 68d5d7cd
Loading
Loading
Loading
Loading
+15 −96
Original line number Diff line number Diff line
@@ -16,113 +16,32 @@

package com.android.wm.shell;

import android.util.Slog;

import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;

import java.io.PrintWriter;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * An entry point into the shell for dumping shell internal state and running adb commands.
 *
 * Use with {@code adb shell dumpsys activity service SystemUIService WMShell ...}.
 */
public final class ShellCommandHandler {

    private final Optional<LegacySplitScreen> mLegacySplitScreenOptional;
    private final Optional<Pip> mPipOptional;
    private final Optional<OneHanded> mOneHandedOptional;
    private final Optional<HideDisplayCutout> mHideDisplayCutout;
    private final ShellTaskOrganizer mShellTaskOrganizer;
    private final Optional<AppPairs> mAppPairsOptional;

    public ShellCommandHandler(
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreen> legacySplitScreenOptional,
            Optional<Pip> pipOptional,
            Optional<OneHanded> oneHandedOptional,
            Optional<HideDisplayCutout> hideDisplayCutout,
            Optional<AppPairs> appPairsOptional) {
        mShellTaskOrganizer = shellTaskOrganizer;
        mLegacySplitScreenOptional = legacySplitScreenOptional;
        mPipOptional = pipOptional;
        mOneHandedOptional = oneHandedOptional;
        mHideDisplayCutout = hideDisplayCutout;
        mAppPairsOptional = appPairsOptional;
    }

    /** Dumps WM Shell internal state. */
    @ExternalThread
    public void dump(PrintWriter pw) {
        mShellTaskOrganizer.dump(pw, "");
        pw.println();
        pw.println();
        mPipOptional.ifPresent(pip -> pip.dump(pw));
        mLegacySplitScreenOptional.ifPresent(splitScreen -> splitScreen.dump(pw));
        mOneHandedOptional.ifPresent(oneHanded -> oneHanded.dump(pw));
        mHideDisplayCutout.ifPresent(hideDisplayCutout -> hideDisplayCutout.dump(pw));
        pw.println();
        pw.println();
        mAppPairsOptional.ifPresent(appPairs -> appPairs.dump(pw, ""));
    }


    /** Returns {@code true} if command was found and executed. */
    @ExternalThread
    public boolean handleCommand(String[] args, PrintWriter pw) {
        if (args.length < 2) {
            // Argument at position 0 is "WMShell".
            return false;
        }
        switch (args[1]) {
            case "pair":
                return runPair(args, pw);
            case "unpair":
                return runUnpair(args, pw);
            case "help":
                return runHelp(pw);
            default:
                return false;
        }
    }


    private boolean runPair(String[] args, PrintWriter pw) {
        if (args.length < 4) {
            // First two arguments are "WMShell" and command name.
            pw.println("Error: two task ids should be provided as arguments");
            return false;
        }
        final int taskId1 = new Integer(args[2]);
        final int taskId2 = new Integer(args[3]);
        mAppPairsOptional.ifPresent(appPairs -> appPairs.pair(taskId1, taskId2));
        return true;
    }

    private boolean runUnpair(String[] args, PrintWriter pw) {
        if (args.length < 3) {
            // First two arguments are "WMShell" and command name.
            pw.println("Error: task id should be provided as an argument");
            return false;
        }
        final int taskId = new Integer(args[2]);
        mAppPairsOptional.ifPresent(appPairs -> appPairs.unpair(taskId));
        return true;
    }
public interface ShellCommandHandler {
    /**
     * Dumps the shell state.
     */
    void dump(PrintWriter pw);

    private boolean runHelp(PrintWriter pw) {
        pw.println("Window Manager Shell commands:");
        pw.println("  help");
        pw.println("      Print this help text.");
        pw.println("  <no arguments provided>");
        pw.println("    Dump Window Manager Shell internal state");
        pw.println("  pair <taskId1> <taskId2>");
        pw.println("  unpair <taskId>");
        pw.println("    Pairs/unpairs tasks with given ids.");
        return true;
    }
    /**
     * Handles a shell command.
     */
    boolean handleCommand(final String[] args, PrintWriter pw);
}
+171 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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;

import android.util.Slog;

import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;

import java.io.PrintWriter;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * An entry point into the shell for dumping shell internal state and running adb commands.
 *
 * Use with {@code adb shell dumpsys activity service SystemUIService WMShell ...}.
 */
public final class ShellCommandHandlerImpl {
    private static final String TAG = ShellCommandHandlerImpl.class.getSimpleName();

    private final Optional<LegacySplitScreen> mLegacySplitScreenOptional;
    private final Optional<Pip> mPipOptional;
    private final Optional<OneHanded> mOneHandedOptional;
    private final Optional<HideDisplayCutout> mHideDisplayCutout;
    private final ShellTaskOrganizer mShellTaskOrganizer;
    private final Optional<AppPairs> mAppPairsOptional;
    private final ShellExecutor mMainExecutor;
    private final HandlerImpl mImpl = new HandlerImpl();

    public static ShellCommandHandler create(
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreen> legacySplitScreenOptional,
            Optional<Pip> pipOptional,
            Optional<OneHanded> oneHandedOptional,
            Optional<HideDisplayCutout> hideDisplayCutout,
            Optional<AppPairs> appPairsOptional,
            ShellExecutor mainExecutor) {
        return new ShellCommandHandlerImpl(shellTaskOrganizer, legacySplitScreenOptional,
                pipOptional, oneHandedOptional, hideDisplayCutout, appPairsOptional,
                mainExecutor).mImpl;
    }

    private ShellCommandHandlerImpl(
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreen> legacySplitScreenOptional,
            Optional<Pip> pipOptional,
            Optional<OneHanded> oneHandedOptional,
            Optional<HideDisplayCutout> hideDisplayCutout,
            Optional<AppPairs> appPairsOptional,
            ShellExecutor mainExecutor) {
        mShellTaskOrganizer = shellTaskOrganizer;
        mLegacySplitScreenOptional = legacySplitScreenOptional;
        mPipOptional = pipOptional;
        mOneHandedOptional = oneHandedOptional;
        mHideDisplayCutout = hideDisplayCutout;
        mAppPairsOptional = appPairsOptional;
        mMainExecutor = mainExecutor;
    }

    /** Dumps WM Shell internal state. */
    private void dump(PrintWriter pw) {
        mShellTaskOrganizer.dump(pw, "");
        pw.println();
        pw.println();
        mPipOptional.ifPresent(pip -> pip.dump(pw));
        mLegacySplitScreenOptional.ifPresent(splitScreen -> splitScreen.dump(pw));
        mOneHandedOptional.ifPresent(oneHanded -> oneHanded.dump(pw));
        mHideDisplayCutout.ifPresent(hideDisplayCutout -> hideDisplayCutout.dump(pw));
        pw.println();
        pw.println();
        mAppPairsOptional.ifPresent(appPairs -> appPairs.dump(pw, ""));
    }


    /** Returns {@code true} if command was found and executed. */
    private boolean handleCommand(final String[] args, PrintWriter pw) {
        if (args.length < 2) {
            // Argument at position 0 is "WMShell".
            return false;
        }
        switch (args[1]) {
            case "pair":
                return runPair(args, pw);
            case "unpair":
                return runUnpair(args, pw);
            case "help":
                return runHelp(pw);
            default:
                return false;
        }
    }


    private boolean runPair(String[] args, PrintWriter pw) {
        if (args.length < 4) {
            // First two arguments are "WMShell" and command name.
            pw.println("Error: two task ids should be provided as arguments");
            return false;
        }
        final int taskId1 = new Integer(args[2]);
        final int taskId2 = new Integer(args[3]);
        mAppPairsOptional.ifPresent(appPairs -> appPairs.pair(taskId1, taskId2));
        return true;
    }

    private boolean runUnpair(String[] args, PrintWriter pw) {
        if (args.length < 3) {
            // First two arguments are "WMShell" and command name.
            pw.println("Error: task id should be provided as an argument");
            return false;
        }
        final int taskId = new Integer(args[2]);
        mAppPairsOptional.ifPresent(appPairs -> appPairs.unpair(taskId));
        return true;
    }

    private boolean runHelp(PrintWriter pw) {
        pw.println("Window Manager Shell commands:");
        pw.println("  help");
        pw.println("      Print this help text.");
        pw.println("  <no arguments provided>");
        pw.println("    Dump Window Manager Shell internal state");
        pw.println("  pair <taskId1> <taskId2>");
        pw.println("  unpair <taskId>");
        pw.println("    Pairs/unpairs tasks with given ids.");
        return true;
    }

    private class HandlerImpl implements ShellCommandHandler {
        @Override
        public void dump(PrintWriter pw) {
            try {
                mMainExecutor.executeBlocking(() -> ShellCommandHandlerImpl.this.dump(pw));
            } catch (InterruptedException e) {
                throw new RuntimeException("Failed to dump the Shell in 2s", e);
            }
        }

        @Override
        public boolean handleCommand(String[] args, PrintWriter pw) {
            try {
                boolean[] result = new boolean[1];
                mMainExecutor.executeBlocking(() -> {
                    result[0] = ShellCommandHandlerImpl.this.handleCommand(args, pw);
                });
                return result[0];
            } catch (InterruptedException e) {
                throw new RuntimeException("Failed to handle Shell command in 2s", e);
            }
        }
    }
}
+6 −52
Original line number Diff line number Diff line
@@ -16,61 +16,15 @@

package com.android.wm.shell;

import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;

import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;

import java.util.Optional;

/**
 * An entry point into the shell for initializing shell internal state.
 */
public class ShellInit {

    private final DisplayImeController mDisplayImeController;
    private final DragAndDropController mDragAndDropController;
    private final ShellTaskOrganizer mShellTaskOrganizer;
    private final Optional<LegacySplitScreen> mLegacySplitScreenOptional;
    private final Optional<AppPairs> mAppPairsOptional;
    private final FullscreenTaskListener mFullscreenTaskListener;
    private final Transitions mTransitions;

    public ShellInit(DisplayImeController displayImeController,
            DragAndDropController dragAndDropController,
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreen> legacySplitScreenOptional,
            Optional<AppPairs> appPairsOptional,
            FullscreenTaskListener fullscreenTaskListener,
            Transitions transitions) {
        mDisplayImeController = displayImeController;
        mDragAndDropController = dragAndDropController;
        mShellTaskOrganizer = shellTaskOrganizer;
        mLegacySplitScreenOptional = legacySplitScreenOptional;
        mAppPairsOptional = appPairsOptional;
        mFullscreenTaskListener = fullscreenTaskListener;
        mTransitions = transitions;
    }

@ExternalThread
    public void init() {
        // Start listening for display changes
        mDisplayImeController.startMonitorDisplays();

        mShellTaskOrganizer.addListenerForType(
                mFullscreenTaskListener, TASK_LISTENER_TYPE_FULLSCREEN);
        // Register the shell organizer
        mShellTaskOrganizer.registerOrganizer();

        mAppPairsOptional.ifPresent(AppPairs::onOrganizerRegistered);
        // Bind the splitscreen impl to the drag drop controller
        mDragAndDropController.setSplitScreenController(mLegacySplitScreenOptional);

        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
            mTransitions.register(mShellTaskOrganizer);
        }
    }
public interface ShellInit {
    /**
     * Initializes the shell state.
     */
    void init();
}
+105 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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;

import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;

import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;

import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * The entry point implementation into the shell for initializing shell internal state.
 */
public class ShellInitImpl {
    private static final String TAG = ShellInitImpl.class.getSimpleName();

    private final DisplayImeController mDisplayImeController;
    private final DragAndDropController mDragAndDropController;
    private final ShellTaskOrganizer mShellTaskOrganizer;
    private final Optional<LegacySplitScreen> mLegacySplitScreenOptional;
    private final Optional<AppPairs> mAppPairsOptional;
    private final FullscreenTaskListener mFullscreenTaskListener;
    private final ShellExecutor mMainExecutor;

    private final InitImpl mImpl = new InitImpl();

    public static ShellInit create(DisplayImeController displayImeController,
            DragAndDropController dragAndDropController,
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreen> legacySplitScreenOptional,
            Optional<AppPairs> appPairsOptional,
            FullscreenTaskListener fullscreenTaskListener,
            ShellExecutor mainExecutor) {
        return new ShellInitImpl(displayImeController,
                dragAndDropController,
                shellTaskOrganizer,
                legacySplitScreenOptional,
                appPairsOptional,
                fullscreenTaskListener,
                mainExecutor).mImpl;
    }

    private ShellInitImpl(DisplayImeController displayImeController,
            DragAndDropController dragAndDropController,
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<LegacySplitScreen> legacySplitScreenOptional,
            Optional<AppPairs> appPairsOptional,
            FullscreenTaskListener fullscreenTaskListener,
            ShellExecutor mainExecutor) {
        mDisplayImeController = displayImeController;
        mDragAndDropController = dragAndDropController;
        mShellTaskOrganizer = shellTaskOrganizer;
        mLegacySplitScreenOptional = legacySplitScreenOptional;
        mAppPairsOptional = appPairsOptional;
        mFullscreenTaskListener = fullscreenTaskListener;
        mMainExecutor = mainExecutor;
    }

    private void init() {
        // Start listening for display changes
        mDisplayImeController.startMonitorDisplays();

        mShellTaskOrganizer.addListenerForType(
                mFullscreenTaskListener, TASK_LISTENER_TYPE_FULLSCREEN);
        // Register the shell organizer
        mShellTaskOrganizer.registerOrganizer();

        mAppPairsOptional.ifPresent(AppPairs::onOrganizerRegistered);

        // Bind the splitscreen impl to the drag drop controller
        mDragAndDropController.initialize(mLegacySplitScreenOptional);
    }

    @ExternalThread
    private class InitImpl implements ShellInit {
        @Override
        public void init() {
            try {
                mMainExecutor.executeBlocking(() -> ShellInitImpl.this.init());
            } catch (InterruptedException e) {
                throw new RuntimeException("Failed to initialize the Shell in 2s", e);
            }
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@ public class WindowManagerShellWrapper {
     */
    private final PinnedStackListenerForwarder mPinnedStackListenerForwarder;

    public WindowManagerShellWrapper(ShellExecutor shellMainExecutor) {
        mPinnedStackListenerForwarder = new PinnedStackListenerForwarder(shellMainExecutor);
    public WindowManagerShellWrapper(ShellExecutor mainExecutor) {
        mPinnedStackListenerForwarder = new PinnedStackListenerForwarder(mainExecutor);
    }

    /**
Loading