Merge changes from topic "b168904199-qs-injection"
* changes: 5/N Rename QSFooterImpl to QSFooterView 4/N Remove ActivityStarter from QSFooterImpl. 3/N Remove DevProvCtrl & UserTracker from QSFooter 2/N Move UserInfoController out of QSFooterImpl 1/N Add Controller for QSFooter
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
-->
|
||||
|
||||
<!-- Extends FrameLayout -->
|
||||
<com.android.systemui.qs.QSFooterImpl
|
||||
<com.android.systemui.qs.QSFooterView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/qs_footer"
|
||||
android:layout_width="match_parent"
|
||||
@@ -130,4 +130,4 @@
|
||||
</com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
|
||||
</com.android.keyguard.AlphaOptimizedLinearLayout>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.qs.QSFooterImpl>
|
||||
</com.android.systemui.qs.QSFooterView>
|
||||
|
||||
@@ -76,7 +76,7 @@ public class QSDetail extends LinearLayout {
|
||||
private int mOpenY;
|
||||
private boolean mAnimatingOpen;
|
||||
private boolean mSwitchState;
|
||||
private View mFooter;
|
||||
private QSFooter mFooter;
|
||||
|
||||
public QSDetail(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -120,7 +120,8 @@ public class QSDetail extends LinearLayout {
|
||||
mDetailDoneButton.setOnClickListener(doneListener);
|
||||
}
|
||||
|
||||
public void setQsPanel(QSPanel panel, QuickStatusBarHeader header, View footer) {
|
||||
/** */
|
||||
public void setQsPanel(QSPanel panel, QuickStatusBarHeader header, QSFooter footer) {
|
||||
mQsPanel = panel;
|
||||
mHeader = header;
|
||||
mFooter = footer;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* 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.
|
||||
@@ -11,19 +11,14 @@
|
||||
* 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
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.qs;
|
||||
|
||||
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
|
||||
|
||||
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
@@ -36,50 +31,27 @@ import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.development.DevelopmentSettingsEnabler;
|
||||
import com.android.settingslib.drawable.UserIconDrawable;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.R.dimen;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.qs.TouchAnimator.Builder;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.MultiUserSwitch;
|
||||
import com.android.systemui.statusbar.phone.SettingsButton;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.statusbar.policy.UserInfoController;
|
||||
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
OnClickListener, OnUserInfoChangedListener {
|
||||
|
||||
private static final String TAG = "QSFooterImpl";
|
||||
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final UserInfoController mUserInfoController;
|
||||
private final DeviceProvisionedController mDeviceProvisionedController;
|
||||
private final UserTracker mUserTracker;
|
||||
/** */
|
||||
public class QSFooterView extends FrameLayout {
|
||||
private SettingsButton mSettingsButton;
|
||||
protected View mSettingsContainer;
|
||||
private PageIndicator mPageIndicator;
|
||||
@@ -87,7 +59,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
private boolean mShouldShowBuildText;
|
||||
|
||||
private boolean mQsDisabled;
|
||||
private QSPanel mQsPanel;
|
||||
private QuickQSPanel mQuickQsPanel;
|
||||
|
||||
private boolean mExpanded;
|
||||
@@ -117,39 +88,19 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
}
|
||||
};
|
||||
|
||||
@Inject
|
||||
public QSFooterImpl(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
|
||||
ActivityStarter activityStarter, UserInfoController userInfoController,
|
||||
DeviceProvisionedController deviceProvisionedController, UserTracker userTracker) {
|
||||
public QSFooterView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mActivityStarter = activityStarter;
|
||||
mUserInfoController = userInfoController;
|
||||
mDeviceProvisionedController = deviceProvisionedController;
|
||||
mUserTracker = userTracker;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public QSFooterImpl(Context context, AttributeSet attrs) {
|
||||
this(context, attrs,
|
||||
Dependency.get(ActivityStarter.class),
|
||||
Dependency.get(UserInfoController.class),
|
||||
Dependency.get(DeviceProvisionedController.class),
|
||||
Dependency.get(UserTracker.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mEdit = findViewById(android.R.id.edit);
|
||||
mEdit.setOnClickListener(view ->
|
||||
mActivityStarter.postQSRunnableDismissingKeyguard(() ->
|
||||
mQsPanel.showEdit(view)));
|
||||
|
||||
mPageIndicator = findViewById(R.id.footer_page_indicator);
|
||||
|
||||
mSettingsButton = findViewById(R.id.settings_button);
|
||||
mSettingsContainer = findViewById(R.id.settings_button_container);
|
||||
mSettingsButton.setOnClickListener(this);
|
||||
|
||||
mMultiUserSwitch = findViewById(R.id.multi_user_switch);
|
||||
mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
|
||||
@@ -157,19 +108,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
mActionsContainer = findViewById(R.id.qs_footer_actions_container);
|
||||
mEditContainer = findViewById(R.id.qs_footer_actions_edit_container);
|
||||
mBuildText = findViewById(R.id.build);
|
||||
mBuildText.setOnLongClickListener(view -> {
|
||||
CharSequence buildText = mBuildText.getText();
|
||||
if (!TextUtils.isEmpty(buildText)) {
|
||||
ClipboardManager service =
|
||||
mUserTracker.getUserContext().getSystemService(ClipboardManager.class);
|
||||
String label = mContext.getString(R.string.build_number_clip_data_label);
|
||||
service.setPrimaryClip(ClipData.newPlainText(label, buildText));
|
||||
Toast.makeText(mContext, R.string.build_number_copy_toast, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// RenderThread is doing more harm than good when touching the header (to expand quick
|
||||
// settings), so disable it for this view
|
||||
@@ -180,7 +118,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight,
|
||||
oldBottom) -> updateAnimator(right - left));
|
||||
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
|
||||
updateEverything();
|
||||
setBuildText();
|
||||
}
|
||||
|
||||
@@ -249,24 +186,22 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeyguardShowing(boolean keyguardShowing) {
|
||||
/** */
|
||||
public void setKeyguardShowing() {
|
||||
setExpansion(mExpansionAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpandClickListener(OnClickListener onClickListener) {
|
||||
mExpandClickListener = onClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpanded(boolean expanded) {
|
||||
void setExpanded(boolean expanded, boolean isTunerEnabled) {
|
||||
if (mExpanded == expanded) return;
|
||||
mExpanded = expanded;
|
||||
updateEverything();
|
||||
updateEverything(isTunerEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
/** */
|
||||
public void setExpansion(float headerExpansionFraction) {
|
||||
mExpansionAmount = headerExpansionFraction;
|
||||
if (mSettingsCogAnimator != null) mSettingsCogAnimator.setPosition(headerExpansionFraction);
|
||||
@@ -287,18 +222,16 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
@Override
|
||||
@VisibleForTesting
|
||||
public void onDetachedFromWindow() {
|
||||
setListening(false);
|
||||
mContext.getContentResolver().unregisterContentObserver(mDeveloperSettingsObserver);
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
/** */
|
||||
public void setListening(boolean listening) {
|
||||
if (listening == mListening) {
|
||||
return;
|
||||
}
|
||||
mListening = listening;
|
||||
updateListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -318,17 +251,16 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(int state1, int state2, boolean animate) {
|
||||
void disable(int state2, boolean isTunerEnabled) {
|
||||
final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
|
||||
if (disabled == mQsDisabled) return;
|
||||
mQsDisabled = disabled;
|
||||
updateEverything();
|
||||
updateEverything(isTunerEnabled);
|
||||
}
|
||||
|
||||
public void updateEverything() {
|
||||
void updateEverything(boolean isTunerEnabled) {
|
||||
post(() -> {
|
||||
updateVisibilities();
|
||||
updateVisibilities(isTunerEnabled);
|
||||
updateClickabilities();
|
||||
setClickable(false);
|
||||
});
|
||||
@@ -341,11 +273,10 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
mBuildText.setLongClickable(mBuildText.getVisibility() == View.VISIBLE);
|
||||
}
|
||||
|
||||
private void updateVisibilities() {
|
||||
private void updateVisibilities(boolean isTunerEnabled) {
|
||||
mSettingsContainer.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
|
||||
mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
|
||||
TunerService.isTunerEnabled(mContext, mUserTracker.getUserHandle()) ? View.VISIBLE
|
||||
: View.INVISIBLE);
|
||||
isTunerEnabled ? View.VISIBLE : View.INVISIBLE);
|
||||
final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
|
||||
mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.INVISIBLE);
|
||||
mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
|
||||
@@ -358,78 +289,22 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
return mExpanded && mMultiUserSwitch.isMultiUserEnabled();
|
||||
}
|
||||
|
||||
private void updateListeners() {
|
||||
if (mListening) {
|
||||
mUserInfoController.addCallback(this);
|
||||
} else {
|
||||
mUserInfoController.removeCallback(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
/** */
|
||||
public void setQSPanel(final QSPanel qsPanel) {
|
||||
mQsPanel = qsPanel;
|
||||
if (mQsPanel != null) {
|
||||
if (qsPanel != null) {
|
||||
mMultiUserSwitch.setQsPanel(qsPanel);
|
||||
mQsPanel.setFooterPageIndicator(mPageIndicator);
|
||||
qsPanel.setFooterPageIndicator(mPageIndicator);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQQSPanel(@Nullable QuickQSPanel panel) {
|
||||
mQuickQsPanel = panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// Don't do anything until view are unhidden
|
||||
if (!mExpanded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (v == mSettingsButton) {
|
||||
if (!mDeviceProvisionedController.isCurrentUserSetup()) {
|
||||
// If user isn't setup just unlock the device and dump them back at SUW.
|
||||
mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
|
||||
});
|
||||
return;
|
||||
}
|
||||
MetricsLogger.action(mContext,
|
||||
mExpanded ? MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH
|
||||
: MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH);
|
||||
if (mSettingsButton.isTunerClick()) {
|
||||
mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
|
||||
if (TunerService.isTunerEnabled(mContext, mUserTracker.getUserHandle())) {
|
||||
TunerService.showResetRequest(mContext, mUserTracker.getUserHandle(),
|
||||
() -> {
|
||||
// Relaunch settings so that the tuner disappears.
|
||||
startSettingsActivity();
|
||||
});
|
||||
} else {
|
||||
Toast.makeText(getContext(), R.string.tuner_toast,
|
||||
Toast.LENGTH_LONG).show();
|
||||
TunerService.setTunerEnabled(mContext, mUserTracker.getUserHandle(), true);
|
||||
}
|
||||
startSettingsActivity();
|
||||
|
||||
});
|
||||
} else {
|
||||
startSettingsActivity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startSettingsActivity() {
|
||||
mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
|
||||
true /* dismissShade */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
|
||||
if (picture != null &&
|
||||
UserManager.get(mContext).isGuestUser(KeyguardUpdateMonitor.getCurrentUser()) &&
|
||||
!(picture instanceof UserIconDrawable)) {
|
||||
picture = picture.getConstantState().newDrawable(mContext.getResources()).mutate();
|
||||
void onUserInfoChanged(Drawable picture, boolean isGuestUser) {
|
||||
if (picture != null && isGuestUser && !(picture instanceof UserIconDrawable)) {
|
||||
picture = picture.getConstantState().newDrawable(getResources()).mutate();
|
||||
picture.setColorFilter(
|
||||
Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorForeground),
|
||||
Mode.SRC_IN);
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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.qs;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
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.plugins.ActivityStarter;
|
||||
import com.android.systemui.qs.dagger.QSScope;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.SettingsButton;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.statusbar.policy.UserInfoController;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.util.ViewController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Controller for {@link QSFooterView}.
|
||||
*/
|
||||
@QSScope
|
||||
public class QSFooterViewController extends ViewController<QSFooterView> implements QSFooter {
|
||||
|
||||
private final UserManager mUserManager;
|
||||
private final UserInfoController mUserInfoController;
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final DeviceProvisionedController mDeviceProvisionedController;
|
||||
private final UserTracker mUserTracker;
|
||||
private final QSPanelController mQsPanelController;
|
||||
private final TunerService mTunerService;
|
||||
private final MetricsLogger mMetricsLogger;
|
||||
private final SettingsButton mSettingsButton;
|
||||
private final TextView mBuildText;
|
||||
private final View mEdit;
|
||||
|
||||
private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener =
|
||||
new UserInfoController.OnUserInfoChangedListener() {
|
||||
@Override
|
||||
public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
|
||||
boolean isGuestUser = mUserManager.isGuestUser(KeyguardUpdateMonitor.getCurrentUser());
|
||||
mView.onUserInfoChanged(picture, isGuestUser);
|
||||
}
|
||||
};
|
||||
|
||||
private final View.OnClickListener mSettingsOnClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// Don't do anything until view are unhidden
|
||||
if (!mExpanded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (v == mSettingsButton) {
|
||||
if (!mDeviceProvisionedController.isCurrentUserSetup()) {
|
||||
// If user isn't setup just unlock the device and dump them back at SUW.
|
||||
mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
|
||||
});
|
||||
return;
|
||||
}
|
||||
mMetricsLogger.action(
|
||||
mExpanded ? MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH
|
||||
: MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH);
|
||||
if (mSettingsButton.isTunerClick()) {
|
||||
mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
|
||||
if (isTunerEnabled()) {
|
||||
mTunerService.showResetRequest(
|
||||
mUserTracker.getUserHandle(),
|
||||
() -> {
|
||||
// Relaunch settings so that the tuner disappears.
|
||||
startSettingsActivity();
|
||||
});
|
||||
} else {
|
||||
Toast.makeText(getContext(), R.string.tuner_toast,
|
||||
Toast.LENGTH_LONG).show();
|
||||
mTunerService.setTunerEnabled(mUserTracker.getUserHandle(), true);
|
||||
}
|
||||
startSettingsActivity();
|
||||
|
||||
});
|
||||
} else {
|
||||
startSettingsActivity();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private boolean mListening;
|
||||
private boolean mExpanded;
|
||||
|
||||
@Inject
|
||||
QSFooterViewController(QSFooterView view, UserManager userManager,
|
||||
UserInfoController userInfoController, ActivityStarter activityStarter,
|
||||
DeviceProvisionedController deviceProvisionedController, UserTracker userTracker,
|
||||
QSPanelController qsPanelController, TunerService tunerService,
|
||||
MetricsLogger metricsLogger) {
|
||||
super(view);
|
||||
mUserManager = userManager;
|
||||
mUserInfoController = userInfoController;
|
||||
mActivityStarter = activityStarter;
|
||||
mDeviceProvisionedController = deviceProvisionedController;
|
||||
mUserTracker = userTracker;
|
||||
mQsPanelController = qsPanelController;
|
||||
mTunerService = tunerService;
|
||||
mMetricsLogger = metricsLogger;
|
||||
|
||||
mSettingsButton = mView.findViewById(R.id.settings_button);
|
||||
mBuildText = mView.findViewById(R.id.build);
|
||||
mEdit = mView.findViewById(android.R.id.edit);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
mSettingsButton.setOnClickListener(mSettingsOnClickListener);
|
||||
mBuildText.setOnLongClickListener(view -> {
|
||||
CharSequence buildText = mBuildText.getText();
|
||||
if (!TextUtils.isEmpty(buildText)) {
|
||||
ClipboardManager service =
|
||||
mUserTracker.getUserContext().getSystemService(ClipboardManager.class);
|
||||
String label = getResources().getString(R.string.build_number_clip_data_label);
|
||||
service.setPrimaryClip(ClipData.newPlainText(label, buildText));
|
||||
Toast.makeText(getContext(), R.string.build_number_copy_toast, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
mEdit.setOnClickListener(view ->
|
||||
mActivityStarter.postQSRunnableDismissingKeyguard(() ->
|
||||
mQsPanelController.showEdit(view)));
|
||||
|
||||
mView.updateEverything(isTunerEnabled());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
setListening(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setQSPanel(@Nullable QSPanel panel) {
|
||||
mView.setQSPanel(panel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisibility(int visibility) {
|
||||
mView.setVisibility(visibility);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpanded(boolean expanded) {
|
||||
mExpanded = expanded;
|
||||
mView.setExpanded(expanded, isTunerEnabled());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return mView.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpansion(float expansion) {
|
||||
mView.setExpansion(expansion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
if (mListening == listening) {
|
||||
return;
|
||||
}
|
||||
|
||||
mListening = listening;
|
||||
if (mListening) {
|
||||
mUserInfoController.addCallback(mOnUserInfoChangedListener);
|
||||
} else {
|
||||
mUserInfoController.removeCallback(mOnUserInfoChangedListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeyguardShowing(boolean keyguardShowing) {
|
||||
mView.setKeyguardShowing();
|
||||
}
|
||||
|
||||
/** */
|
||||
@Override
|
||||
public void setExpandClickListener(View.OnClickListener onClickListener) {
|
||||
mView.setExpandClickListener(onClickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQQSPanel(@Nullable QuickQSPanel panel) {
|
||||
mView.setQQSPanel(panel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(int state1, int state2, boolean animate) {
|
||||
mView.disable(state2, isTunerEnabled());
|
||||
}
|
||||
|
||||
|
||||
private void startSettingsActivity() {
|
||||
mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
|
||||
true /* dismissShade */);
|
||||
}
|
||||
|
||||
private boolean isTunerEnabled() {
|
||||
return mTunerService.isTunerEnabled(mUserTracker.getUserHandle());
|
||||
}
|
||||
}
|
||||
@@ -142,13 +142,13 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
||||
mQSDetail = view.findViewById(R.id.qs_detail);
|
||||
mHeader = view.findViewById(R.id.header);
|
||||
mQSPanelController.setHeaderContainer(view.findViewById(R.id.header_text_container));
|
||||
mFooter = view.findViewById(R.id.qs_footer);
|
||||
mFooter = qsFragmentComponent.getQSFooter();
|
||||
|
||||
mQSContainerImplController = qsFragmentComponent.getQSContainerImplController();
|
||||
mQSContainerImplController.init();
|
||||
mContainer = mQSContainerImplController.getView();
|
||||
|
||||
mQSDetail.setQsPanel(mQSPanelController.getView(), mHeader, (View) mFooter);
|
||||
mQSDetail.setQsPanel(mQSPanelController.getView(), mHeader, mFooter);
|
||||
mQSAnimator = qsFragmentComponent.getQSAnimator();
|
||||
|
||||
mQSCustomizer = view.findViewById(R.id.qs_customize);
|
||||
|
||||
@@ -20,6 +20,7 @@ import static com.android.systemui.qs.QSPanel.QS_SHOW_BRIGHTNESS;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.res.Configuration;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
@@ -192,4 +193,9 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
|
||||
super.refreshAllTiles();
|
||||
mQsSecurityFooter.refreshState();
|
||||
}
|
||||
|
||||
/** Start customizing the Quick Settings. */
|
||||
public void showEdit(View view) {
|
||||
mView.showEdit(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.qs.dagger;
|
||||
|
||||
import com.android.systemui.qs.QSAnimator;
|
||||
import com.android.systemui.qs.QSContainerImplController;
|
||||
import com.android.systemui.qs.QSFooter;
|
||||
import com.android.systemui.qs.QSFragment;
|
||||
import com.android.systemui.qs.QSPanelController;
|
||||
import com.android.systemui.qs.QuickQSPanelController;
|
||||
@@ -48,4 +49,7 @@ public interface QSFragmentComponent {
|
||||
|
||||
/** Construct a {@link QSContainerImplController}. */
|
||||
QSContainerImplController getQSContainerImplController();
|
||||
|
||||
/** Construct a {@link QSFooter} */
|
||||
QSFooter getQSFooter();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.RootView;
|
||||
import com.android.systemui.plugins.qs.QS;
|
||||
import com.android.systemui.qs.QSContainerImpl;
|
||||
import com.android.systemui.qs.QSFooter;
|
||||
import com.android.systemui.qs.QSFooterView;
|
||||
import com.android.systemui.qs.QSFooterViewController;
|
||||
import com.android.systemui.qs.QSFragment;
|
||||
import com.android.systemui.qs.QSPanel;
|
||||
import com.android.systemui.qs.QuickQSPanel;
|
||||
@@ -70,4 +73,18 @@ public interface QSFragmentModule {
|
||||
static QuickQSPanel providesQuickQSPanel(QuickStatusBarHeader quickStatusBarHeader) {
|
||||
return quickStatusBarHeader.findViewById(R.id.quick_qs_panel);
|
||||
}
|
||||
|
||||
/** */
|
||||
@Provides
|
||||
static QSFooterView providesQSFooterView(@RootView View view) {
|
||||
return view.findViewById(R.id.qs_footer);
|
||||
}
|
||||
|
||||
/** */
|
||||
@Provides
|
||||
@QSScope
|
||||
static QSFooter providesQSFooter(QSFooterViewController qsFooterViewController) {
|
||||
qsFooterViewController.init();
|
||||
return qsFooterViewController;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
public abstract class TunerService {
|
||||
|
||||
public static final String ACTION_CLEAR = "com.android.systemui.action.CLEAR_TUNER";
|
||||
private final Context mContext;
|
||||
|
||||
public abstract void clearAll();
|
||||
public abstract void destroy();
|
||||
@@ -50,6 +51,10 @@ public abstract class TunerService {
|
||||
void onTuningChanged(String key, String newValue);
|
||||
}
|
||||
|
||||
public TunerService(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
private static Context userContext(Context context, UserHandle user) {
|
||||
try {
|
||||
return context.createPackageContextAsUser(context.getPackageName(), 0, user);
|
||||
@@ -58,6 +63,11 @@ public abstract class TunerService {
|
||||
}
|
||||
}
|
||||
|
||||
/** Enables or disables the tuner for the supplied user. */
|
||||
public void setTunerEnabled(UserHandle user, boolean enabled) {
|
||||
setTunerEnabled(mContext, user, enabled);
|
||||
}
|
||||
|
||||
public static final void setTunerEnabled(Context context, UserHandle user, boolean enabled) {
|
||||
userContext(context, user).getPackageManager().setComponentEnabledSetting(
|
||||
new ComponentName(context, TunerActivity.class),
|
||||
@@ -66,6 +76,11 @@ public abstract class TunerService {
|
||||
PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
|
||||
/** Returns true if the tuner is enabled for the supplied user. */
|
||||
public boolean isTunerEnabled(UserHandle user) {
|
||||
return isTunerEnabled(mContext, user);
|
||||
}
|
||||
|
||||
public static final boolean isTunerEnabled(Context context, UserHandle user) {
|
||||
return userContext(context, user).getPackageManager().getComponentEnabledSetting(
|
||||
new ComponentName(context, TunerActivity.class))
|
||||
@@ -81,6 +96,11 @@ public abstract class TunerService {
|
||||
}
|
||||
}
|
||||
|
||||
/** */
|
||||
public void showResetRequest(UserHandle user, final Runnable onDisabled) {
|
||||
showResetRequest(mContext, user, onDisabled);
|
||||
}
|
||||
|
||||
public static final void showResetRequest(final Context context, UserHandle user,
|
||||
final Runnable onDisabled) {
|
||||
SystemUIDialog dialog = new SystemUIDialog(context);
|
||||
|
||||
@@ -94,6 +94,7 @@ public class TunerServiceImpl extends TunerService {
|
||||
DemoModeController demoModeController,
|
||||
BroadcastDispatcher broadcastDispatcher,
|
||||
UserTracker userTracker) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
mContentResolver = mContext.getContentResolver();
|
||||
mLeakDetector = leakDetector;
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.qs.QSFooterImpl;
|
||||
import com.android.systemui.qs.QSPanel;
|
||||
import com.android.systemui.qs.QuickQSPanel;
|
||||
import com.android.systemui.qs.customize.QSCustomizer;
|
||||
@@ -91,11 +90,6 @@ public class InjectionInflationController {
|
||||
@BindsInstance AttributeSet attributeSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the QSFooterImpl.
|
||||
*/
|
||||
QSFooterImpl createQsFooter();
|
||||
|
||||
/**
|
||||
* Creates the NotificationStackScrollLayout.
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
import android.view.View.OnAttachStateChangeListener;
|
||||
|
||||
@@ -75,6 +77,14 @@ public abstract class ViewController<T extends View> {
|
||||
}
|
||||
}
|
||||
|
||||
protected Context getContext() {
|
||||
return mView.getContext();
|
||||
}
|
||||
|
||||
protected Resources getResources() {
|
||||
return mView.getResources();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the view is attached and a call to {@link #init()} has been made in either order.
|
||||
*/
|
||||
|
||||
@@ -70,7 +70,7 @@ public class QSDetailTest extends SysuiTestCase {
|
||||
mQsDetail = (QSDetail) LayoutInflater.from(mContext).inflate(R.layout.qs_detail, null);
|
||||
mQsPanel = mock(QSPanel.class);
|
||||
mQuickHeader = mock(QuickStatusBarHeader.class);
|
||||
mQsDetail.setQsPanel(mQsPanel, mQuickHeader, mock(View.class));
|
||||
mQsDetail.setQsPanel(mQsPanel, mQuickHeader, mock(QSFooter.class));
|
||||
|
||||
mMockDetailAdapter = mock(DetailAdapter.class);
|
||||
when(mMockDetailAdapter.createDetailView(any(), any(), any()))
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.qs;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.R.id;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.statusbar.policy.UserInfoController;
|
||||
import com.android.systemui.utils.leaks.LeakCheckedTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@RunWithLooper
|
||||
@SmallTest
|
||||
public class QSFooterImplTest extends LeakCheckedTest {
|
||||
|
||||
private QSFooterImpl mFooter;
|
||||
private ActivityStarter mActivityStarter;
|
||||
private DeviceProvisionedController mDeviceProvisionedController;
|
||||
private UserInfoController mUserInfoController;
|
||||
private UserTracker mUserTracker;
|
||||
@Mock
|
||||
private ClipboardManager mClipboardManager;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
|
||||
mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
|
||||
mDeviceProvisionedController = mDependency.injectMockDependency(
|
||||
DeviceProvisionedController.class);
|
||||
mUserInfoController = mDependency.injectMockDependency(UserInfoController.class);
|
||||
mUserTracker = mDependency.injectMockDependency(UserTracker.class);
|
||||
|
||||
mContext.addMockSystemService(ClipboardManager.class, mClipboardManager);
|
||||
|
||||
when(mUserTracker.getUserContext()).thenReturn(mContext);
|
||||
|
||||
TestableLooper.get(this).runWithLooper(
|
||||
() -> mFooter = (QSFooterImpl) LayoutInflater.from(mContext).inflate(
|
||||
R.layout.qs_footer_impl, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildTextCopy() {
|
||||
TextView buildTextView = mFooter.requireViewById(R.id.build);
|
||||
CharSequence buildText = "TEST";
|
||||
buildTextView.setText(buildText);
|
||||
buildTextView.setLongClickable(true);
|
||||
|
||||
buildTextView.performLongClick();
|
||||
|
||||
ArgumentCaptor<ClipData> captor = ArgumentCaptor.forClass(ClipData.class);
|
||||
verify(mClipboardManager).setPrimaryClip(captor.capture());
|
||||
assertThat(captor.getValue().getItemAt(0).getText()).isEqualTo(buildText);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("failing")
|
||||
public void testSettings_UserNotSetup() {
|
||||
View settingsButton = mFooter.findViewById(id.settings_button);
|
||||
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false);
|
||||
|
||||
mFooter.onClick(settingsButton);
|
||||
// Verify Settings wasn't launched.
|
||||
verify(mActivityStarter, never()).startActivity(any(), anyBoolean());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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.qs;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.os.UserManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
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.plugins.ActivityStarter;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.SettingsButton;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.statusbar.policy.UserInfoController;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.utils.leaks.FakeTunerService;
|
||||
import com.android.systemui.utils.leaks.LeakCheckedTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
@SmallTest
|
||||
public class QSFooterViewControllerTest extends LeakCheckedTest {
|
||||
|
||||
@Mock
|
||||
private QSFooterView mView;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private ActivityStarter mActivityStarter;
|
||||
@Mock
|
||||
private DeviceProvisionedController mDeviceProvisionedController;
|
||||
@Mock
|
||||
private UserInfoController mUserInfoController;
|
||||
@Mock
|
||||
private UserTracker mUserTracker;
|
||||
@Mock
|
||||
private QSPanelController mQSPanelController;
|
||||
@Mock
|
||||
private ClipboardManager mClipboardManager;
|
||||
private FakeTunerService mFakeTunerService;
|
||||
private MetricsLogger mMetricsLogger = new FakeMetricsLogger();
|
||||
|
||||
@Mock
|
||||
private SettingsButton mSettingsButton;
|
||||
@Mock
|
||||
private TextView mBuildText;
|
||||
@Mock
|
||||
private View mEdit;
|
||||
|
||||
private QSFooterViewController mController;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
|
||||
|
||||
mFakeTunerService = (FakeTunerService) Dependency.get(TunerService.class);
|
||||
|
||||
mContext.addMockSystemService(ClipboardManager.class, mClipboardManager);
|
||||
|
||||
when(mView.getContext()).thenReturn(mContext);
|
||||
when(mView.getResources()).thenReturn(mContext.getResources());
|
||||
when(mUserTracker.getUserContext()).thenReturn(mContext);
|
||||
|
||||
when(mView.isAttachedToWindow()).thenReturn(true);
|
||||
when(mView.findViewById(R.id.settings_button)).thenReturn(mSettingsButton);
|
||||
when(mView.findViewById(R.id.build)).thenReturn(mBuildText);
|
||||
when(mView.findViewById(android.R.id.edit)).thenReturn(mEdit);
|
||||
|
||||
mController = new QSFooterViewController(mView, mUserManager, mUserInfoController,
|
||||
mActivityStarter, mDeviceProvisionedController, mUserTracker, mQSPanelController,
|
||||
mFakeTunerService, mMetricsLogger);
|
||||
|
||||
mController.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildTextCopy() {
|
||||
String text = "TEST";
|
||||
ArgumentCaptor<View.OnLongClickListener> onLongClickCaptor =
|
||||
ArgumentCaptor.forClass(View.OnLongClickListener.class);
|
||||
|
||||
verify(mBuildText).setOnLongClickListener(onLongClickCaptor.capture());
|
||||
|
||||
when(mBuildText.getText()).thenReturn(text);
|
||||
onLongClickCaptor.getValue().onLongClick(mBuildText);
|
||||
|
||||
ArgumentCaptor<ClipData> captor = ArgumentCaptor.forClass(ClipData.class);
|
||||
verify(mClipboardManager).setPrimaryClip(captor.capture());
|
||||
assertThat(captor.getValue().getItemAt(0).getText()).isEqualTo(text);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettings_UserNotSetup() {
|
||||
ArgumentCaptor<View.OnClickListener> onClickCaptor =
|
||||
ArgumentCaptor.forClass(View.OnClickListener.class);
|
||||
verify(mSettingsButton).setOnClickListener(onClickCaptor.capture());
|
||||
|
||||
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false);
|
||||
|
||||
onClickCaptor.getValue().onClick(mSettingsButton);
|
||||
// Verify Settings wasn't launched.
|
||||
verify(mActivityStarter, never()).startActivity(any(), anyBoolean());
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
package com.android.systemui.utils.leaks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.testing.LeakCheck;
|
||||
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
@@ -22,8 +22,10 @@ import com.android.systemui.tuner.TunerService;
|
||||
public class FakeTunerService extends TunerService {
|
||||
|
||||
private final BaseLeakChecker<Tunable> mBaseLeakChecker;
|
||||
private boolean mEnabled;
|
||||
|
||||
public FakeTunerService(LeakCheck test) {
|
||||
super(null);
|
||||
mBaseLeakChecker = new BaseLeakChecker<>(test, "tunable");
|
||||
}
|
||||
|
||||
@@ -74,4 +76,14 @@ public class FakeTunerService extends TunerService {
|
||||
public void setValue(String setting, int value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTunerEnabled(UserHandle user, boolean enabled) {
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTunerEnabled(UserHandle user) {
|
||||
return mEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user