1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.qs.tiles; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.net.ConnectivityManager; 24 import android.os.Handler; 25 import android.os.Looper; 26 import android.os.UserManager; 27 import android.provider.Settings; 28 import android.provider.Settings.Global; 29 import android.service.quicksettings.Tile; 30 import android.sysprop.TelephonyProperties; 31 import android.telephony.TelephonyManager; 32 import android.view.View; 33 import android.widget.Switch; 34 35 import androidx.annotation.Nullable; 36 37 import com.android.internal.logging.MetricsLogger; 38 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 39 import com.android.systemui.R; 40 import com.android.systemui.broadcast.BroadcastDispatcher; 41 import com.android.systemui.dagger.qualifiers.Background; 42 import com.android.systemui.dagger.qualifiers.Main; 43 import com.android.systemui.plugins.ActivityStarter; 44 import com.android.systemui.plugins.FalsingManager; 45 import com.android.systemui.plugins.qs.QSTile.BooleanState; 46 import com.android.systemui.plugins.statusbar.StatusBarStateController; 47 import com.android.systemui.qs.QSHost; 48 import com.android.systemui.qs.QsEventLogger; 49 import com.android.systemui.qs.SettingObserver; 50 import com.android.systemui.qs.logging.QSLogger; 51 import com.android.systemui.qs.tileimpl.QSTileImpl; 52 import com.android.systemui.settings.UserTracker; 53 import com.android.systemui.util.settings.GlobalSettings; 54 55 import dagger.Lazy; 56 57 import javax.inject.Inject; 58 59 60 61 /** Quick settings tile: Airplane mode **/ 62 public class AirplaneModeTile extends QSTileImpl<BooleanState> { 63 64 public static final String TILE_SPEC = "airplane"; 65 66 private final SettingObserver mSetting; 67 private final BroadcastDispatcher mBroadcastDispatcher; 68 private final Lazy<ConnectivityManager> mLazyConnectivityManager; 69 70 private boolean mListening; 71 72 @Inject AirplaneModeTile( QSHost host, QsEventLogger uiEventLogger, @Background Looper backgroundLooper, @Main Handler mainHandler, FalsingManager falsingManager, MetricsLogger metricsLogger, StatusBarStateController statusBarStateController, ActivityStarter activityStarter, QSLogger qsLogger, BroadcastDispatcher broadcastDispatcher, Lazy<ConnectivityManager> lazyConnectivityManager, GlobalSettings globalSettings, UserTracker userTracker )73 public AirplaneModeTile( 74 QSHost host, 75 QsEventLogger uiEventLogger, 76 @Background Looper backgroundLooper, 77 @Main Handler mainHandler, 78 FalsingManager falsingManager, 79 MetricsLogger metricsLogger, 80 StatusBarStateController statusBarStateController, 81 ActivityStarter activityStarter, 82 QSLogger qsLogger, 83 BroadcastDispatcher broadcastDispatcher, 84 Lazy<ConnectivityManager> lazyConnectivityManager, 85 GlobalSettings globalSettings, 86 UserTracker userTracker 87 ) { 88 super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger, 89 statusBarStateController, activityStarter, qsLogger); 90 mBroadcastDispatcher = broadcastDispatcher; 91 mLazyConnectivityManager = lazyConnectivityManager; 92 93 mSetting = new SettingObserver(globalSettings, mHandler, Global.AIRPLANE_MODE_ON, 94 userTracker.getUserId()) { 95 @Override 96 protected void handleValueChanged(int value, boolean observedChange) { 97 // mHandler is the background handler so calling this is OK 98 handleRefreshState(value); 99 } 100 }; 101 } 102 103 @Override newTileState()104 public BooleanState newTileState() { 105 return new BooleanState(); 106 } 107 108 @Override handleClick(@ullable View view)109 public void handleClick(@Nullable View view) { 110 boolean airplaneModeEnabled = mState.value; 111 MetricsLogger.action(mContext, getMetricsCategory(), !airplaneModeEnabled); 112 if (!airplaneModeEnabled && TelephonyProperties.in_ecm_mode().orElse(false)) { 113 mActivityStarter.postStartActivityDismissingKeyguard( 114 new Intent(TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS), 0); 115 return; 116 } 117 setEnabled(!airplaneModeEnabled); 118 } 119 setEnabled(boolean enabled)120 private void setEnabled(boolean enabled) { 121 mLazyConnectivityManager.get().setAirplaneMode(enabled); 122 } 123 124 @Override getLongClickIntent()125 public Intent getLongClickIntent() { 126 return new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS); 127 } 128 129 @Override getTileLabel()130 public CharSequence getTileLabel() { 131 return mContext.getString(R.string.airplane_mode); 132 } 133 134 @Override handleUpdateState(BooleanState state, Object arg)135 protected void handleUpdateState(BooleanState state, Object arg) { 136 checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_AIRPLANE_MODE); 137 final int value = arg instanceof Integer ? (Integer)arg : mSetting.getValue(); 138 final boolean airplaneMode = value != 0; 139 state.value = airplaneMode; 140 state.label = mContext.getString(R.string.airplane_mode); 141 state.icon = ResourceIcon.get(state.value 142 ? R.drawable.qs_airplane_icon_on : R.drawable.qs_airplane_icon_off); 143 state.state = airplaneMode ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; 144 state.contentDescription = state.label; 145 state.expandedAccessibilityClassName = Switch.class.getName(); 146 } 147 148 @Override getMetricsCategory()149 public int getMetricsCategory() { 150 return MetricsEvent.QS_AIRPLANEMODE; 151 } 152 handleSetListening(boolean listening)153 public void handleSetListening(boolean listening) { 154 super.handleSetListening(listening); 155 if (mListening == listening) return; 156 mListening = listening; 157 if (listening) { 158 final IntentFilter filter = new IntentFilter(); 159 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); 160 mBroadcastDispatcher.registerReceiver(mReceiver, filter); 161 } else { 162 mBroadcastDispatcher.unregisterReceiver(mReceiver); 163 } 164 mSetting.setListening(listening); 165 } 166 167 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 168 @Override 169 public void onReceive(Context context, Intent intent) { 170 if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) { 171 refreshState(); 172 } 173 } 174 }; 175 } 176