CellularTile.java revision 01df36f37fc470d3fd8c120b09cc4e7943cfacfb
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 17package com.android.systemui.qs.tiles; 18 19import android.content.ComponentName; 20import android.content.Context; 21import android.content.Intent; 22import android.content.res.Resources; 23import android.service.quicksettings.Tile; 24import android.view.LayoutInflater; 25import android.view.View; 26import android.view.ViewGroup; 27import android.widget.Switch; 28 29import com.android.internal.logging.MetricsLogger; 30import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 31import com.android.settingslib.net.DataUsageController; 32import com.android.systemui.Dependency; 33import com.android.systemui.R; 34import com.android.systemui.plugins.ActivityStarter; 35import com.android.systemui.plugins.qs.DetailAdapter; 36import com.android.systemui.plugins.qs.QSIconView; 37import com.android.systemui.plugins.qs.QSTile.SignalState; 38import com.android.systemui.qs.CellTileView; 39import com.android.systemui.qs.CellTileView.SignalIcon; 40import com.android.systemui.qs.QSHost; 41import com.android.systemui.qs.SignalTileView; 42import com.android.systemui.qs.tileimpl.QSTileImpl; 43import com.android.systemui.statusbar.policy.NetworkController; 44import com.android.systemui.statusbar.policy.NetworkController.IconState; 45import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; 46 47/** Quick settings tile: Cellular **/ 48public class CellularTile extends QSTileImpl<SignalState> { 49 static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName( 50 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); 51 52 private final NetworkController mController; 53 private final DataUsageController mDataController; 54 private final CellularDetailAdapter mDetailAdapter; 55 56 private final CellSignalCallback mSignalCallback = new CellSignalCallback(); 57 private final ActivityStarter mActivityStarter; 58 59 public CellularTile(QSHost host) { 60 super(host); 61 mController = Dependency.get(NetworkController.class); 62 mActivityStarter = Dependency.get(ActivityStarter.class); 63 mDataController = mController.getMobileDataController(); 64 mDetailAdapter = new CellularDetailAdapter(); 65 } 66 67 @Override 68 public SignalState newTileState() { 69 return new SignalState(); 70 } 71 72 @Override 73 public DetailAdapter getDetailAdapter() { 74 return mDetailAdapter; 75 } 76 77 @Override 78 public void setListening(boolean listening) { 79 if (listening) { 80 mController.addCallback(mSignalCallback); 81 } else { 82 mController.removeCallback(mSignalCallback); 83 } 84 } 85 86 @Override 87 public QSIconView createTileView(Context context) { 88 return new CellTileView(context); 89 } 90 91 @Override 92 public Intent getLongClickIntent() { 93 return CELLULAR_SETTINGS; 94 } 95 96 @Override 97 protected void handleClick() { 98 mDataController.setMobileDataEnabled(!mDataController.isMobileDataEnabled()); 99 } 100 101 @Override 102 protected void handleSecondaryClick() { 103 if (mDataController.isMobileDataSupported()) { 104 showDetail(true); 105 } else { 106 mActivityStarter.postStartActivityDismissingKeyguard(CELLULAR_SETTINGS, 0); 107 } 108 } 109 110 @Override 111 public CharSequence getTileLabel() { 112 return mContext.getString(R.string.quick_settings_cellular_detail_title); 113 } 114 115 @Override 116 protected void handleUpdateState(SignalState state, Object arg) { 117 CallbackInfo cb = (CallbackInfo) arg; 118 if (cb == null) { 119 cb = mSignalCallback.mInfo; 120 } 121 122 final Resources r = mContext.getResources(); 123 state.activityIn = cb.enabled && cb.activityIn; 124 state.activityOut = cb.enabled && cb.activityOut; 125 state.isOverlayIconWide = cb.isDataTypeIconWide; 126 state.overlayIconId = cb.dataTypeIconId; 127 128 state.label = r.getString(R.string.mobile_data); 129 130 final String signalContentDesc = cb.enabled && (cb.mobileSignalIconId > 0) 131 ? cb.signalContentDescription 132 : r.getString(R.string.accessibility_no_signal); 133 if (cb.noSim) { 134 state.contentDescription = state.label; 135 } else { 136 state.contentDescription = signalContentDesc + ", " + state.label; 137 } 138 139 state.expandedAccessibilityClassName = Switch.class.getName(); 140 state.value = mDataController.isMobileDataSupported() 141 && mDataController.isMobileDataEnabled(); 142 state.icon = new SignalIcon(cb.mobileSignalIconId); 143 state.state = Tile.STATE_ACTIVE; 144 } 145 146 @Override 147 public int getMetricsCategory() { 148 return MetricsEvent.QS_CELLULAR; 149 } 150 151 @Override 152 public boolean isAvailable() { 153 return mController.hasMobileDataFeature(); 154 } 155 156 // Remove the period from the network name 157 public static String removeTrailingPeriod(String string) { 158 if (string == null) return null; 159 final int length = string.length(); 160 if (string.endsWith(".")) { 161 return string.substring(0, length - 1); 162 } 163 return string; 164 } 165 166 private static final class CallbackInfo { 167 boolean enabled; 168 boolean wifiEnabled; 169 boolean airplaneModeEnabled; 170 int mobileSignalIconId; 171 String signalContentDescription; 172 int dataTypeIconId; 173 String dataContentDescription; 174 boolean activityIn; 175 boolean activityOut; 176 String enabledDesc; 177 boolean noSim; 178 boolean isDataTypeIconWide; 179 boolean roaming; 180 } 181 182 private final class CellSignalCallback implements SignalCallback { 183 private final CallbackInfo mInfo = new CallbackInfo(); 184 @Override 185 public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, 186 boolean activityIn, boolean activityOut, String description, boolean isTransient) { 187 mInfo.wifiEnabled = enabled; 188 refreshState(mInfo); 189 } 190 191 @Override 192 public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, 193 int qsType, boolean activityIn, boolean activityOut, String typeContentDescription, 194 String description, boolean isWide, int subId, boolean roaming) { 195 if (qsIcon == null) { 196 // Not data sim, don't display. 197 return; 198 } 199 mInfo.enabled = qsIcon.visible; 200 mInfo.mobileSignalIconId = qsIcon.icon; 201 mInfo.signalContentDescription = qsIcon.contentDescription; 202 mInfo.dataTypeIconId = qsType; 203 mInfo.dataContentDescription = typeContentDescription; 204 mInfo.activityIn = activityIn; 205 mInfo.activityOut = activityOut; 206 mInfo.enabledDesc = description; 207 mInfo.isDataTypeIconWide = qsType != 0 && isWide; 208 mInfo.roaming = roaming; 209 refreshState(mInfo); 210 } 211 212 @Override 213 public void setNoSims(boolean show) { 214 mInfo.noSim = show; 215 if (mInfo.noSim) { 216 // Make sure signal gets cleared out when no sims. 217 mInfo.mobileSignalIconId = 0; 218 mInfo.dataTypeIconId = 0; 219 // Show a No SIMs description to avoid emergency calls message. 220 mInfo.enabled = true; 221 mInfo.enabledDesc = mContext.getString( 222 R.string.keyguard_missing_sim_message_short); 223 mInfo.signalContentDescription = mInfo.enabledDesc; 224 } 225 refreshState(mInfo); 226 } 227 228 @Override 229 public void setIsAirplaneMode(IconState icon) { 230 mInfo.airplaneModeEnabled = icon.visible; 231 refreshState(mInfo); 232 } 233 234 @Override 235 public void setMobileDataEnabled(boolean enabled) { 236 mDetailAdapter.setMobileDataEnabled(enabled); 237 } 238 }; 239 240 private final class CellularDetailAdapter implements DetailAdapter { 241 242 @Override 243 public CharSequence getTitle() { 244 return mContext.getString(R.string.quick_settings_cellular_detail_title); 245 } 246 247 @Override 248 public Boolean getToggleState() { 249 return mDataController.isMobileDataSupported() 250 ? mDataController.isMobileDataEnabled() 251 : null; 252 } 253 254 @Override 255 public Intent getSettingsIntent() { 256 return CELLULAR_SETTINGS; 257 } 258 259 @Override 260 public void setToggleState(boolean state) { 261 MetricsLogger.action(mContext, MetricsEvent.QS_CELLULAR_TOGGLE, state); 262 mDataController.setMobileDataEnabled(state); 263 } 264 265 @Override 266 public int getMetricsCategory() { 267 return MetricsEvent.QS_DATAUSAGEDETAIL; 268 } 269 270 @Override 271 public View createDetailView(Context context, View convertView, ViewGroup parent) { 272 final DataUsageDetailView v = (DataUsageDetailView) (convertView != null 273 ? convertView 274 : LayoutInflater.from(mContext).inflate(R.layout.data_usage, parent, false)); 275 final DataUsageController.DataUsageInfo info = mDataController.getDataUsageInfo(); 276 if (info == null) return v; 277 v.bind(info); 278 v.findViewById(R.id.roaming_text).setVisibility(mSignalCallback.mInfo.roaming 279 ? View.VISIBLE : View.INVISIBLE); 280 return v; 281 } 282 283 public void setMobileDataEnabled(boolean enabled) { 284 fireToggleStateChanged(enabled); 285 } 286 } 287} 288