Merge "Remove wifi and celluar tiles from qs" into tm-qpr-dev am: 3a85879f13
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20713515 Change-Id: Idd6175f4cfba672dece41e4afafa8b08c4581dae Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -1037,8 +1037,6 @@
|
|||||||
|
|
||||||
<dimen name="ongoing_appops_dialog_side_padding">16dp</dimen>
|
<dimen name="ongoing_appops_dialog_side_padding">16dp</dimen>
|
||||||
|
|
||||||
<!-- Size of the RAT type for CellularTile -->
|
|
||||||
|
|
||||||
<!-- Size of media cards in the QSPanel carousel -->
|
<!-- Size of media cards in the QSPanel carousel -->
|
||||||
<dimen name="qs_media_padding">16dp</dimen>
|
<dimen name="qs_media_padding">16dp</dimen>
|
||||||
<dimen name="qs_media_album_radius">14dp</dimen>
|
<dimen name="qs_media_album_radius">14dp</dimen>
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import com.android.systemui.qs.tiles.BatterySaverTile;
|
|||||||
import com.android.systemui.qs.tiles.BluetoothTile;
|
import com.android.systemui.qs.tiles.BluetoothTile;
|
||||||
import com.android.systemui.qs.tiles.CameraToggleTile;
|
import com.android.systemui.qs.tiles.CameraToggleTile;
|
||||||
import com.android.systemui.qs.tiles.CastTile;
|
import com.android.systemui.qs.tiles.CastTile;
|
||||||
import com.android.systemui.qs.tiles.CellularTile;
|
|
||||||
import com.android.systemui.qs.tiles.ColorCorrectionTile;
|
import com.android.systemui.qs.tiles.ColorCorrectionTile;
|
||||||
import com.android.systemui.qs.tiles.ColorInversionTile;
|
import com.android.systemui.qs.tiles.ColorInversionTile;
|
||||||
import com.android.systemui.qs.tiles.DataSaverTile;
|
import com.android.systemui.qs.tiles.DataSaverTile;
|
||||||
@@ -54,7 +53,6 @@ import com.android.systemui.qs.tiles.ReduceBrightColorsTile;
|
|||||||
import com.android.systemui.qs.tiles.RotationLockTile;
|
import com.android.systemui.qs.tiles.RotationLockTile;
|
||||||
import com.android.systemui.qs.tiles.ScreenRecordTile;
|
import com.android.systemui.qs.tiles.ScreenRecordTile;
|
||||||
import com.android.systemui.qs.tiles.UiModeNightTile;
|
import com.android.systemui.qs.tiles.UiModeNightTile;
|
||||||
import com.android.systemui.qs.tiles.WifiTile;
|
|
||||||
import com.android.systemui.qs.tiles.WorkModeTile;
|
import com.android.systemui.qs.tiles.WorkModeTile;
|
||||||
import com.android.systemui.util.leak.GarbageMonitor;
|
import com.android.systemui.util.leak.GarbageMonitor;
|
||||||
|
|
||||||
@@ -68,10 +66,8 @@ public class QSFactoryImpl implements QSFactory {
|
|||||||
|
|
||||||
private static final String TAG = "QSFactory";
|
private static final String TAG = "QSFactory";
|
||||||
|
|
||||||
private final Provider<WifiTile> mWifiTileProvider;
|
|
||||||
private final Provider<InternetTile> mInternetTileProvider;
|
private final Provider<InternetTile> mInternetTileProvider;
|
||||||
private final Provider<BluetoothTile> mBluetoothTileProvider;
|
private final Provider<BluetoothTile> mBluetoothTileProvider;
|
||||||
private final Provider<CellularTile> mCellularTileProvider;
|
|
||||||
private final Provider<DndTile> mDndTileProvider;
|
private final Provider<DndTile> mDndTileProvider;
|
||||||
private final Provider<ColorCorrectionTile> mColorCorrectionTileProvider;
|
private final Provider<ColorCorrectionTile> mColorCorrectionTileProvider;
|
||||||
private final Provider<ColorInversionTile> mColorInversionTileProvider;
|
private final Provider<ColorInversionTile> mColorInversionTileProvider;
|
||||||
@@ -106,10 +102,8 @@ public class QSFactoryImpl implements QSFactory {
|
|||||||
public QSFactoryImpl(
|
public QSFactoryImpl(
|
||||||
Lazy<QSHost> qsHostLazy,
|
Lazy<QSHost> qsHostLazy,
|
||||||
Provider<CustomTile.Builder> customTileBuilderProvider,
|
Provider<CustomTile.Builder> customTileBuilderProvider,
|
||||||
Provider<WifiTile> wifiTileProvider,
|
|
||||||
Provider<InternetTile> internetTileProvider,
|
Provider<InternetTile> internetTileProvider,
|
||||||
Provider<BluetoothTile> bluetoothTileProvider,
|
Provider<BluetoothTile> bluetoothTileProvider,
|
||||||
Provider<CellularTile> cellularTileProvider,
|
|
||||||
Provider<DndTile> dndTileProvider,
|
Provider<DndTile> dndTileProvider,
|
||||||
Provider<ColorInversionTile> colorInversionTileProvider,
|
Provider<ColorInversionTile> colorInversionTileProvider,
|
||||||
Provider<AirplaneModeTile> airplaneModeTileProvider,
|
Provider<AirplaneModeTile> airplaneModeTileProvider,
|
||||||
@@ -139,10 +133,8 @@ public class QSFactoryImpl implements QSFactory {
|
|||||||
mQsHostLazy = qsHostLazy;
|
mQsHostLazy = qsHostLazy;
|
||||||
mCustomTileBuilderProvider = customTileBuilderProvider;
|
mCustomTileBuilderProvider = customTileBuilderProvider;
|
||||||
|
|
||||||
mWifiTileProvider = wifiTileProvider;
|
|
||||||
mInternetTileProvider = internetTileProvider;
|
mInternetTileProvider = internetTileProvider;
|
||||||
mBluetoothTileProvider = bluetoothTileProvider;
|
mBluetoothTileProvider = bluetoothTileProvider;
|
||||||
mCellularTileProvider = cellularTileProvider;
|
|
||||||
mDndTileProvider = dndTileProvider;
|
mDndTileProvider = dndTileProvider;
|
||||||
mColorInversionTileProvider = colorInversionTileProvider;
|
mColorInversionTileProvider = colorInversionTileProvider;
|
||||||
mAirplaneModeTileProvider = airplaneModeTileProvider;
|
mAirplaneModeTileProvider = airplaneModeTileProvider;
|
||||||
@@ -186,14 +178,10 @@ public class QSFactoryImpl implements QSFactory {
|
|||||||
protected QSTileImpl createTileInternal(String tileSpec) {
|
protected QSTileImpl createTileInternal(String tileSpec) {
|
||||||
// Stock tiles.
|
// Stock tiles.
|
||||||
switch (tileSpec) {
|
switch (tileSpec) {
|
||||||
case "wifi":
|
|
||||||
return mWifiTileProvider.get();
|
|
||||||
case "internet":
|
case "internet":
|
||||||
return mInternetTileProvider.get();
|
return mInternetTileProvider.get();
|
||||||
case "bt":
|
case "bt":
|
||||||
return mBluetoothTileProvider.get();
|
return mBluetoothTileProvider.get();
|
||||||
case "cell":
|
|
||||||
return mCellularTileProvider.get();
|
|
||||||
case "dnd":
|
case "dnd":
|
||||||
return mDndTileProvider.get();
|
return mDndTileProvider.get();
|
||||||
case "inversion":
|
case "inversion":
|
||||||
|
|||||||
@@ -1,301 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 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.tiles;
|
|
||||||
|
|
||||||
import static com.android.systemui.Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.AlertDialog.Builder;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.service.quicksettings.Tile;
|
|
||||||
import android.telephony.SubscriptionManager;
|
|
||||||
import android.text.Html;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager.LayoutParams;
|
|
||||||
import android.widget.Switch;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settingslib.net.DataUsageController;
|
|
||||||
import com.android.systemui.Prefs;
|
|
||||||
import com.android.systemui.R;
|
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
|
||||||
import com.android.systemui.plugins.FalsingManager;
|
|
||||||
import com.android.systemui.plugins.qs.QSIconView;
|
|
||||||
import com.android.systemui.plugins.qs.QSTile.SignalState;
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
|
||||||
import com.android.systemui.qs.QSHost;
|
|
||||||
import com.android.systemui.qs.SignalTileView;
|
|
||||||
import com.android.systemui.qs.logging.QSLogger;
|
|
||||||
import com.android.systemui.qs.tileimpl.QSTileImpl;
|
|
||||||
import com.android.systemui.statusbar.connectivity.IconState;
|
|
||||||
import com.android.systemui.statusbar.connectivity.MobileDataIndicators;
|
|
||||||
import com.android.systemui.statusbar.connectivity.NetworkController;
|
|
||||||
import com.android.systemui.statusbar.connectivity.SignalCallback;
|
|
||||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/** Quick settings tile: Cellular **/
|
|
||||||
public class CellularTile extends QSTileImpl<SignalState> {
|
|
||||||
private static final String ENABLE_SETTINGS_DATA_PLAN = "enable.settings.data.plan";
|
|
||||||
|
|
||||||
private final NetworkController mController;
|
|
||||||
private final DataUsageController mDataController;
|
|
||||||
private final KeyguardStateController mKeyguard;
|
|
||||||
private final CellSignalCallback mSignalCallback = new CellSignalCallback();
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public CellularTile(
|
|
||||||
QSHost host,
|
|
||||||
@Background Looper backgroundLooper,
|
|
||||||
@Main Handler mainHandler,
|
|
||||||
FalsingManager falsingManager,
|
|
||||||
MetricsLogger metricsLogger,
|
|
||||||
StatusBarStateController statusBarStateController,
|
|
||||||
ActivityStarter activityStarter,
|
|
||||||
QSLogger qsLogger,
|
|
||||||
NetworkController networkController,
|
|
||||||
KeyguardStateController keyguardStateController
|
|
||||||
|
|
||||||
) {
|
|
||||||
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
|
|
||||||
statusBarStateController, activityStarter, qsLogger);
|
|
||||||
mController = networkController;
|
|
||||||
mKeyguard = keyguardStateController;
|
|
||||||
mDataController = mController.getMobileDataController();
|
|
||||||
mController.observe(getLifecycle(), mSignalCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SignalState newTileState() {
|
|
||||||
return new SignalState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QSIconView createTileView(Context context) {
|
|
||||||
return new SignalTileView(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Intent getLongClickIntent() {
|
|
||||||
if (getState().state == Tile.STATE_UNAVAILABLE) {
|
|
||||||
return new Intent(Settings.ACTION_WIRELESS_SETTINGS);
|
|
||||||
}
|
|
||||||
return getCellularSettingIntent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleClick(@Nullable View view) {
|
|
||||||
if (getState().state == Tile.STATE_UNAVAILABLE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mDataController.isMobileDataEnabled()) {
|
|
||||||
maybeShowDisableDialog();
|
|
||||||
} else {
|
|
||||||
mDataController.setMobileDataEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void maybeShowDisableDialog() {
|
|
||||||
if (Prefs.getBoolean(mContext, QS_HAS_TURNED_OFF_MOBILE_DATA, false)) {
|
|
||||||
// Directly turn off mobile data if the user has seen the dialog before.
|
|
||||||
mDataController.setMobileDataEnabled(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String carrierName = mController.getMobileDataNetworkName();
|
|
||||||
boolean isInService = mController.isMobileDataNetworkInService();
|
|
||||||
if (TextUtils.isEmpty(carrierName) || !isInService) {
|
|
||||||
carrierName = mContext.getString(R.string.mobile_data_disable_message_default_carrier);
|
|
||||||
}
|
|
||||||
AlertDialog dialog = new Builder(mContext)
|
|
||||||
.setTitle(R.string.mobile_data_disable_title)
|
|
||||||
.setMessage(mContext.getString(R.string.mobile_data_disable_message, carrierName))
|
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
|
||||||
.setPositiveButton(
|
|
||||||
com.android.internal.R.string.alert_windows_notification_turn_off_action,
|
|
||||||
(d, w) -> {
|
|
||||||
mDataController.setMobileDataEnabled(false);
|
|
||||||
Prefs.putBoolean(mContext, QS_HAS_TURNED_OFF_MOBILE_DATA, true);
|
|
||||||
})
|
|
||||||
.create();
|
|
||||||
dialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
|
|
||||||
SystemUIDialog.setShowForAllUsers(dialog, true);
|
|
||||||
SystemUIDialog.registerDismissListener(dialog);
|
|
||||||
SystemUIDialog.setWindowOnTop(dialog, mKeyguard.isShowing());
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleSecondaryClick(@Nullable View view) {
|
|
||||||
handleLongClick(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTileLabel() {
|
|
||||||
return mContext.getString(R.string.quick_settings_cellular_detail_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleUpdateState(SignalState state, Object arg) {
|
|
||||||
CallbackInfo cb = (CallbackInfo) arg;
|
|
||||||
if (cb == null) {
|
|
||||||
cb = mSignalCallback.mInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Resources r = mContext.getResources();
|
|
||||||
state.label = r.getString(R.string.mobile_data);
|
|
||||||
boolean mobileDataEnabled = mDataController.isMobileDataSupported()
|
|
||||||
&& mDataController.isMobileDataEnabled();
|
|
||||||
state.value = mobileDataEnabled;
|
|
||||||
state.activityIn = mobileDataEnabled && cb.activityIn;
|
|
||||||
state.activityOut = mobileDataEnabled && cb.activityOut;
|
|
||||||
state.expandedAccessibilityClassName = Switch.class.getName();
|
|
||||||
if (cb.noSim) {
|
|
||||||
state.icon = ResourceIcon.get(R.drawable.ic_qs_no_sim);
|
|
||||||
} else {
|
|
||||||
state.icon = ResourceIcon.get(R.drawable.ic_swap_vert);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cb.noSim) {
|
|
||||||
state.state = Tile.STATE_UNAVAILABLE;
|
|
||||||
state.secondaryLabel = r.getString(R.string.keyguard_missing_sim_message_short);
|
|
||||||
} else if (cb.airplaneModeEnabled) {
|
|
||||||
state.state = Tile.STATE_UNAVAILABLE;
|
|
||||||
state.secondaryLabel = r.getString(R.string.status_bar_airplane);
|
|
||||||
} else if (mobileDataEnabled) {
|
|
||||||
state.state = Tile.STATE_ACTIVE;
|
|
||||||
state.secondaryLabel = appendMobileDataType(
|
|
||||||
// Only show carrier name if there are more than 1 subscription
|
|
||||||
cb.multipleSubs ? cb.dataSubscriptionName : "",
|
|
||||||
getMobileDataContentName(cb));
|
|
||||||
} else {
|
|
||||||
state.state = Tile.STATE_INACTIVE;
|
|
||||||
state.secondaryLabel = r.getString(R.string.cell_data_off);
|
|
||||||
}
|
|
||||||
|
|
||||||
state.contentDescription = state.label;
|
|
||||||
if (state.state == Tile.STATE_INACTIVE) {
|
|
||||||
// This information is appended later by converting the Tile.STATE_INACTIVE state.
|
|
||||||
state.stateDescription = "";
|
|
||||||
} else {
|
|
||||||
state.stateDescription = state.secondaryLabel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CharSequence appendMobileDataType(CharSequence current, CharSequence dataType) {
|
|
||||||
if (TextUtils.isEmpty(dataType)) {
|
|
||||||
return Html.fromHtml(current.toString(), 0);
|
|
||||||
}
|
|
||||||
if (TextUtils.isEmpty(current)) {
|
|
||||||
return Html.fromHtml(dataType.toString(), 0);
|
|
||||||
}
|
|
||||||
String concat = mContext.getString(R.string.mobile_carrier_text_format, current, dataType);
|
|
||||||
return Html.fromHtml(concat, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CharSequence getMobileDataContentName(CallbackInfo cb) {
|
|
||||||
if (cb.roaming && !TextUtils.isEmpty(cb.dataContentDescription)) {
|
|
||||||
String roaming = mContext.getString(R.string.data_connection_roaming);
|
|
||||||
String dataDescription = cb.dataContentDescription.toString();
|
|
||||||
return mContext.getString(R.string.mobile_data_text_format, roaming, dataDescription);
|
|
||||||
}
|
|
||||||
if (cb.roaming) {
|
|
||||||
return mContext.getString(R.string.data_connection_roaming);
|
|
||||||
}
|
|
||||||
return cb.dataContentDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsCategory() {
|
|
||||||
return MetricsEvent.QS_CELLULAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAvailable() {
|
|
||||||
return mController.hasMobileDataFeature()
|
|
||||||
&& mHost.getUserContext().getUserId() == UserHandle.USER_SYSTEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class CallbackInfo {
|
|
||||||
boolean airplaneModeEnabled;
|
|
||||||
@Nullable
|
|
||||||
CharSequence dataSubscriptionName;
|
|
||||||
@Nullable
|
|
||||||
CharSequence dataContentDescription;
|
|
||||||
boolean activityIn;
|
|
||||||
boolean activityOut;
|
|
||||||
boolean noSim;
|
|
||||||
boolean roaming;
|
|
||||||
boolean multipleSubs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class CellSignalCallback implements SignalCallback {
|
|
||||||
private final CallbackInfo mInfo = new CallbackInfo();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMobileDataIndicators(@NonNull MobileDataIndicators indicators) {
|
|
||||||
if (indicators.qsIcon == null) {
|
|
||||||
// Not data sim, don't display.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mInfo.dataSubscriptionName = mController.getMobileDataNetworkName();
|
|
||||||
mInfo.dataContentDescription = indicators.qsDescription != null
|
|
||||||
? indicators.typeContentDescriptionHtml : null;
|
|
||||||
mInfo.activityIn = indicators.activityIn;
|
|
||||||
mInfo.activityOut = indicators.activityOut;
|
|
||||||
mInfo.roaming = indicators.roaming;
|
|
||||||
mInfo.multipleSubs = mController.getNumberSubscriptions() > 1;
|
|
||||||
refreshState(mInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNoSims(boolean show, boolean simDetected) {
|
|
||||||
mInfo.noSim = show;
|
|
||||||
refreshState(mInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setIsAirplaneMode(@NonNull IconState icon) {
|
|
||||||
mInfo.airplaneModeEnabled = icon.visible;
|
|
||||||
refreshState(mInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Intent getCellularSettingIntent() {
|
|
||||||
Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
|
|
||||||
int dataSub = SubscriptionManager.getDefaultDataSubscriptionId();
|
|
||||||
if (dataSub != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
|
||||||
intent.putExtra(Settings.EXTRA_SUB_ID,
|
|
||||||
SubscriptionManager.getDefaultDataSubscriptionId());
|
|
||||||
}
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,286 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 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.tiles;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.service.quicksettings.Tile;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Switch;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.systemui.R;
|
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
|
||||||
import com.android.systemui.plugins.FalsingManager;
|
|
||||||
import com.android.systemui.plugins.qs.QSIconView;
|
|
||||||
import com.android.systemui.plugins.qs.QSTile;
|
|
||||||
import com.android.systemui.plugins.qs.QSTile.SignalState;
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
|
||||||
import com.android.systemui.qs.AlphaControlledSignalTileView;
|
|
||||||
import com.android.systemui.qs.QSHost;
|
|
||||||
import com.android.systemui.qs.logging.QSLogger;
|
|
||||||
import com.android.systemui.qs.tileimpl.QSIconViewImpl;
|
|
||||||
import com.android.systemui.qs.tileimpl.QSTileImpl;
|
|
||||||
import com.android.systemui.statusbar.connectivity.AccessPointController;
|
|
||||||
import com.android.systemui.statusbar.connectivity.NetworkController;
|
|
||||||
import com.android.systemui.statusbar.connectivity.SignalCallback;
|
|
||||||
import com.android.systemui.statusbar.connectivity.WifiIcons;
|
|
||||||
import com.android.systemui.statusbar.connectivity.WifiIndicators;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/** Quick settings tile: Wifi **/
|
|
||||||
public class WifiTile extends QSTileImpl<SignalState> {
|
|
||||||
private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS);
|
|
||||||
|
|
||||||
protected final NetworkController mController;
|
|
||||||
private final AccessPointController mWifiController;
|
|
||||||
private final QSTile.SignalState mStateBeforeClick = newTileState();
|
|
||||||
|
|
||||||
protected final WifiSignalCallback mSignalCallback = new WifiSignalCallback();
|
|
||||||
private boolean mExpectDisabled;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public WifiTile(
|
|
||||||
QSHost host,
|
|
||||||
@Background Looper backgroundLooper,
|
|
||||||
@Main Handler mainHandler,
|
|
||||||
FalsingManager falsingManager,
|
|
||||||
MetricsLogger metricsLogger,
|
|
||||||
StatusBarStateController statusBarStateController,
|
|
||||||
ActivityStarter activityStarter,
|
|
||||||
QSLogger qsLogger,
|
|
||||||
NetworkController networkController,
|
|
||||||
AccessPointController accessPointController
|
|
||||||
) {
|
|
||||||
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
|
|
||||||
statusBarStateController, activityStarter, qsLogger);
|
|
||||||
mController = networkController;
|
|
||||||
mWifiController = accessPointController;
|
|
||||||
mController.observe(getLifecycle(), mSignalCallback);
|
|
||||||
mStateBeforeClick.spec = "wifi";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SignalState newTileState() {
|
|
||||||
return new SignalState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QSIconView createTileView(Context context) {
|
|
||||||
return new AlphaControlledSignalTileView(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Intent getLongClickIntent() {
|
|
||||||
return WIFI_SETTINGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleClick(@Nullable View view) {
|
|
||||||
// Secondary clicks are header clicks, just toggle.
|
|
||||||
mState.copyTo(mStateBeforeClick);
|
|
||||||
boolean wifiEnabled = mState.value;
|
|
||||||
// Immediately enter transient state when turning on wifi.
|
|
||||||
refreshState(wifiEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
|
|
||||||
mController.setWifiEnabled(!wifiEnabled);
|
|
||||||
mExpectDisabled = wifiEnabled;
|
|
||||||
if (mExpectDisabled) {
|
|
||||||
mHandler.postDelayed(() -> {
|
|
||||||
if (mExpectDisabled) {
|
|
||||||
mExpectDisabled = false;
|
|
||||||
refreshState();
|
|
||||||
}
|
|
||||||
}, QSIconViewImpl.QS_ANIM_LENGTH);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleSecondaryClick(@Nullable View view) {
|
|
||||||
if (!mWifiController.canConfigWifi()) {
|
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(
|
|
||||||
new Intent(Settings.ACTION_WIFI_SETTINGS), 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!mState.value) {
|
|
||||||
mController.setWifiEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTileLabel() {
|
|
||||||
return mContext.getString(R.string.quick_settings_wifi_label);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleUpdateState(SignalState state, Object arg) {
|
|
||||||
if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg);
|
|
||||||
final CallbackInfo cb = mSignalCallback.mInfo;
|
|
||||||
if (mExpectDisabled) {
|
|
||||||
if (cb.enabled) {
|
|
||||||
return; // Ignore updates until disabled event occurs.
|
|
||||||
} else {
|
|
||||||
mExpectDisabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
|
|
||||||
boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0)
|
|
||||||
&& (cb.ssid != null || cb.wifiSignalIconId != WifiIcons.QS_WIFI_NO_NETWORK);
|
|
||||||
boolean wifiNotConnected = (cb.ssid == null)
|
|
||||||
&& (cb.wifiSignalIconId == WifiIcons.QS_WIFI_NO_NETWORK);
|
|
||||||
if (state.slash == null) {
|
|
||||||
state.slash = new SlashState();
|
|
||||||
state.slash.rotation = 6;
|
|
||||||
}
|
|
||||||
state.slash.isSlashed = false;
|
|
||||||
boolean isTransient = transientEnabling || cb.isTransient;
|
|
||||||
state.secondaryLabel = getSecondaryLabel(isTransient, cb.statusLabel);
|
|
||||||
state.state = Tile.STATE_ACTIVE;
|
|
||||||
state.dualTarget = true;
|
|
||||||
state.value = transientEnabling || cb.enabled;
|
|
||||||
state.activityIn = cb.enabled && cb.activityIn;
|
|
||||||
state.activityOut = cb.enabled && cb.activityOut;
|
|
||||||
final StringBuffer minimalContentDescription = new StringBuffer();
|
|
||||||
final StringBuffer minimalStateDescription = new StringBuffer();
|
|
||||||
final Resources r = mContext.getResources();
|
|
||||||
if (isTransient) {
|
|
||||||
state.icon = ResourceIcon.get(
|
|
||||||
com.android.internal.R.drawable.ic_signal_wifi_transient_animation);
|
|
||||||
state.label = r.getString(R.string.quick_settings_wifi_label);
|
|
||||||
} else if (!state.value) {
|
|
||||||
state.slash.isSlashed = true;
|
|
||||||
state.state = Tile.STATE_INACTIVE;
|
|
||||||
state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_DISABLED);
|
|
||||||
state.label = r.getString(R.string.quick_settings_wifi_label);
|
|
||||||
} else if (wifiConnected) {
|
|
||||||
state.icon = ResourceIcon.get(cb.wifiSignalIconId);
|
|
||||||
state.label = cb.ssid != null ? removeDoubleQuotes(cb.ssid) : getTileLabel();
|
|
||||||
} else if (wifiNotConnected) {
|
|
||||||
state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_NO_NETWORK);
|
|
||||||
state.label = r.getString(R.string.quick_settings_wifi_label);
|
|
||||||
} else {
|
|
||||||
state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_NO_NETWORK);
|
|
||||||
state.label = r.getString(R.string.quick_settings_wifi_label);
|
|
||||||
}
|
|
||||||
minimalContentDescription.append(
|
|
||||||
mContext.getString(R.string.quick_settings_wifi_label)).append(",");
|
|
||||||
if (state.value) {
|
|
||||||
if (wifiConnected) {
|
|
||||||
minimalStateDescription.append(cb.wifiSignalContentDescription);
|
|
||||||
minimalContentDescription.append(removeDoubleQuotes(cb.ssid));
|
|
||||||
if (!TextUtils.isEmpty(state.secondaryLabel)) {
|
|
||||||
minimalContentDescription.append(",").append(state.secondaryLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.stateDescription = minimalStateDescription.toString();
|
|
||||||
state.contentDescription = minimalContentDescription.toString();
|
|
||||||
state.dualLabelContentDescription = r.getString(
|
|
||||||
R.string.accessibility_quick_settings_open_settings, getTileLabel());
|
|
||||||
state.expandedAccessibilityClassName = Switch.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CharSequence getSecondaryLabel(boolean isTransient, String statusLabel) {
|
|
||||||
return isTransient
|
|
||||||
? mContext.getString(R.string.quick_settings_wifi_secondary_label_transient)
|
|
||||||
: statusLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsCategory() {
|
|
||||||
return MetricsEvent.QS_WIFI;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAvailable() {
|
|
||||||
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static String removeDoubleQuotes(String string) {
|
|
||||||
if (string == null) return null;
|
|
||||||
final int length = string.length();
|
|
||||||
if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
|
|
||||||
return string.substring(1, length - 1);
|
|
||||||
}
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static final class CallbackInfo {
|
|
||||||
boolean enabled;
|
|
||||||
boolean connected;
|
|
||||||
int wifiSignalIconId;
|
|
||||||
@Nullable
|
|
||||||
String ssid;
|
|
||||||
boolean activityIn;
|
|
||||||
boolean activityOut;
|
|
||||||
@Nullable
|
|
||||||
String wifiSignalContentDescription;
|
|
||||||
boolean isTransient;
|
|
||||||
@Nullable
|
|
||||||
public String statusLabel;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new StringBuilder("CallbackInfo[")
|
|
||||||
.append("enabled=").append(enabled)
|
|
||||||
.append(",connected=").append(connected)
|
|
||||||
.append(",wifiSignalIconId=").append(wifiSignalIconId)
|
|
||||||
.append(",ssid=").append(ssid)
|
|
||||||
.append(",activityIn=").append(activityIn)
|
|
||||||
.append(",activityOut=").append(activityOut)
|
|
||||||
.append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
|
|
||||||
.append(",isTransient=").append(isTransient)
|
|
||||||
.append(']').toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final class WifiSignalCallback implements SignalCallback {
|
|
||||||
final CallbackInfo mInfo = new CallbackInfo();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setWifiIndicators(@NonNull WifiIndicators indicators) {
|
|
||||||
if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + indicators.enabled);
|
|
||||||
if (indicators.qsIcon == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mInfo.enabled = indicators.enabled;
|
|
||||||
mInfo.connected = indicators.qsIcon.visible;
|
|
||||||
mInfo.wifiSignalIconId = indicators.qsIcon.icon;
|
|
||||||
mInfo.ssid = indicators.description;
|
|
||||||
mInfo.activityIn = indicators.activityIn;
|
|
||||||
mInfo.activityOut = indicators.activityOut;
|
|
||||||
mInfo.wifiSignalContentDescription = indicators.qsIcon.contentDescription;
|
|
||||||
mInfo.isTransient = indicators.isTransient;
|
|
||||||
mInfo.statusLabel = indicators.statusLabel;
|
|
||||||
refreshState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,7 +28,6 @@ import com.android.systemui.qs.tiles.BatterySaverTile
|
|||||||
import com.android.systemui.qs.tiles.BluetoothTile
|
import com.android.systemui.qs.tiles.BluetoothTile
|
||||||
import com.android.systemui.qs.tiles.CameraToggleTile
|
import com.android.systemui.qs.tiles.CameraToggleTile
|
||||||
import com.android.systemui.qs.tiles.CastTile
|
import com.android.systemui.qs.tiles.CastTile
|
||||||
import com.android.systemui.qs.tiles.CellularTile
|
|
||||||
import com.android.systemui.qs.tiles.ColorCorrectionTile
|
import com.android.systemui.qs.tiles.ColorCorrectionTile
|
||||||
import com.android.systemui.qs.tiles.ColorInversionTile
|
import com.android.systemui.qs.tiles.ColorInversionTile
|
||||||
import com.android.systemui.qs.tiles.DataSaverTile
|
import com.android.systemui.qs.tiles.DataSaverTile
|
||||||
@@ -49,7 +48,6 @@ import com.android.systemui.qs.tiles.ReduceBrightColorsTile
|
|||||||
import com.android.systemui.qs.tiles.RotationLockTile
|
import com.android.systemui.qs.tiles.RotationLockTile
|
||||||
import com.android.systemui.qs.tiles.ScreenRecordTile
|
import com.android.systemui.qs.tiles.ScreenRecordTile
|
||||||
import com.android.systemui.qs.tiles.UiModeNightTile
|
import com.android.systemui.qs.tiles.UiModeNightTile
|
||||||
import com.android.systemui.qs.tiles.WifiTile
|
|
||||||
import com.android.systemui.qs.tiles.WorkModeTile
|
import com.android.systemui.qs.tiles.WorkModeTile
|
||||||
import com.android.systemui.util.leak.GarbageMonitor
|
import com.android.systemui.util.leak.GarbageMonitor
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
@@ -63,10 +61,8 @@ import org.mockito.MockitoAnnotations
|
|||||||
import org.mockito.Mockito.`when` as whenever
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
|
||||||
private val specMap = mapOf(
|
private val specMap = mapOf(
|
||||||
"wifi" to WifiTile::class.java,
|
|
||||||
"internet" to InternetTile::class.java,
|
"internet" to InternetTile::class.java,
|
||||||
"bt" to BluetoothTile::class.java,
|
"bt" to BluetoothTile::class.java,
|
||||||
"cell" to CellularTile::class.java,
|
|
||||||
"dnd" to DndTile::class.java,
|
"dnd" to DndTile::class.java,
|
||||||
"inversion" to ColorInversionTile::class.java,
|
"inversion" to ColorInversionTile::class.java,
|
||||||
"airplane" to AirplaneModeTile::class.java,
|
"airplane" to AirplaneModeTile::class.java,
|
||||||
@@ -102,10 +98,8 @@ class QSFactoryImplTest : SysuiTestCase() {
|
|||||||
@Mock(answer = Answers.RETURNS_SELF) private lateinit var customTileBuilder: CustomTile.Builder
|
@Mock(answer = Answers.RETURNS_SELF) private lateinit var customTileBuilder: CustomTile.Builder
|
||||||
@Mock private lateinit var customTile: CustomTile
|
@Mock private lateinit var customTile: CustomTile
|
||||||
|
|
||||||
@Mock private lateinit var wifiTile: WifiTile
|
|
||||||
@Mock private lateinit var internetTile: InternetTile
|
@Mock private lateinit var internetTile: InternetTile
|
||||||
@Mock private lateinit var bluetoothTile: BluetoothTile
|
@Mock private lateinit var bluetoothTile: BluetoothTile
|
||||||
@Mock private lateinit var cellularTile: CellularTile
|
|
||||||
@Mock private lateinit var dndTile: DndTile
|
@Mock private lateinit var dndTile: DndTile
|
||||||
@Mock private lateinit var colorInversionTile: ColorInversionTile
|
@Mock private lateinit var colorInversionTile: ColorInversionTile
|
||||||
@Mock private lateinit var airplaneTile: AirplaneModeTile
|
@Mock private lateinit var airplaneTile: AirplaneModeTile
|
||||||
@@ -146,10 +140,8 @@ class QSFactoryImplTest : SysuiTestCase() {
|
|||||||
factory = QSFactoryImpl(
|
factory = QSFactoryImpl(
|
||||||
{ qsHost },
|
{ qsHost },
|
||||||
{ customTileBuilder },
|
{ customTileBuilder },
|
||||||
{ wifiTile },
|
|
||||||
{ internetTile },
|
{ internetTile },
|
||||||
{ bluetoothTile },
|
{ bluetoothTile },
|
||||||
{ cellularTile },
|
|
||||||
{ dndTile },
|
{ dndTile },
|
||||||
{ colorInversionTile },
|
{ colorInversionTile },
|
||||||
{ airplaneTile },
|
{ airplaneTile },
|
||||||
|
|||||||
Reference in New Issue
Block a user