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