1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.wm.shell; 18 19 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN; 20 21 import com.android.wm.shell.apppairs.AppPairsController; 22 import com.android.wm.shell.bubbles.BubbleController; 23 import com.android.wm.shell.common.DisplayController; 24 import com.android.wm.shell.common.DisplayImeController; 25 import com.android.wm.shell.common.DisplayInsetsController; 26 import com.android.wm.shell.common.ShellExecutor; 27 import com.android.wm.shell.common.annotations.ExternalThread; 28 import com.android.wm.shell.draganddrop.DragAndDropController; 29 import com.android.wm.shell.freeform.FreeformTaskListener; 30 import com.android.wm.shell.fullscreen.FullscreenTaskListener; 31 import com.android.wm.shell.fullscreen.FullscreenUnfoldController; 32 import com.android.wm.shell.pip.phone.PipTouchHandler; 33 import com.android.wm.shell.recents.RecentTasksController; 34 import com.android.wm.shell.splitscreen.SplitScreenController; 35 import com.android.wm.shell.startingsurface.StartingWindowController; 36 import com.android.wm.shell.transition.Transitions; 37 38 import java.util.Optional; 39 40 /** 41 * The entry point implementation into the shell for initializing shell internal state. 42 */ 43 public class ShellInitImpl { 44 private static final String TAG = ShellInitImpl.class.getSimpleName(); 45 46 private final DisplayController mDisplayController; 47 private final DisplayImeController mDisplayImeController; 48 private final DisplayInsetsController mDisplayInsetsController; 49 private final DragAndDropController mDragAndDropController; 50 private final ShellTaskOrganizer mShellTaskOrganizer; 51 private final Optional<BubbleController> mBubblesOptional; 52 private final Optional<SplitScreenController> mSplitScreenOptional; 53 private final Optional<AppPairsController> mAppPairsOptional; 54 private final Optional<PipTouchHandler> mPipTouchHandlerOptional; 55 private final FullscreenTaskListener mFullscreenTaskListener; 56 private final Optional<FullscreenUnfoldController> mFullscreenUnfoldController; 57 private final Optional<FreeformTaskListener> mFreeformTaskListenerOptional; 58 private final ShellExecutor mMainExecutor; 59 private final Transitions mTransitions; 60 private final StartingWindowController mStartingWindow; 61 private final Optional<RecentTasksController> mRecentTasks; 62 63 private final InitImpl mImpl = new InitImpl(); 64 ShellInitImpl( DisplayController displayController, DisplayImeController displayImeController, DisplayInsetsController displayInsetsController, DragAndDropController dragAndDropController, ShellTaskOrganizer shellTaskOrganizer, Optional<BubbleController> bubblesOptional, Optional<SplitScreenController> splitScreenOptional, Optional<AppPairsController> appPairsOptional, Optional<PipTouchHandler> pipTouchHandlerOptional, FullscreenTaskListener fullscreenTaskListener, Optional<FullscreenUnfoldController> fullscreenUnfoldTransitionController, Optional<FreeformTaskListener> freeformTaskListenerOptional, Optional<RecentTasksController> recentTasks, Transitions transitions, StartingWindowController startingWindow, ShellExecutor mainExecutor)65 public ShellInitImpl( 66 DisplayController displayController, 67 DisplayImeController displayImeController, 68 DisplayInsetsController displayInsetsController, 69 DragAndDropController dragAndDropController, 70 ShellTaskOrganizer shellTaskOrganizer, 71 Optional<BubbleController> bubblesOptional, 72 Optional<SplitScreenController> splitScreenOptional, 73 Optional<AppPairsController> appPairsOptional, 74 Optional<PipTouchHandler> pipTouchHandlerOptional, 75 FullscreenTaskListener fullscreenTaskListener, 76 Optional<FullscreenUnfoldController> fullscreenUnfoldTransitionController, 77 Optional<FreeformTaskListener> freeformTaskListenerOptional, 78 Optional<RecentTasksController> recentTasks, 79 Transitions transitions, 80 StartingWindowController startingWindow, 81 ShellExecutor mainExecutor) { 82 mDisplayController = displayController; 83 mDisplayImeController = displayImeController; 84 mDisplayInsetsController = displayInsetsController; 85 mDragAndDropController = dragAndDropController; 86 mShellTaskOrganizer = shellTaskOrganizer; 87 mBubblesOptional = bubblesOptional; 88 mSplitScreenOptional = splitScreenOptional; 89 mAppPairsOptional = appPairsOptional; 90 mFullscreenTaskListener = fullscreenTaskListener; 91 mPipTouchHandlerOptional = pipTouchHandlerOptional; 92 mFullscreenUnfoldController = fullscreenUnfoldTransitionController; 93 mFreeformTaskListenerOptional = freeformTaskListenerOptional; 94 mRecentTasks = recentTasks; 95 mTransitions = transitions; 96 mMainExecutor = mainExecutor; 97 mStartingWindow = startingWindow; 98 } 99 asShellInit()100 public ShellInit asShellInit() { 101 return mImpl; 102 } 103 init()104 private void init() { 105 // Start listening for display and insets changes 106 mDisplayController.initialize(); 107 mDisplayInsetsController.initialize(); 108 mDisplayImeController.startMonitorDisplays(); 109 110 // Setup the shell organizer 111 mShellTaskOrganizer.addListenerForType( 112 mFullscreenTaskListener, TASK_LISTENER_TYPE_FULLSCREEN); 113 mShellTaskOrganizer.initStartingWindow(mStartingWindow); 114 mShellTaskOrganizer.registerOrganizer(); 115 116 mAppPairsOptional.ifPresent(AppPairsController::onOrganizerRegistered); 117 mSplitScreenOptional.ifPresent(SplitScreenController::onOrganizerRegistered); 118 mBubblesOptional.ifPresent(BubbleController::initialize); 119 120 // Bind the splitscreen impl to the drag drop controller 121 mDragAndDropController.initialize(mSplitScreenOptional); 122 123 if (Transitions.ENABLE_SHELL_TRANSITIONS) { 124 mTransitions.register(mShellTaskOrganizer); 125 } 126 127 // TODO(b/181599115): This should really be the pip controller, but until we can provide the 128 // controller instead of the feature interface, can just initialize the touch handler if 129 // needed 130 mPipTouchHandlerOptional.ifPresent((handler) -> handler.init()); 131 132 // Initialize optional freeform 133 mFreeformTaskListenerOptional.ifPresent(f -> 134 mShellTaskOrganizer.addListenerForType( 135 f, ShellTaskOrganizer.TASK_LISTENER_TYPE_FREEFORM)); 136 137 mFullscreenUnfoldController.ifPresent(FullscreenUnfoldController::init); 138 mRecentTasks.ifPresent(RecentTasksController::init); 139 } 140 141 @ExternalThread 142 private class InitImpl implements ShellInit { 143 @Override init()144 public void init() { 145 try { 146 mMainExecutor.executeBlocking(() -> ShellInitImpl.this.init()); 147 } catch (InterruptedException e) { 148 throw new RuntimeException("Failed to initialize the Shell in 2s", e); 149 } 150 } 151 } 152 } 153