Merge "Add power menu lite" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
6e967422ca
@@ -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. -->
|
||||
|
||||
@@ -570,6 +570,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-->
|
||||
|
||||
@@ -1065,6 +1065,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