Add power menu lite
Refactored existing long-press power menu so common elements could be reused. This power menu only includes the standard buttons and can rotate, with different "grid" size based on number of buttons available Bug: 179674461 Test: atest com.android.systemui.globalactions Test: manual, verify layout looks correct with different buttons and rotations Change-Id: I2b61bc0ac2c9a15c4acc639770e4a3799a26c21a
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/global_actions_lite_background"/>
|
||||
<corners android:radius="@dimen/global_actions_corner_radius" />
|
||||
</shape>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="@color/global_actions_lite_button_background"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<com.android.systemui.globalactions.GlobalActionsItem
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:stateListAnimator="@anim/control_state_list_animator">
|
||||
<ImageView
|
||||
android:id="@*android:id/icon"
|
||||
android:layout_width="@dimen/global_actions_button_size"
|
||||
android:layout_height="@dimen/global_actions_button_size"
|
||||
android:layout_marginBottom="@dimen/global_actions_grid_container_bottom_margin"
|
||||
android:padding="@dimen/global_actions_button_padding"
|
||||
android:scaleType="centerInside"
|
||||
android:tint="@color/global_actions_lite_text"
|
||||
android:background="@drawable/global_actions_lite_button"/>
|
||||
<TextView
|
||||
android:id="@*android:id/message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:maxLines="2"
|
||||
android:textSize="12sp"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/global_actions_lite_text"
|
||||
android:breakStrategy="high_quality"
|
||||
android:hyphenationFrequency="full"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
</com.android.systemui.globalactions.GlobalActionsItem>
|
||||
56
packages/SystemUI/res/layout/global_actions_grid_lite.xml
Normal file
56
packages/SystemUI/res/layout/global_actions_grid_lite.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/global_actions_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center">
|
||||
<com.android.systemui.globalactions.GlobalActionsLayoutLite
|
||||
android:id="@id/global_actions_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:background="@drawable/global_actions_lite_background"
|
||||
android:padding="@dimen/global_actions_lite_padding">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@android:id/list"
|
||||
android:gravity="center"
|
||||
android:translationZ="@dimen/global_actions_translate"
|
||||
android:orientation="horizontal"
|
||||
android:layoutDirection="ltr">
|
||||
<androidx.constraintlayout.helper.widget.Flow
|
||||
android:id="@+id/list_flow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:flow_wrapMode="chain"
|
||||
app:flow_maxElementsWrap="2"
|
||||
app:flow_horizontalGap="@dimen/global_actions_lite_padding"
|
||||
app:flow_verticalGap="@dimen/global_actions_lite_padding"
|
||||
app:flow_horizontalStyle="packed"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.android.systemui.globalactions.GlobalActionsLayoutLite>
|
||||
</LinearLayout>
|
||||
@@ -54,6 +54,13 @@
|
||||
<color name="global_actions_emergency_background">@color/GM2_red_400</color>
|
||||
<color name="global_actions_emergency_text">@color/GM2_grey_100</color>
|
||||
|
||||
<!-- Colors for Power Menu Lite -->
|
||||
<color name="global_actions_lite_background">#191C18</color>
|
||||
<color name="global_actions_lite_button_background">#303030</color>
|
||||
<color name="global_actions_lite_text">#F0F0F0</color>
|
||||
<color name="global_actions_lite_emergency_background">#F85D4D</color>
|
||||
<color name="global_actions_lite_emergency_icon">@color/GM2_grey_900</color>
|
||||
|
||||
<color name="global_actions_shutdown_ui_text">@color/control_primary_text</color>
|
||||
|
||||
<!-- Tint color for the content on the notification overflow card. -->
|
||||
|
||||
@@ -553,6 +553,10 @@
|
||||
|
||||
<!-- Max number of columns for power menu -->
|
||||
<integer name="power_menu_max_columns">3</integer>
|
||||
<!-- Max number of columns for power menu lite -->
|
||||
<integer name="power_menu_lite_max_columns">2</integer>
|
||||
<!-- Max number of rows for power menu lite -->
|
||||
<integer name="power_menu_lite_max_rows">4</integer>
|
||||
|
||||
<!-- If the dp width of the available space is <= this value, potentially adjust the number
|
||||
of columns-->
|
||||
|
||||
@@ -1063,6 +1063,12 @@
|
||||
<dimen name="global_actions_power_dialog_item_width">255dp</dimen>
|
||||
<dimen name="global_actions_power_dialog_item_bottom_margin">45dp</dimen>
|
||||
|
||||
<!-- Power Menu Lite -->
|
||||
<dimen name="global_actions_button_size">96dp</dimen>
|
||||
<dimen name="global_actions_button_padding">38dp</dimen>
|
||||
<dimen name="global_actions_corner_radius">28dp</dimen>
|
||||
<dimen name="global_actions_lite_padding">24dp</dimen>
|
||||
|
||||
<!-- The maximum offset in either direction that elements are moved horizontally to prevent
|
||||
burn-in on AOD. -->
|
||||
<dimen name="burn_in_prevention_offset_x">8dp</dimen>
|
||||
|
||||
@@ -395,6 +395,13 @@
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.SystemUI.Dialog.GlobalActionsLite" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar.Fullscreen">
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:backgroundDimEnabled">true</item>
|
||||
<item name="android:windowCloseOnTouchOutside">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.SystemUI.Dialog.MediaOutput">
|
||||
<item name="android:windowBackground">@drawable/media_output_dialog_background</item>
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.globalactions;
|
||||
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.constraintlayout.helper.widget.Flow;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.HardwareBgDrawable;
|
||||
import com.android.systemui.R;
|
||||
|
||||
/**
|
||||
* ConstraintLayout implementation of the button layout created by the global actions dialog.
|
||||
*/
|
||||
public class GlobalActionsLayoutLite extends GlobalActionsLayout {
|
||||
private final int mMaxColumns;
|
||||
private final int mMaxRows;
|
||||
|
||||
public GlobalActionsLayoutLite(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mMaxColumns = getResources().getInteger(
|
||||
com.android.systemui.R.integer.power_menu_lite_max_columns);
|
||||
mMaxRows = getResources().getInteger(
|
||||
com.android.systemui.R.integer.power_menu_lite_max_rows);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Override
|
||||
protected boolean shouldReverseListItems() {
|
||||
// Handled in XML
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HardwareBgDrawable getBackgroundDrawable(int backgroundColor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateList() {
|
||||
super.onUpdateList();
|
||||
int nElementsWrap = (getCurrentRotation() == ROTATION_NONE) ? mMaxColumns : mMaxRows;
|
||||
int nChildren = getListView().getChildCount() - 1; // don't count flow element
|
||||
if (getCurrentRotation() != ROTATION_NONE && nChildren > mMaxRows) {
|
||||
// up to 4 elements can fit in a row in landscape, otherwise limit for balance
|
||||
nElementsWrap -= 1;
|
||||
}
|
||||
Flow flow = findViewById(R.id.list_flow);
|
||||
flow.setMaxElementsWrap(nElementsWrap);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addToListView(View v, boolean reverse) {
|
||||
super.addToListView(v, reverse);
|
||||
Flow flow = findViewById(R.id.list_flow);
|
||||
flow.addView(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeAllListViews() {
|
||||
View flow = findViewById(R.id.list_flow);
|
||||
super.removeAllListViews();
|
||||
|
||||
// Add flow element back after clearing the list view
|
||||
super.addToListView(flow, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
boolean anyTruncated = false;
|
||||
ViewGroup listView = getListView();
|
||||
|
||||
// Check to see if any of the GlobalActionsItems have had their messages truncated
|
||||
for (int i = 0; i < listView.getChildCount(); i++) {
|
||||
View child = listView.getChildAt(i);
|
||||
if (child instanceof GlobalActionsItem) {
|
||||
GlobalActionsItem item = (GlobalActionsItem) child;
|
||||
anyTruncated = anyTruncated || item.isTruncated();
|
||||
}
|
||||
}
|
||||
// If any of the items have been truncated, set the all to single-line marquee
|
||||
if (anyTruncated) {
|
||||
for (int i = 0; i < listView.getChildCount(); i++) {
|
||||
View child = listView.getChildAt(i);
|
||||
if (child instanceof GlobalActionsItem) {
|
||||
GlobalActionsItem item = (GlobalActionsItem) child;
|
||||
item.setMarquee(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected float getGridItemSize() {
|
||||
return getContext().getResources().getDimension(R.dimen.global_actions_grid_item_height);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected float getAnimationDistance() {
|
||||
return getGridItemSize() / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAnimationOffsetX() {
|
||||
return getAnimationDistance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAnimationOffsetY() {
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.globalactions.GlobalActionsDialogLite;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.qs.dagger.QSScope;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
@@ -68,6 +69,7 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
|
||||
private final PageIndicator mPageIndicator;
|
||||
private final View mPowerMenuLite;
|
||||
private final boolean mShowPMLiteButton;
|
||||
private GlobalActionsDialogLite mGlobalActionsDialog;
|
||||
|
||||
private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener =
|
||||
new UserInfoController.OnUserInfoChangedListener() {
|
||||
@@ -115,6 +117,8 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
|
||||
} else {
|
||||
startSettingsActivity();
|
||||
}
|
||||
} else if (v == mPowerMenuLite) {
|
||||
mGlobalActionsDialog.showOrHideDialog(false, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -129,7 +133,8 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
|
||||
QSPanelController qsPanelController, QSDetailDisplayer qsDetailDisplayer,
|
||||
QuickQSPanelController quickQSPanelController,
|
||||
TunerService tunerService, MetricsLogger metricsLogger,
|
||||
@Named(PM_LITE_ENABLED) boolean showPMLiteButton) {
|
||||
@Named(PM_LITE_ENABLED) boolean showPMLiteButton,
|
||||
GlobalActionsDialogLite globalActionsDialog) {
|
||||
super(view);
|
||||
mUserManager = userManager;
|
||||
mUserInfoController = userInfoController;
|
||||
@@ -149,11 +154,15 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
|
||||
mPageIndicator = mView.findViewById(R.id.footer_page_indicator);
|
||||
mPowerMenuLite = mView.findViewById(R.id.pm_lite);
|
||||
mShowPMLiteButton = showPMLiteButton;
|
||||
mGlobalActionsDialog = globalActionsDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
if (!mShowPMLiteButton) {
|
||||
if (mShowPMLiteButton) {
|
||||
mPowerMenuLite.setVisibility(View.VISIBLE);
|
||||
mPowerMenuLite.setOnClickListener(mSettingsOnClickListener);
|
||||
} else {
|
||||
mPowerMenuLite.setVisibility(View.GONE);
|
||||
}
|
||||
mView.addOnLayoutChangeListener(
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.globalactions;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.IActivityManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.trust.TrustManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Handler;
|
||||
import android.os.UserManager;
|
||||
import android.service.dreams.IDreamManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.WindowManagerPolicyConstants;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.colorextraction.ColorExtractor;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
||||
import com.android.systemui.model.SysUiState;
|
||||
import com.android.systemui.plugins.GlobalActions;
|
||||
import com.android.systemui.settings.UserContextProvider;
|
||||
import com.android.systemui.statusbar.NotificationShadeDepthController;
|
||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.util.RingerModeLiveData;
|
||||
import com.android.systemui.util.RingerModeTracker;
|
||||
import com.android.systemui.util.settings.GlobalSettings;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
public class GlobalActionsDialogLiteTest extends SysuiTestCase {
|
||||
private GlobalActionsDialogLite mGlobalActionsDialogLite;
|
||||
|
||||
@Mock private GlobalActions.GlobalActionsManager mWindowManagerFuncs;
|
||||
@Mock private AudioManager mAudioManager;
|
||||
@Mock private IDreamManager mDreamManager;
|
||||
@Mock private DevicePolicyManager mDevicePolicyManager;
|
||||
@Mock private LockPatternUtils mLockPatternUtils;
|
||||
@Mock private BroadcastDispatcher mBroadcastDispatcher;
|
||||
@Mock private TelephonyListenerManager mTelephonyListenerManager;
|
||||
@Mock private GlobalSettings mGlobalSettings;
|
||||
@Mock private SecureSettings mSecureSettings;
|
||||
@Mock private Resources mResources;
|
||||
@Mock private ConfigurationController mConfigurationController;
|
||||
@Mock private KeyguardStateController mKeyguardStateController;
|
||||
@Mock private UserManager mUserManager;
|
||||
@Mock private TrustManager mTrustManager;
|
||||
@Mock private IActivityManager mActivityManager;
|
||||
@Mock private MetricsLogger mMetricsLogger;
|
||||
@Mock private NotificationShadeDepthController mDepthController;
|
||||
@Mock private SysuiColorExtractor mColorExtractor;
|
||||
@Mock private IStatusBarService mStatusBarService;
|
||||
@Mock private NotificationShadeWindowController mNotificationShadeWindowController;
|
||||
@Mock private IWindowManager mWindowManager;
|
||||
@Mock private Executor mBackgroundExecutor;
|
||||
@Mock private UiEventLogger mUiEventLogger;
|
||||
@Mock private RingerModeTracker mRingerModeTracker;
|
||||
@Mock private RingerModeLiveData mRingerModeLiveData;
|
||||
@Mock private SysUiState mSysUiState;
|
||||
@Mock private Handler mHandler;
|
||||
@Mock private UserContextProvider mUserContextProvider;
|
||||
|
||||
private TestableLooper mTestableLooper;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mTestableLooper = TestableLooper.get(this);
|
||||
allowTestableLooperAsMainThread();
|
||||
|
||||
when(mRingerModeTracker.getRingerMode()).thenReturn(mRingerModeLiveData);
|
||||
when(mUserContextProvider.getUserContext()).thenReturn(mContext);
|
||||
|
||||
mGlobalActionsDialogLite = new GlobalActionsDialogLite(mContext,
|
||||
mWindowManagerFuncs,
|
||||
mAudioManager,
|
||||
mDreamManager,
|
||||
mDevicePolicyManager,
|
||||
mLockPatternUtils,
|
||||
mBroadcastDispatcher,
|
||||
mTelephonyListenerManager,
|
||||
mGlobalSettings,
|
||||
mSecureSettings,
|
||||
null,
|
||||
mResources,
|
||||
mConfigurationController,
|
||||
mKeyguardStateController,
|
||||
mUserManager,
|
||||
mTrustManager,
|
||||
mActivityManager,
|
||||
null,
|
||||
mMetricsLogger,
|
||||
mDepthController,
|
||||
mColorExtractor,
|
||||
mStatusBarService,
|
||||
mNotificationShadeWindowController,
|
||||
mWindowManager,
|
||||
mBackgroundExecutor,
|
||||
mUiEventLogger,
|
||||
mRingerModeTracker,
|
||||
mSysUiState,
|
||||
mHandler
|
||||
);
|
||||
mGlobalActionsDialogLite.setZeroDialogPressDelayForTesting();
|
||||
|
||||
ColorExtractor.GradientColors backdropColors = new ColorExtractor.GradientColors();
|
||||
backdropColors.setMainColor(Color.BLACK);
|
||||
when(mColorExtractor.getNeutralColors()).thenReturn(backdropColors);
|
||||
when(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldLogShow() {
|
||||
mGlobalActionsDialogLite.onShow(null);
|
||||
mTestableLooper.processAllMessages();
|
||||
verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_POWER_MENU_OPEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldLogDismiss() {
|
||||
mGlobalActionsDialogLite.onDismiss(mGlobalActionsDialogLite.mDialog);
|
||||
mTestableLooper.processAllMessages();
|
||||
verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_POWER_MENU_CLOSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldLogBugreportPress() throws InterruptedException {
|
||||
GlobalActionsDialog.BugReportAction bugReportAction =
|
||||
mGlobalActionsDialogLite.makeBugReportActionForTesting();
|
||||
bugReportAction.onPress();
|
||||
verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_BUGREPORT_PRESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldLogBugreportLongPress() {
|
||||
GlobalActionsDialog.BugReportAction bugReportAction =
|
||||
mGlobalActionsDialogLite.makeBugReportActionForTesting();
|
||||
bugReportAction.onLongPress();
|
||||
verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_BUGREPORT_LONG_PRESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldLogEmergencyDialerPress() {
|
||||
GlobalActionsDialog.EmergencyDialerAction emergencyDialerAction =
|
||||
mGlobalActionsDialogLite.makeEmergencyDialerActionForTesting();
|
||||
emergencyDialerAction.onPress();
|
||||
verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_EMERGENCY_DIALER_PRESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldLogScreenshotPress() {
|
||||
GlobalActionsDialog.ScreenshotAction screenshotAction =
|
||||
mGlobalActionsDialogLite.makeScreenshotActionForTesting();
|
||||
screenshotAction.onPress();
|
||||
verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_PRESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldShowScreenshot() {
|
||||
mContext.getOrCreateTestableResources().addOverride(
|
||||
com.android.internal.R.integer.config_navBarInteractionMode,
|
||||
WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
GlobalActionsDialog.ScreenshotAction screenshotAction =
|
||||
mGlobalActionsDialogLite.makeScreenshotActionForTesting();
|
||||
assertThat(screenshotAction.shouldShow()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldNotShowScreenshot() {
|
||||
mContext.getOrCreateTestableResources().addOverride(
|
||||
com.android.internal.R.integer.config_navBarInteractionMode,
|
||||
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON);
|
||||
|
||||
GlobalActionsDialog.ScreenshotAction screenshotAction =
|
||||
mGlobalActionsDialogLite.makeScreenshotActionForTesting();
|
||||
assertThat(screenshotAction.shouldShow()).isFalse();
|
||||
}
|
||||
|
||||
private void verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent event) {
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mUiEventLogger, times(1))
|
||||
.log(event);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static <T> void assertItemsOfType(List<T> stuff, Class<? extends T>... classes) {
|
||||
assertThat(stuff).hasSize(classes.length);
|
||||
for (int i = 0; i < stuff.size(); i++) {
|
||||
assertThat(stuff.get(i)).isInstanceOf(classes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateActionItems_lockdownEnabled_doesShowLockdown() {
|
||||
mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
|
||||
doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
|
||||
doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
|
||||
doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
|
||||
String[] actions = {
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
|
||||
};
|
||||
doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
|
||||
mGlobalActionsDialogLite.createActionItems();
|
||||
|
||||
assertItemsOfType(mGlobalActionsDialogLite.mItems,
|
||||
GlobalActionsDialog.EmergencyAction.class,
|
||||
GlobalActionsDialog.LockDownAction.class,
|
||||
GlobalActionsDialog.ShutDownAction.class,
|
||||
GlobalActionsDialog.RestartAction.class);
|
||||
assertThat(mGlobalActionsDialogLite.mOverflowItems).isEmpty();
|
||||
assertThat(mGlobalActionsDialogLite.mPowerItems).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateActionItems_lockdownDisabled_doesNotShowLockdown() {
|
||||
mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
|
||||
doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
|
||||
// make sure lockdown action will NOT be shown
|
||||
doReturn(false).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
|
||||
String[] actions = {
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
|
||||
// lockdown action not allowed
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
|
||||
};
|
||||
doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
|
||||
mGlobalActionsDialogLite.createActionItems();
|
||||
|
||||
assertItemsOfType(mGlobalActionsDialogLite.mItems,
|
||||
GlobalActionsDialog.EmergencyAction.class,
|
||||
GlobalActionsDialog.ShutDownAction.class,
|
||||
GlobalActionsDialog.RestartAction.class);
|
||||
assertThat(mGlobalActionsDialogLite.mOverflowItems).isEmpty();
|
||||
assertThat(mGlobalActionsDialogLite.mPowerItems).isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -33,12 +33,10 @@ import static org.mockito.Mockito.when;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.trust.TrustManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.media.AudioManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserManager;
|
||||
@@ -77,6 +75,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.util.RingerModeLiveData;
|
||||
import com.android.systemui.util.RingerModeTracker;
|
||||
import com.android.systemui.util.settings.GlobalSettings;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -105,9 +104,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
@Mock private DevicePolicyManager mDevicePolicyManager;
|
||||
@Mock private LockPatternUtils mLockPatternUtils;
|
||||
@Mock private BroadcastDispatcher mBroadcastDispatcher;
|
||||
@Mock private ConnectivityManager mConnectivityManager;
|
||||
@Mock private TelephonyListenerManager mTelephonyListenerManager;
|
||||
@Mock private ContentResolver mContentResolver;
|
||||
@Mock private GlobalSettings mGlobalSettings;
|
||||
@Mock private Resources mResources;
|
||||
@Mock private ConfigurationController mConfigurationController;
|
||||
@Mock private ActivityStarter mActivityStarter;
|
||||
@@ -166,9 +164,9 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
mDevicePolicyManager,
|
||||
mLockPatternUtils,
|
||||
mBroadcastDispatcher,
|
||||
mConnectivityManager,
|
||||
mTelephonyListenerManager,
|
||||
mContentResolver,
|
||||
mGlobalSettings,
|
||||
mSecureSettings,
|
||||
null,
|
||||
mResources,
|
||||
mConfigurationController,
|
||||
@@ -520,7 +518,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
|
||||
mGlobalActionsDialog.showOrHideDialog(false, true, mWalletPlugin);
|
||||
|
||||
GlobalActionsDialog.ActionsDialog dialog = mGlobalActionsDialog.mDialog;
|
||||
GlobalActionsDialog.ActionsDialog dialog =
|
||||
(GlobalActionsDialog.ActionsDialog) mGlobalActionsDialog.mDialog;
|
||||
assertThat(dialog).isNotNull();
|
||||
assertThat(dialog.mLockMessageContainer.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
|
||||
@@ -543,7 +542,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
|
||||
mGlobalActionsDialog.showOrHideDialog(false, true, mWalletPlugin);
|
||||
|
||||
GlobalActionsDialog.ActionsDialog dialog = mGlobalActionsDialog.mDialog;
|
||||
GlobalActionsDialog.ActionsDialog dialog =
|
||||
(GlobalActionsDialog.ActionsDialog) mGlobalActionsDialog.mDialog;
|
||||
assertThat(dialog).isNotNull();
|
||||
assertThat(dialog.mLockMessageContainer.getVisibility()).isEqualTo(View.GONE);
|
||||
|
||||
@@ -568,7 +568,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
|
||||
mGlobalActionsDialog.showOrHideDialog(false, true, mWalletPlugin);
|
||||
|
||||
GlobalActionsDialog.ActionsDialog dialog = mGlobalActionsDialog.mDialog;
|
||||
GlobalActionsDialog.ActionsDialog dialog =
|
||||
(GlobalActionsDialog.ActionsDialog) mGlobalActionsDialog.mDialog;
|
||||
assertThat(dialog).isNotNull();
|
||||
assertThat(dialog.mLockMessageContainer.getVisibility()).isEqualTo(View.GONE);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.testing.FakeMetricsLogger;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.globalactions.GlobalActionsDialogLite;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.MultiUserSwitch;
|
||||
@@ -91,6 +92,8 @@ public class QSFooterViewControllerTest extends LeakCheckedTest {
|
||||
private MultiUserSwitch mMultiUserSwitch;
|
||||
@Mock
|
||||
private View mPowerMenuLiteView;
|
||||
@Mock
|
||||
private GlobalActionsDialogLite mGlobalActionsDialog;
|
||||
|
||||
private QSFooterViewController mController;
|
||||
|
||||
@@ -118,7 +121,7 @@ public class QSFooterViewControllerTest extends LeakCheckedTest {
|
||||
mController = new QSFooterViewController(mView, mUserManager, mUserInfoController,
|
||||
mActivityStarter, mDeviceProvisionedController, mUserTracker, mQSPanelController,
|
||||
new QSDetailDisplayer(), mQuickQSPanelController, mFakeTunerService,
|
||||
mMetricsLogger, false);
|
||||
mMetricsLogger, false, mGlobalActionsDialog);
|
||||
|
||||
mController.init();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user