1/* 2 * Copyright (C) 2008 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.statusbar.phone; 18 19import android.app.StatusBarManager; 20import android.bluetooth.BluetoothAdapter; 21import android.content.BroadcastReceiver; 22import android.content.Context; 23import android.content.Intent; 24import android.content.IntentFilter; 25import android.media.AudioManager; 26import android.os.Handler; 27import android.util.Log; 28 29import com.android.internal.telephony.IccCardConstants; 30import com.android.internal.telephony.TelephonyIntents; 31import com.android.internal.telephony.cdma.TtyIntent; 32import com.android.systemui.R; 33 34/** 35 * This class contains all of the policy about which icons are installed in the status 36 * bar at boot time. It goes through the normal API for icons, even though it probably 37 * strictly doesn't need to. 38 */ 39public class PhoneStatusBarPolicy { 40 private static final String TAG = "PhoneStatusBarPolicy"; 41 42 // message codes for the handler 43 private static final int EVENT_BATTERY_CLOSE = 4; 44 45 private static final int AM_PM_STYLE_NORMAL = 0; 46 private static final int AM_PM_STYLE_SMALL = 1; 47 private static final int AM_PM_STYLE_GONE = 2; 48 49 private static final int AM_PM_STYLE = AM_PM_STYLE_GONE; 50 51 private static final int INET_CONDITION_THRESHOLD = 50; 52 53 private static final boolean SHOW_SYNC_ICON = false; 54 55 private final Context mContext; 56 private final StatusBarManager mService; 57 private final Handler mHandler = new Handler(); 58 59 // Assume it's all good unless we hear otherwise. We don't always seem 60 // to get broadcasts that it *is* there. 61 IccCardConstants.State mSimState = IccCardConstants.State.READY; 62 63 // ringer volume 64 private boolean mVolumeVisible; 65 66 // bluetooth device status 67 private boolean mBluetoothEnabled = false; 68 69 private int mLastWifiSignalLevel = -1; 70 private boolean mIsWifiConnected = false; 71 72 // state of inet connection - 0 not connected, 100 connected 73 private int mInetCondition = 0; 74 75 // sync state 76 // If sync is active the SyncActive icon is displayed. If sync is not active but 77 // sync is failing the SyncFailing icon is displayed. Otherwise neither are displayed. 78 79 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 80 @Override 81 public void onReceive(Context context, Intent intent) { 82 String action = intent.getAction(); 83 if (action.equals(Intent.ACTION_ALARM_CHANGED)) { 84 updateAlarm(intent); 85 } 86 else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) { 87 updateSyncState(intent); 88 } 89 else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) || 90 action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { 91 updateBluetooth(intent); 92 } 93 else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { 94 updateVolume(); 95 } 96 else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { 97 updateSimState(intent); 98 } 99 else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) { 100 updateTTY(intent); 101 } 102 } 103 }; 104 105 public PhoneStatusBarPolicy(Context context) { 106 mContext = context; 107 mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE); 108 109 // listen for broadcasts 110 IntentFilter filter = new IntentFilter(); 111 filter.addAction(Intent.ACTION_ALARM_CHANGED); 112 filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED); 113 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); 114 filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 115 filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); 116 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 117 filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION); 118 mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); 119 120 // TTY status 121 mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0, null); 122 mService.setIconVisibility("tty", false); 123 124 // Cdma Roaming Indicator, ERI 125 mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_0, 0, null); 126 mService.setIconVisibility("cdma_eri", false); 127 128 // bluetooth status 129 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 130 int bluetoothIcon = R.drawable.stat_sys_data_bluetooth; 131 if (adapter != null) { 132 mBluetoothEnabled = (adapter.getState() == BluetoothAdapter.STATE_ON); 133 if (adapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED) { 134 bluetoothIcon = R.drawable.stat_sys_data_bluetooth_connected; 135 } 136 } 137 mService.setIcon("bluetooth", bluetoothIcon, 0, null); 138 mService.setIconVisibility("bluetooth", mBluetoothEnabled); 139 140 // Alarm clock 141 mService.setIcon("alarm_clock", R.drawable.stat_sys_alarm, 0, null); 142 mService.setIconVisibility("alarm_clock", false); 143 144 // Sync state 145 mService.setIcon("sync_active", R.drawable.stat_sys_sync, 0, null); 146 mService.setIconVisibility("sync_active", false); 147 // "sync_failing" is obsolete: b/1297963 148 149 // volume 150 mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0, null); 151 mService.setIconVisibility("volume", false); 152 updateVolume(); 153 } 154 155 private final void updateAlarm(Intent intent) { 156 boolean alarmSet = intent.getBooleanExtra("alarmSet", false); 157 mService.setIconVisibility("alarm_clock", alarmSet); 158 } 159 160 private final void updateSyncState(Intent intent) { 161 if (!SHOW_SYNC_ICON) return; 162 boolean isActive = intent.getBooleanExtra("active", false); 163 mService.setIconVisibility("sync_active", isActive); 164 } 165 166 private final void updateSimState(Intent intent) { 167 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); 168 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { 169 mSimState = IccCardConstants.State.ABSENT; 170 } 171 else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) { 172 mSimState = IccCardConstants.State.READY; 173 } 174 else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { 175 final String lockedReason = 176 intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); 177 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { 178 mSimState = IccCardConstants.State.PIN_REQUIRED; 179 } 180 else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { 181 mSimState = IccCardConstants.State.PUK_REQUIRED; 182 } 183 else { 184 mSimState = IccCardConstants.State.NETWORK_LOCKED; 185 } 186 } else { 187 mSimState = IccCardConstants.State.UNKNOWN; 188 } 189 } 190 191 private final void updateVolume() { 192 AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 193 final int ringerMode = audioManager.getRingerMode(); 194 final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT || 195 ringerMode == AudioManager.RINGER_MODE_VIBRATE; 196 197 final int iconId; 198 String contentDescription = null; 199 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { 200 iconId = R.drawable.stat_sys_ringer_vibrate; 201 contentDescription = mContext.getString(R.string.accessibility_ringer_vibrate); 202 } else { 203 iconId = R.drawable.stat_sys_ringer_silent; 204 contentDescription = mContext.getString(R.string.accessibility_ringer_silent); 205 } 206 207 if (visible) { 208 mService.setIcon("volume", iconId, 0, contentDescription); 209 } 210 if (visible != mVolumeVisible) { 211 mService.setIconVisibility("volume", visible); 212 mVolumeVisible = visible; 213 } 214 } 215 216 private final void updateBluetooth(Intent intent) { 217 int iconId = R.drawable.stat_sys_data_bluetooth; 218 String contentDescription = null; 219 String action = intent.getAction(); 220 if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 221 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); 222 mBluetoothEnabled = state == BluetoothAdapter.STATE_ON; 223 } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { 224 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, 225 BluetoothAdapter.STATE_DISCONNECTED); 226 if (state == BluetoothAdapter.STATE_CONNECTED) { 227 iconId = R.drawable.stat_sys_data_bluetooth_connected; 228 contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected); 229 } else { 230 contentDescription = mContext.getString( 231 R.string.accessibility_bluetooth_disconnected); 232 } 233 } else { 234 return; 235 } 236 237 mService.setIcon("bluetooth", iconId, 0, contentDescription); 238 mService.setIconVisibility("bluetooth", mBluetoothEnabled); 239 } 240 241 private final void updateTTY(Intent intent) { 242 final String action = intent.getAction(); 243 final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false); 244 245 if (false) Log.v(TAG, "updateTTY: enabled: " + enabled); 246 247 if (enabled) { 248 // TTY is on 249 if (false) Log.v(TAG, "updateTTY: set TTY on"); 250 mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0, 251 mContext.getString(R.string.accessibility_tty_enabled)); 252 mService.setIconVisibility("tty", true); 253 } else { 254 // TTY is off 255 if (false) Log.v(TAG, "updateTTY: set TTY off"); 256 mService.setIconVisibility("tty", false); 257 } 258 } 259} 260