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