diff --git a/packages/SystemUI/res/layout/idle_host_view.xml b/packages/SystemUI/res/layout/idle_host_view.xml
new file mode 100644
index 0000000000000..f4078742c916a
--- /dev/null
+++ b/packages/SystemUI/res/layout/idle_host_view.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index da0010e9ddffc..281eee65ec544 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -73,7 +73,12 @@
layout="@layout/keyguard_status_view"
android:visibility="gone"/>
-
+
+
+
@null
+
+
+ false
+
+
+ 10000
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
index bcc36847d1fe2..5f75d86a94637 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
+++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
@@ -16,13 +16,32 @@
package com.android.systemui.communal.dagger;
+import android.content.Context;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.systemui.idle.dagger.IdleViewComponent;
+
+import javax.inject.Named;
+
import dagger.Module;
+import dagger.Provides;
/**
* Dagger Module providing Communal-related functionality.
*/
@Module(subcomponents = {
CommunalViewComponent.class,
+ IdleViewComponent.class,
})
-public class CommunalModule {
+public interface CommunalModule {
+ String IDLE_VIEW = "idle_view";
+
+ /** */
+ @Provides
+ @Named(IDLE_VIEW)
+ static View provideIdleView(Context context) {
+ FrameLayout view = new FrameLayout(context);
+ return view;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/idle/IdleHostView.java b/packages/SystemUI/src/com/android/systemui/idle/IdleHostView.java
new file mode 100644
index 0000000000000..7d79279799ea1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/idle/IdleHostView.java
@@ -0,0 +1,42 @@
+/*
+ * 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.systemui.idle;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * {@link IdleHostView} houses a surface to be displayed when the device idle.
+ */
+public class IdleHostView extends FrameLayout {
+ public IdleHostView(@NonNull Context context) {
+ this(context, null);
+ }
+
+ public IdleHostView(@NonNull Context context,
+ @Nullable AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public IdleHostView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/idle/IdleHostViewController.java b/packages/SystemUI/src/com/android/systemui/idle/IdleHostViewController.java
new file mode 100644
index 0000000000000..78d1045837a19
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/idle/IdleHostViewController.java
@@ -0,0 +1,281 @@
+/*
+ * 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.systemui.idle;
+
+import static com.android.systemui.communal.dagger.CommunalModule.IDLE_VIEW;
+
+import android.annotation.IntDef;
+import android.content.res.Resources;
+import android.os.Looper;
+import android.util.Log;
+import android.view.Choreographer;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shared.system.InputMonitorCompat;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.ViewController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+
+/**
+ * {@link IdleHostViewController} processes signals to control the lifecycle of the idle screen.
+ */
+public class IdleHostViewController extends ViewController {
+ private static final String INPUT_MONITOR_IDENTIFIER = "IdleHostViewController";
+ private static final String TAG = "IdleHostViewController";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @IntDef({STATE_IDLE_MODE_ENABLED, STATE_DOZING, STATE_KEYGUARD_SHOWING, STATE_IDLING})
+ public @interface State {}
+
+ // Set at construction to indicate idle mode is available.
+ private static final int STATE_IDLE_MODE_ENABLED = 1 << 0;
+
+ // Set when the device has entered a system level dream.
+ private static final int STATE_DOZING = 1 << 1;
+
+ // Set when the keyguard is showing.
+ private static final int STATE_KEYGUARD_SHOWING = 1 << 2;
+
+ // Set when input monitoring has established the device is now idling.
+ private static final int STATE_IDLING = 1 << 3;
+
+ // The state the controller must be in to start recognizing idleness (lack of input
+ // interaction).
+ private static final int CONDITIONS_IDLE_MONITORING =
+ STATE_IDLE_MODE_ENABLED | STATE_KEYGUARD_SHOWING;
+
+ // The state the controller must be in before entering idle mode.
+ private static final int CONDITIONS_IDLING = CONDITIONS_IDLE_MONITORING | STATE_IDLING;
+
+ // The aggregate current state.
+ private int mState;
+ private boolean mIdleModeActive;
+
+ // Timeout to idle in milliseconds.
+ private final int mIdleTimeout;
+
+ // Factory for generating input listeners.
+ private final InputMonitorFactory mInputMonitorFactory;
+
+ // Delayable executor.
+ private final DelayableExecutor mDelayableExecutor;
+
+ // Runnable for canceling enabling idle.
+ private Runnable mCancelEnableIdling;
+
+ // Keyguard state controller for monitoring keyguard show state.
+ private final KeyguardStateController mKeyguardStateController;
+
+ // Status bar state controller for monitoring when the device is dozing.
+ private final StatusBarStateController mStatusBarStateController;
+
+ // Looper to use for monitoring input.
+ private final Looper mLooper;
+
+ // Choreographer to use for monitoring input.
+ private final Choreographer mChoreographer;
+
+ // Monitor for tracking touches for activity.
+ private InputMonitorCompat mInputMonitor;
+
+ // Delayed callback for enabling idle mode.
+ private final Runnable mEnableIdlingCallback = () -> {
+ if (DEBUG) {
+ Log.d(TAG, "enabling idle");
+ }
+ setState(STATE_IDLING, true);
+ };
+
+ private final KeyguardStateController.Callback mKeyguardCallback =
+ new KeyguardStateController.Callback() {
+ @Override
+ public void onKeyguardShowingChanged() {
+ setState(STATE_KEYGUARD_SHOWING, mKeyguardStateController.isShowing());
+ }
+ };
+
+ private final StatusBarStateController.StateListener mStatusBarCallback =
+ new StatusBarStateController.StateListener() {
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ setState(STATE_DOZING, isDozing);
+ }
+ };
+
+ final Provider mIdleViewProvider;
+
+ @Inject
+ protected IdleHostViewController(
+ IdleHostView view, InputMonitorFactory factory,
+ @Main DelayableExecutor delayableExecutor,
+ @Main Resources resources,
+ @Main Looper looper,
+ @Named(IDLE_VIEW) Provider idleViewProvider,
+ Choreographer choreographer,
+ KeyguardStateController keyguardStateController,
+ StatusBarStateController statusBarStateController) {
+ super(view);
+ mIdleViewProvider = idleViewProvider;
+ mKeyguardStateController = keyguardStateController;
+ mStatusBarStateController = statusBarStateController;
+ mLooper = looper;
+ mChoreographer = choreographer;
+
+ final boolean enabled = resources.getBoolean(R.bool.config_enableIdleMode);
+ if (enabled) {
+ mState |= STATE_IDLE_MODE_ENABLED;
+ }
+
+ setState(mState, true);
+
+ mIdleTimeout = resources.getInteger(R.integer.config_idleModeTimeout);
+ mInputMonitorFactory = factory;
+ mDelayableExecutor = delayableExecutor;
+
+ if (DEBUG) {
+ Log.d(TAG, "initial state:" + mState + " enabled:" + enabled
+ + " timeout:" + mIdleTimeout);
+ }
+ }
+
+ @Override
+ public void init() {
+ super.init();
+
+ setState(STATE_KEYGUARD_SHOWING, mKeyguardStateController.isShowing());
+ setState(STATE_DOZING, mStatusBarStateController.isDozing());
+ }
+
+ private void setState(@State int state, boolean active) {
+ final int oldState = mState;
+
+ if (active) {
+ mState |= state;
+ } else {
+ mState &= ~state;
+ }
+
+ // If we have entered doze or no longer match the preconditions for idling, remove idling.
+ if ((mState & STATE_DOZING) == STATE_DOZING
+ || (mState & CONDITIONS_IDLE_MONITORING) != CONDITIONS_IDLE_MONITORING) {
+ mState &= ~STATE_IDLING;
+ }
+
+ if (oldState == mState) {
+ return;
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "state changed from " + oldState + " to " + mState);
+ }
+
+ enableIdleMonitoring(mState == CONDITIONS_IDLE_MONITORING);
+ enableIdleMode(mState == CONDITIONS_IDLING);
+ }
+
+ private void enableIdleMonitoring(boolean enable) {
+ if (enable && mInputMonitor == null) {
+ if (DEBUG) {
+ Log.d(TAG, "enable idle monitoring");
+ }
+ // Set initial timeout to idle.
+ mCancelEnableIdling = mDelayableExecutor.executeDelayed(mEnableIdlingCallback,
+ mIdleTimeout);
+
+ // Monitor - any input should reset timer
+ mInputMonitor = mInputMonitorFactory.getInputMonitor(INPUT_MONITOR_IDENTIFIER);
+ mInputMonitor.getInputReceiver(mLooper, mChoreographer,
+ v -> {
+ if (DEBUG) {
+ Log.d(TAG, "touch detected, reseting timeout");
+ }
+ // When input is received, reset timeout.
+ if (mCancelEnableIdling != null) {
+ mCancelEnableIdling.run();
+ mCancelEnableIdling = null;
+ }
+ mCancelEnableIdling = mDelayableExecutor.executeDelayed(
+ mEnableIdlingCallback, mIdleTimeout);
+ });
+ } else if (!enable && mInputMonitor != null) {
+ if (DEBUG) {
+ Log.d(TAG, "disable idle monitoring");
+ }
+ // Clean up idle callback and touch monitoring.
+ if (mCancelEnableIdling != null) {
+ mCancelEnableIdling.run();
+ mCancelEnableIdling = null;
+ }
+
+ mInputMonitor.dispose();
+ mInputMonitor = null;
+ }
+ }
+
+ private void enableIdleMode(boolean enable) {
+ if (mIdleModeActive == enable) {
+ return;
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "enable idle mode:" + enable);
+ }
+
+ mIdleModeActive = enable;
+ mDelayableExecutor.execute(() -> {
+ mView.setVisibility(mIdleModeActive ? View.VISIBLE : View.GONE);
+
+ if (mIdleModeActive) {
+ final View idleView = mIdleViewProvider.get();
+ idleView.setLayoutParams(
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
+ mView.addView(idleView);
+ } else {
+ mView.removeAllViews();
+ }
+ });
+ }
+
+ @Override
+ protected void onViewAttached() {
+ if (DEBUG) {
+ Log.d(TAG, "onViewAttached");
+ }
+
+ mKeyguardStateController.addCallback(mKeyguardCallback);
+ mStatusBarStateController.addCallback(mStatusBarCallback);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mKeyguardStateController.removeCallback(mKeyguardCallback);
+ mStatusBarStateController.removeCallback(mStatusBarCallback);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/idle/InputMonitorFactory.java b/packages/SystemUI/src/com/android/systemui/idle/InputMonitorFactory.java
new file mode 100644
index 0000000000000..be0a378d10a54
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/idle/InputMonitorFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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.systemui.idle;
+
+import com.android.systemui.dagger.qualifiers.DisplayId;
+import com.android.systemui.shared.system.InputMonitorCompat;
+
+import javax.inject.Inject;
+
+/**
+ * {@link InputMonitorFactory} generates instances of {@link InputMonitorCompat}.
+ */
+public class InputMonitorFactory {
+ private final int mDisplayId;
+
+ @Inject
+ public InputMonitorFactory(@DisplayId int displayId) {
+ mDisplayId = displayId;
+ }
+
+ /**
+ * Generates a new {@link InputMonitorCompat}.
+ *
+ * @param identifier Identifier to generate monitor with.
+ * @return A {@link InputMonitorCompat} instance.
+ */
+ public InputMonitorCompat getInputMonitor(String identifier) {
+ return new InputMonitorCompat(identifier, mDisplayId);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/idle/dagger/IdleViewComponent.java b/packages/SystemUI/src/com/android/systemui/idle/dagger/IdleViewComponent.java
new file mode 100644
index 0000000000000..9754b1f009f5f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/idle/dagger/IdleViewComponent.java
@@ -0,0 +1,38 @@
+/*
+ * 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.systemui.idle.dagger;
+
+import com.android.systemui.idle.IdleHostView;
+import com.android.systemui.idle.IdleHostViewController;
+
+import dagger.BindsInstance;
+import dagger.Subcomponent;
+
+/**
+ * Subcomponent for working with {@link IdleHostView}.
+ */
+@Subcomponent
+public interface IdleViewComponent {
+ /** Simple factory for {@link Factory}. */
+ @Subcomponent.Factory
+ interface Factory {
+ IdleViewComponent build(@BindsInstance IdleHostView idleHostView);
+ }
+
+ /** Builds a {@link IdleHostViewController}. */
+ IdleHostViewController getIdleHostViewController();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 98d31ab68bb47..358da4069df8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -117,6 +117,9 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.idle.IdleHostView;
+import com.android.systemui.idle.IdleHostViewController;
+import com.android.systemui.idle.dagger.IdleViewComponent;
import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
@@ -332,6 +335,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
private final KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
+ private final IdleViewComponent.Factory mIdleViewComponentFactory;
private final QSDetailDisplayer mQSDetailDisplayer;
private final FragmentService mFragmentService;
private final ScrimController mScrimController;
@@ -365,6 +369,8 @@ public class NotificationPanelViewController extends PanelViewController {
@Nullable
private CommunalHostViewController mCommunalViewController;
private KeyguardStatusViewController mKeyguardStatusViewController;
+ @Nullable
+ private IdleHostViewController mIdleHostViewController;
private LockIconViewController mLockIconViewController;
private NotificationsQuickSettingsContainer mNotificationContainerParent;
private boolean mAnimateNextPositionUpdate;
@@ -745,6 +751,7 @@ public class NotificationPanelViewController extends PanelViewController {
KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory,
CommunalViewComponent.Factory communalViewComponentFactory,
+ IdleViewComponent.Factory idleViewComponentFactory,
LockscreenShadeTransitionController lockscreenShadeTransitionController,
QSDetailDisplayer qsDetailDisplayer,
NotificationGroupManagerLegacy groupManager,
@@ -792,6 +799,7 @@ public class NotificationPanelViewController extends PanelViewController {
mCommunalViewComponentFactory = communalViewComponentFactory;
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
+ mIdleViewComponentFactory = idleViewComponentFactory;
mDepthController = notificationShadeDepthController;
mContentResolver = contentResolver;
mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory;
@@ -914,7 +922,8 @@ public class NotificationPanelViewController extends PanelViewController {
userAvatarView,
mKeyguardStatusBar,
keyguardUserSwitcherView,
- mCommunalView);
+ mCommunalView,
+ mView.findViewById(R.id.idle_host_view));
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
NotificationStackScrollLayout stackScrollLayout = mView.findViewById(
R.id.notification_stack_scroller);
@@ -1007,13 +1016,18 @@ public class NotificationPanelViewController extends PanelViewController {
UserAvatarView userAvatarView,
KeyguardStatusBarView keyguardStatusBarView,
KeyguardUserSwitcherView keyguardUserSwitcherView,
- CommunalHostView communalView) {
+ CommunalHostView communalView,
+ IdleHostView idleHostView) {
// Re-associate the KeyguardStatusViewController
KeyguardStatusViewComponent statusViewComponent =
mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController();
mKeyguardStatusViewController.init();
+ IdleViewComponent idleViewComponent = mIdleViewComponentFactory.build(idleHostView);
+ mIdleHostViewController = idleViewComponent.getIdleHostViewController();
+ mIdleHostViewController.init();
+
KeyguardStatusBarViewComponent statusBarViewComponent =
mKeyguardStatusBarViewComponentFactory.build(keyguardStatusBarView);
if (mKeyguardStatusBarViewController != null) {
@@ -1191,7 +1205,8 @@ public class NotificationPanelViewController extends PanelViewController {
mBigClockContainer.removeAllViews();
updateViewControllers(mView.findViewById(R.id.keyguard_status_view), userAvatarView,
- mKeyguardStatusBar, keyguardUserSwitcherView, mCommunalView);
+ mKeyguardStatusBar, keyguardUserSwitcherView, mCommunalView,
+ mView.findViewById(R.id.idle_host_view));
// Update keyguard bottom area
int index = mView.indexOfChild(mKeyguardBottomArea);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 20b61926a0f0f..13fb44bf2166f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -97,6 +97,8 @@ import com.android.systemui.controls.dagger.ControlsComponent;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.idle.IdleHostViewController;
+import com.android.systemui.idle.dagger.IdleViewComponent;
import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
@@ -245,6 +247,12 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Mock
private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
@Mock
+ private IdleViewComponent.Factory mIdleViewComponentFactory;
+ @Mock
+ private IdleViewComponent mIdleViewComponent;
+ @Mock
+ private IdleHostViewController mIdleHostViewController;
+ @Mock
private QSDetailDisplayer mQSDetailDisplayer;
@Mock
private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
@@ -416,6 +424,10 @@ public class NotificationPanelViewTest extends SysuiTestCase {
.thenReturn(mCommunalViewComponent);
when(mCommunalViewComponent.getCommunalHostViewController())
.thenReturn(mCommunalHostViewController);
+ when(mIdleViewComponentFactory.build(any()))
+ .thenReturn(mIdleViewComponent);
+ when(mIdleViewComponent.getIdleHostViewController())
+ .thenReturn(mIdleHostViewController);
when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean()))
.thenReturn(mKeyguardStatusView);
when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean()))
@@ -444,6 +456,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mKeyguardUserSwitcherComponentFactory,
mKeyguardStatusBarViewComponentFactory,
mCommunalViewComponentFactory,
+ mIdleViewComponentFactory,
mLockscreenShadeTransitionController,
mQSDetailDisplayer,
mGroupManager,