diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index b20798481a585..d109ae197714c 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -42,6 +42,7 @@ import com.android.systemui.power.PowerUI; import com.android.systemui.recents.Recents; import com.android.systemui.shortcut.ShortcutKeyDispatcher; import com.android.systemui.stackdivider.Divider; +import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.SystemBars; import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.tuner.TunerService; @@ -65,6 +66,7 @@ public class SystemUIApplication extends Application { private final Class[] SERVICES = new Class[] { FragmentService.class, TunerService.class, + CommandQueue.CommandQueueStart.class, KeyguardViewMediator.class, Recents.class, VolumeUI.class, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 08953557d1f7e..db099bc15472f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -42,7 +42,6 @@ import android.content.pm.UserInfo; import android.content.res.Configuration; import android.database.ContentObserver; import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; @@ -80,7 +79,6 @@ import android.view.ViewParent; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; -import android.widget.ImageView; import android.widget.RemoteViews; import android.widget.TextView; import android.widget.Toast; @@ -754,7 +752,8 @@ public abstract class BaseStatusBar extends SystemUI implements mLockPatternUtils = new LockPatternUtils(mContext); // Connect in to the status bar manager service - mCommandQueue = new CommandQueue(this); + mCommandQueue = getComponent(CommandQueue.class); + mCommandQueue.addCallbacks(this); int[] switches = new int[9]; ArrayList binders = new ArrayList(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 419c91b11e37e..a3e4d5b6db542 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -21,13 +21,16 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.Message; +import android.support.annotation.VisibleForTesting; import android.util.Pair; import android.view.KeyEvent; import com.android.internal.os.SomeArgs; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.StatusBarIcon; +import com.android.systemui.SystemUI; /** * This class takes the functions from IStatusBar that come in on @@ -88,55 +91,68 @@ public class CommandQueue extends IStatusBar.Stub { private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey"; private final Object mLock = new Object(); - private Callbacks mCallbacks; - private Handler mHandler = new H(); + private Callbacks[] mCallbacks = new Callbacks[0]; + private Handler mHandler = new H(Looper.getMainLooper()); /** * These methods are called back on the main thread. */ public interface Callbacks { - void setIcon(String slot, StatusBarIcon icon); - void removeIcon(String slot); - void disable(int state1, int state2, boolean animate); - void animateExpandNotificationsPanel(); - void animateCollapsePanels(int flags); - void animateExpandSettingsPanel(String obj); - void setSystemUiVisibility(int vis, int fullscreenStackVis, - int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds); - void topAppWindowChanged(boolean visible); - void setImeWindowStatus(IBinder token, int vis, int backDisposition, - boolean showImeSwitcher); - void showRecentApps(boolean triggeredFromAltTab, boolean fromHome); - void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey); - void toggleRecentApps(); - void toggleSplitScreen(); - void preloadRecentApps(); - void dismissKeyboardShortcutsMenu(); - void toggleKeyboardShortcutsMenu(int deviceId); - void cancelPreloadRecentApps(); - void setWindowState(int window, int state); - void buzzBeepBlinked(); - void notificationLightOff(); - void notificationLightPulse(int argb, int onMillis, int offMillis); - void showScreenPinningRequest(int taskId); - void appTransitionPending(); - void appTransitionCancelled(); - void appTransitionStarting(long startTime, long duration); - void appTransitionFinished(); - void showAssistDisclosure(); - void startAssist(Bundle args); - void onCameraLaunchGestureDetected(int source); - void showTvPictureInPictureMenu(); + default void setIcon(String slot, StatusBarIcon icon) { } + default void removeIcon(String slot) { } + default void disable(int state1, int state2, boolean animate) { } + default void animateExpandNotificationsPanel() { } + default void animateCollapsePanels(int flags) { } + default void animateExpandSettingsPanel(String obj) { } + default void setSystemUiVisibility(int vis, int fullscreenStackVis, + int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) { + } + default void topAppWindowChanged(boolean visible) { } + default void setImeWindowStatus(IBinder token, int vis, int backDisposition, + boolean showImeSwitcher) { } + default void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) { } + default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { } + default void toggleRecentApps() { } + default void toggleSplitScreen() { } + default void preloadRecentApps() { } + default void dismissKeyboardShortcutsMenu() { } + default void toggleKeyboardShortcutsMenu(int deviceId) { } + default void cancelPreloadRecentApps() { } + default void setWindowState(int window, int state) { } + default void buzzBeepBlinked() { } + default void notificationLightOff() { } + default void notificationLightPulse(int argb, int onMillis, int offMillis) { } + default void showScreenPinningRequest(int taskId) { } + default void appTransitionPending() { } + default void appTransitionCancelled() { } + default void appTransitionStarting(long startTime, long duration) { } + default void appTransitionFinished() { } + default void showAssistDisclosure() { } + default void startAssist(Bundle args) { } + default void onCameraLaunchGestureDetected(int source) { } + default void showTvPictureInPictureMenu() { } - void addQsTile(ComponentName tile); - void remQsTile(ComponentName tile); - void clickTile(ComponentName tile); + default void addQsTile(ComponentName tile) { } + default void remQsTile(ComponentName tile) { } + default void clickTile(ComponentName tile) { } - void handleSystemNavigationKey(int arg1); + default void handleSystemNavigationKey(int arg1) { } } - public CommandQueue(Callbacks callbacks) { - mCallbacks = callbacks; + @VisibleForTesting + protected CommandQueue() { + } + + public void addCallbacks(Callbacks callbacks) { + Callbacks[] newArray = new Callbacks[mCallbacks.length + 1]; + for (int i = 0; i < newArray.length - 1; i++) { + newArray[i] = mCallbacks[i]; + if (newArray[i] == callbacks) { + throw new IllegalArgumentException("Callback was already added"); + } + } + newArray[newArray.length - 1] = callbacks; + mCallbacks = newArray; } public void setIcon(String slot, StatusBarIcon icon) { @@ -328,8 +344,8 @@ public class CommandQueue extends IStatusBar.Stub { public void appTransitionCancelled() { synchronized (mLock) { - mHandler.removeMessages(MSG_APP_TRANSITION_PENDING); - mHandler.sendEmptyMessage(MSG_APP_TRANSITION_PENDING); + mHandler.removeMessages(MSG_APP_TRANSITION_CANCELLED); + mHandler.sendEmptyMessage(MSG_APP_TRANSITION_CANCELLED); } } @@ -400,6 +416,10 @@ public class CommandQueue extends IStatusBar.Stub { } private final class H extends Handler { + private H(Looper l) { + super(l); + } + public void handleMessage(Message msg) { final int what = msg.what & MSG_MASK; switch (what) { @@ -407,118 +427,195 @@ public class CommandQueue extends IStatusBar.Stub { switch (msg.arg1) { case OP_SET_ICON: { Pair p = (Pair) msg.obj; - mCallbacks.setIcon(p.first, p.second); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].setIcon(p.first, p.second); + } break; } case OP_REMOVE_ICON: - mCallbacks.removeIcon((String) msg.obj); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].removeIcon((String) msg.obj); + } break; } break; } case MSG_DISABLE: - mCallbacks.disable(msg.arg1, msg.arg2, true /* animate */); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].disable(msg.arg1, msg.arg2, true /* animate */); + } break; case MSG_EXPAND_NOTIFICATIONS: - mCallbacks.animateExpandNotificationsPanel(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].animateExpandNotificationsPanel(); + } break; case MSG_COLLAPSE_PANELS: - mCallbacks.animateCollapsePanels(0); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].animateCollapsePanels(0); + } break; case MSG_EXPAND_SETTINGS: - mCallbacks.animateExpandSettingsPanel((String) msg.obj); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].animateExpandSettingsPanel((String) msg.obj); + } break; case MSG_SET_SYSTEMUI_VISIBILITY: SomeArgs args = (SomeArgs) msg.obj; - mCallbacks.setSystemUiVisibility(args.argi1, args.argi2, args.argi3, - args.argi4, (Rect) args.arg1, (Rect) args.arg2); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].setSystemUiVisibility(args.argi1, args.argi2, args.argi3, + args.argi4, (Rect) args.arg1, (Rect) args.arg2); + } args.recycle(); break; case MSG_TOP_APP_WINDOW_CHANGED: - mCallbacks.topAppWindowChanged(msg.arg1 != 0); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].topAppWindowChanged(msg.arg1 != 0); + } break; case MSG_SHOW_IME_BUTTON: - mCallbacks.setImeWindowStatus((IBinder) msg.obj, msg.arg1, msg.arg2, - msg.getData().getBoolean(SHOW_IME_SWITCHER_KEY, false)); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].setImeWindowStatus((IBinder) msg.obj, msg.arg1, msg.arg2, + msg.getData().getBoolean(SHOW_IME_SWITCHER_KEY, false)); + } break; case MSG_SHOW_RECENT_APPS: - mCallbacks.showRecentApps(msg.arg1 != 0, msg.arg2 != 0); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].showRecentApps(msg.arg1 != 0, msg.arg2 != 0); + } break; case MSG_HIDE_RECENT_APPS: - mCallbacks.hideRecentApps(msg.arg1 != 0, msg.arg2 != 0); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].hideRecentApps(msg.arg1 != 0, msg.arg2 != 0); + } break; case MSG_TOGGLE_RECENT_APPS: - mCallbacks.toggleRecentApps(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].toggleRecentApps(); + } break; case MSG_PRELOAD_RECENT_APPS: - mCallbacks.preloadRecentApps(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].preloadRecentApps(); + } break; case MSG_CANCEL_PRELOAD_RECENT_APPS: - mCallbacks.cancelPreloadRecentApps(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].cancelPreloadRecentApps(); + } break; case MSG_DISMISS_KEYBOARD_SHORTCUTS: - mCallbacks.dismissKeyboardShortcutsMenu(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].dismissKeyboardShortcutsMenu(); + } break; case MSG_TOGGLE_KEYBOARD_SHORTCUTS: - mCallbacks.toggleKeyboardShortcutsMenu(msg.arg1); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].toggleKeyboardShortcutsMenu(msg.arg1); + } break; case MSG_SET_WINDOW_STATE: - mCallbacks.setWindowState(msg.arg1, msg.arg2); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].setWindowState(msg.arg1, msg.arg2); + } break; case MSG_BUZZ_BEEP_BLINKED: - mCallbacks.buzzBeepBlinked(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].buzzBeepBlinked(); + } break; case MSG_NOTIFICATION_LIGHT_OFF: - mCallbacks.notificationLightOff(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].notificationLightOff(); + } break; case MSG_NOTIFICATION_LIGHT_PULSE: - mCallbacks.notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2); + } break; case MSG_SHOW_SCREEN_PIN_REQUEST: - mCallbacks.showScreenPinningRequest(msg.arg1); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].showScreenPinningRequest(msg.arg1); + } break; case MSG_APP_TRANSITION_PENDING: - mCallbacks.appTransitionPending(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].appTransitionPending(); + } break; case MSG_APP_TRANSITION_CANCELLED: - mCallbacks.appTransitionCancelled(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].appTransitionCancelled(); + } break; case MSG_APP_TRANSITION_STARTING: - Pair data = (Pair) msg.obj; - mCallbacks.appTransitionStarting(data.first, data.second); + for (int i = 0; i < mCallbacks.length; i++) { + Pair data = (Pair) msg.obj; + mCallbacks[i].appTransitionStarting(data.first, data.second); + } break; case MSG_APP_TRANSITION_FINISHED: - mCallbacks.appTransitionFinished(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].appTransitionFinished(); + } break; case MSG_ASSIST_DISCLOSURE: - mCallbacks.showAssistDisclosure(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].showAssistDisclosure(); + } break; case MSG_START_ASSIST: - mCallbacks.startAssist((Bundle) msg.obj); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].startAssist((Bundle) msg.obj); + } break; case MSG_CAMERA_LAUNCH_GESTURE: - mCallbacks.onCameraLaunchGestureDetected(msg.arg1); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].onCameraLaunchGestureDetected(msg.arg1); + } break; case MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU: - mCallbacks.showTvPictureInPictureMenu(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].showTvPictureInPictureMenu(); + } break; case MSG_ADD_QS_TILE: - mCallbacks.addQsTile((ComponentName) msg.obj); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].addQsTile((ComponentName) msg.obj); + } break; case MSG_REMOVE_QS_TILE: - mCallbacks.remQsTile((ComponentName) msg.obj); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].remQsTile((ComponentName) msg.obj); + } break; case MSG_CLICK_QS_TILE: - mCallbacks.clickTile((ComponentName) msg.obj); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].clickTile((ComponentName) msg.obj); + } break; case MSG_TOGGLE_APP_SPLIT_SCREEN: - mCallbacks.toggleSplitScreen(); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].toggleSplitScreen(); + } break; case MSG_HANDLE_SYSNAV_KEY: - mCallbacks.handleSystemNavigationKey(msg.arg1); + for (int i = 0; i < mCallbacks.length; i++) { + mCallbacks[i].handleSystemNavigationKey(msg.arg1); + } break; } } } + + // Need this class since CommandQueue already extends IStatusBar.Stub, so CommandQueueStart + // is needed so it can extend SystemUI. + public static class CommandQueueStart extends SystemUI { + @Override + public void start() { + putComponent(CommandQueue.class, new CommandQueue()); + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java new file mode 100644 index 0000000000000..43f8629b2945e --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2017 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.systemui.statusbar; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import android.content.ComponentName; +import android.graphics.Rect; +import android.os.Bundle; + +import com.android.internal.statusbar.StatusBarIcon; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.CommandQueue.Callbacks; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class CommandQueueTest extends SysuiTestCase { + + private CommandQueue mCommandQueue; + private Callbacks mCallbacks; + + @Before + public void setup() { + mCommandQueue = new CommandQueue(); + mCallbacks = mock(Callbacks.class); + mCommandQueue.addCallbacks(mCallbacks); + } + + @After + public void tearDown() { + verifyNoMoreInteractions(mCallbacks); + } + + @Test + public void testIcon() { + String slot = "testSlot"; + StatusBarIcon icon = mock(StatusBarIcon.class); + mCommandQueue.setIcon(slot, icon); + waitForIdleSync(); + verify(mCallbacks).setIcon(eq(slot), eq(icon)); + + mCommandQueue.removeIcon(slot); + waitForIdleSync(); + verify(mCallbacks).removeIcon(eq(slot)); + } + + @Test + public void testDisable() { + int state1 = 14; + int state2 = 42; + mCommandQueue.disable(state1, state2); + waitForIdleSync(); + verify(mCallbacks).disable(eq(state1), eq(state2), eq(true)); + } + + @Test + public void testExpandNotifications() { + mCommandQueue.animateExpandNotificationsPanel(); + waitForIdleSync(); + verify(mCallbacks).animateExpandNotificationsPanel(); + } + + @Test + public void testCollapsePanels() { + mCommandQueue.animateCollapsePanels(); + waitForIdleSync(); + verify(mCallbacks).animateCollapsePanels(eq(0)); + } + + @Test + public void testExpandSettings() { + String panel = "some_panel"; + mCommandQueue.animateExpandSettingsPanel(panel); + waitForIdleSync(); + verify(mCallbacks).animateExpandSettingsPanel(eq(panel)); + } + + @Test + public void testSetSystemUiVisibility() { + Rect r = new Rect(); + mCommandQueue.setSystemUiVisibility(1, 2, 3, 4, null, r); + waitForIdleSync(); + verify(mCallbacks).setSystemUiVisibility(eq(1), eq(2), eq(3), eq(4), eq(null), eq(r)); + } + + @Test + public void testTopAppWindowChanged() { + mCommandQueue.topAppWindowChanged(true); + waitForIdleSync(); + verify(mCallbacks).topAppWindowChanged(eq(true)); + } + + @Test + public void testShowImeButton() { + mCommandQueue.setImeWindowStatus(null, 1, 2, true); + waitForIdleSync(); + verify(mCallbacks).setImeWindowStatus(eq(null), eq(1), eq(2), eq(true)); + } + + @Test + public void testShowRecentApps() { + mCommandQueue.showRecentApps(true, false); + waitForIdleSync(); + verify(mCallbacks).showRecentApps(eq(true), eq(false)); + } + + @Test + public void testHideRecentApps() { + mCommandQueue.hideRecentApps(true, false); + waitForIdleSync(); + verify(mCallbacks).hideRecentApps(eq(true), eq(false)); + } + + @Test + public void testToggleRecentApps() { + mCommandQueue.toggleRecentApps(); + waitForIdleSync(); + verify(mCallbacks).toggleRecentApps(); + } + + @Test + public void testPreloadRecentApps() { + mCommandQueue.preloadRecentApps(); + waitForIdleSync(); + verify(mCallbacks).preloadRecentApps(); + } + + @Test + public void testCancelPreloadRecentApps() { + mCommandQueue.cancelPreloadRecentApps(); + waitForIdleSync(); + verify(mCallbacks).cancelPreloadRecentApps(); + } + + @Test + public void testDismissKeyboardShortcuts() { + mCommandQueue.dismissKeyboardShortcutsMenu(); + waitForIdleSync(); + verify(mCallbacks).dismissKeyboardShortcutsMenu(); + } + + @Test + public void testToggleKeyboardShortcuts() { + mCommandQueue.toggleKeyboardShortcutsMenu(1); + waitForIdleSync(); + verify(mCallbacks).toggleKeyboardShortcutsMenu(eq(1)); + } + + @Test + public void testSetWindowState() { + mCommandQueue.setWindowState(1, 2); + waitForIdleSync(); + verify(mCallbacks).setWindowState(eq(1), eq(2)); + } + + @Test + public void testBuzzBeepBlink() { + mCommandQueue.buzzBeepBlinked(); + waitForIdleSync(); + verify(mCallbacks).buzzBeepBlinked(); + } + + @Test + public void testNotificationLightOff() { + mCommandQueue.notificationLightOff(); + waitForIdleSync(); + verify(mCallbacks).notificationLightOff(); + } + + @Test + public void testNotificationLightPulse() { + mCommandQueue.notificationLightPulse(1, 2, 3); + waitForIdleSync(); + verify(mCallbacks).notificationLightPulse(eq(1), eq(2), eq(3)); + } + + @Test + public void testScreenPinRequest() { + mCommandQueue.showScreenPinningRequest(1); + waitForIdleSync(); + verify(mCallbacks).showScreenPinningRequest(eq(1)); + } + + @Test + public void testAppTransitionPending() { + mCommandQueue.appTransitionPending(); + waitForIdleSync(); + verify(mCallbacks).appTransitionPending(); + } + + @Test + public void testAppTransitionCancelled() { + mCommandQueue.appTransitionCancelled(); + waitForIdleSync(); + verify(mCallbacks).appTransitionCancelled(); + } + + @Test + public void testAppTransitionStarting() { + mCommandQueue.appTransitionStarting(1, 2); + waitForIdleSync(); + verify(mCallbacks).appTransitionStarting(eq(1L), eq(2L)); + } + + @Test + public void testAppTransitionFinished() { + mCommandQueue.appTransitionFinished(); + waitForIdleSync(); + verify(mCallbacks).appTransitionFinished(); + } + + @Test + public void testAssistDisclosure() { + mCommandQueue.showAssistDisclosure(); + waitForIdleSync(); + verify(mCallbacks).showAssistDisclosure(); + } + + @Test + public void testStartAssist() { + Bundle b = new Bundle(); + mCommandQueue.startAssist(b); + waitForIdleSync(); + verify(mCallbacks).startAssist(eq(b)); + } + + @Test + public void testCameraLaunchGesture() { + mCommandQueue.onCameraLaunchGestureDetected(1); + waitForIdleSync(); + verify(mCallbacks).onCameraLaunchGestureDetected(eq(1)); + } + + @Test + public void testShowTvPipMenu() { + mCommandQueue.showTvPictureInPictureMenu(); + waitForIdleSync(); + verify(mCallbacks).showTvPictureInPictureMenu(); + } + + @Test + public void testAddQsTile() { + ComponentName c = new ComponentName("testpkg", "testcls"); + mCommandQueue.addQsTile(c); + waitForIdleSync(); + verify(mCallbacks).addQsTile(eq(c)); + } + + @Test + public void testRemoveQsTile() { + ComponentName c = new ComponentName("testpkg", "testcls"); + mCommandQueue.remQsTile(c); + waitForIdleSync(); + verify(mCallbacks).remQsTile(eq(c)); + } + + @Test + public void testClickQsTile() { + ComponentName c = new ComponentName("testpkg", "testcls"); + mCommandQueue.clickQsTile(c); + waitForIdleSync(); + verify(mCallbacks).clickTile(eq(c)); + } + + @Test + public void testToggleAppSplitScreen() { + mCommandQueue.toggleSplitScreen(); + waitForIdleSync(); + verify(mCallbacks).toggleSplitScreen(); + } + + @Test + public void testHandleSysnavKey() { + mCommandQueue.handleSystemNavigationKey(1); + waitForIdleSync(); + verify(mCallbacks).handleSystemNavigationKey(eq(1)); + } +}