CellularTile.java revision c133d26b3897811e9f567d787bff8eafb364f3e3
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.systemui.R; 29import com.android.systemui.qs.QSTile; 30import com.android.systemui.qs.QSTileBaseView; 31import com.android.systemui.qs.SignalTileView; 32import com.android.systemui.statusbar.policy.NetworkController; 33import com.android.systemui.statusbar.policy.NetworkController.IconState; 34import com.android.systemui.statusbar.policy.NetworkController.MobileDataController; 35import com.android.systemui.statusbar.policy.NetworkController.MobileDataController.DataUsageInfo; 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 MobileDataController 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 protected 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 QSTileBaseView 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 handleUpdateState(SignalState state, Object arg) { 92 state.visible = mController.hasMobileDataFeature(); 93 if (!state.visible) return; 94 CallbackInfo cb = (CallbackInfo) arg; 95 if (cb == null) { 96 cb = mSignalCallback.mInfo; 97 } 98 99 final Resources r = mContext.getResources(); 100 final int iconId = cb.noSim ? R.drawable.ic_qs_no_sim 101 : !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled 102 : cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId 103 : R.drawable.ic_qs_signal_no_signal; 104 state.icon = ResourceIcon.get(iconId); 105 state.isOverlayIconWide = cb.isDataTypeIconWide; 106 state.autoMirrorDrawable = !cb.noSim; 107 state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) ? cb.dataTypeIconId : 0; 108 state.filter = iconId != R.drawable.ic_qs_no_sim; 109 state.activityIn = cb.enabled && cb.activityIn; 110 state.activityOut = cb.enabled && cb.activityOut; 111 112 state.label = cb.enabled 113 ? removeTrailingPeriod(cb.enabledDesc) 114 : r.getString(R.string.quick_settings_rssi_emergency_only); 115 116 final String signalContentDesc = cb.enabled && (cb.mobileSignalIconId > 0) 117 ? cb.signalContentDescription 118 : r.getString(R.string.accessibility_no_signal); 119 final String dataContentDesc = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiEnabled 120 ? cb.dataContentDescription 121 : r.getString(R.string.accessibility_no_data); 122 state.contentDescription = r.getString( 123 R.string.accessibility_quick_settings_mobile, 124 signalContentDesc, dataContentDesc, 125 state.label); 126 } 127 128 @Override 129 public int getMetricsCategory() { 130 return MetricsLogger.QS_CELLULAR; 131 } 132 133 // Remove the period from the network name 134 public static String removeTrailingPeriod(String string) { 135 if (string == null) return null; 136 final int length = string.length(); 137 if (string.endsWith(".")) { 138 return string.substring(0, length - 1); 139 } 140 return string; 141 } 142 143 private static final class CallbackInfo { 144 boolean enabled; 145 boolean wifiEnabled; 146 boolean airplaneModeEnabled; 147 int mobileSignalIconId; 148 String signalContentDescription; 149 int dataTypeIconId; 150 String dataContentDescription; 151 boolean activityIn; 152 boolean activityOut; 153 String enabledDesc; 154 boolean noSim; 155 boolean isDataTypeIconWide; 156 } 157 158 private final class CellSignalCallback extends SignalCallbackAdapter { 159 private final CallbackInfo mInfo = new CallbackInfo(); 160 @Override 161 public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, 162 boolean activityIn, boolean activityOut, String description) { 163 mInfo.wifiEnabled = enabled; 164 refreshState(mInfo); 165 } 166 167 @Override 168 public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, 169 int qsType, boolean activityIn, boolean activityOut, String typeContentDescription, 170 String description, boolean isWide, int subId) { 171 if (qsIcon == null) { 172 // Not data sim, don't display. 173 return; 174 } 175 mInfo.enabled = qsIcon.visible; 176 mInfo.mobileSignalIconId = qsIcon.icon; 177 mInfo.signalContentDescription = qsIcon.contentDescription; 178 mInfo.dataTypeIconId = qsType; 179 mInfo.dataContentDescription = typeContentDescription; 180 mInfo.activityIn = activityIn; 181 mInfo.activityOut = activityOut; 182 mInfo.enabledDesc = description; 183 mInfo.isDataTypeIconWide = qsType != 0 && isWide; 184 refreshState(mInfo); 185 } 186 187 @Override 188 public void setNoSims(boolean show) { 189 mInfo.noSim = show; 190 if (mInfo.noSim) { 191 // Make sure signal gets cleared out when no sims. 192 mInfo.mobileSignalIconId = 0; 193 mInfo.dataTypeIconId = 0; 194 // Show a No SIMs description to avoid emergency calls message. 195 mInfo.enabled = true; 196 mInfo.enabledDesc = mContext.getString( 197 R.string.keyguard_missing_sim_message_short); 198 mInfo.signalContentDescription = mInfo.enabledDesc; 199 } 200 refreshState(mInfo); 201 } 202 203 @Override 204 public void setIsAirplaneMode(IconState icon) { 205 mInfo.airplaneModeEnabled = icon.visible; 206 refreshState(mInfo); 207 } 208 209 @Override 210 public void setMobileDataEnabled(boolean enabled) { 211 mDetailAdapter.setMobileDataEnabled(enabled); 212 } 213 }; 214 215 private final class CellularDetailAdapter implements DetailAdapter { 216 217 @Override 218 public int getTitle() { 219 return R.string.quick_settings_cellular_detail_title; 220 } 221 222 @Override 223 public Boolean getToggleState() { 224 return mDataController.isMobileDataSupported() 225 ? mDataController.isMobileDataEnabled() 226 : null; 227 } 228 229 @Override 230 public Intent getSettingsIntent() { 231 return CELLULAR_SETTINGS; 232 } 233 234 @Override 235 public void setToggleState(boolean state) { 236 MetricsLogger.action(mContext, MetricsLogger.QS_CELLULAR_TOGGLE, state); 237 mDataController.setMobileDataEnabled(state); 238 } 239 240 @Override 241 public int getMetricsCategory() { 242 return MetricsLogger.QS_DATAUSAGEDETAIL; 243 } 244 245 @Override 246 public View createDetailView(Context context, View convertView, ViewGroup parent) { 247 final DataUsageDetailView v = (DataUsageDetailView) (convertView != null 248 ? convertView 249 : LayoutInflater.from(mContext).inflate(R.layout.data_usage, parent, false)); 250 final DataUsageInfo info = mDataController.getDataUsageInfo(); 251 if (info == null) return v; 252 v.bind(info); 253 return v; 254 } 255 256 public void setMobileDataEnabled(boolean enabled) { 257 fireToggleStateChanged(enabled); 258 } 259 } 260} 261