| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.systemui.statusbar.phone; |
| |
| import android.app.StatusBarManager; |
| import android.bluetooth.BluetoothAdapter; |
| import android.content.BroadcastReceiver; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.location.LocationManager; |
| import android.media.AudioManager; |
| import android.net.ConnectivityManager; |
| import android.net.NetworkInfo; |
| import android.net.wifi.WifiManager; |
| import android.os.Binder; |
| import android.os.Handler; |
| import android.os.RemoteException; |
| import android.os.storage.StorageManager; |
| import android.provider.Settings; |
| import android.telephony.PhoneStateListener; |
| import android.telephony.ServiceState; |
| import android.telephony.SignalStrength; |
| import android.telephony.TelephonyManager; |
| import android.util.Slog; |
| |
| import com.android.internal.telephony.IccCard; |
| import com.android.internal.telephony.TelephonyIntents; |
| import com.android.internal.telephony.cdma.EriInfo; |
| import com.android.internal.telephony.cdma.TtyIntent; |
| import com.android.server.am.BatteryStatsService; |
| import com.android.systemui.R; |
| |
| /** |
| * This class contains all of the policy about which icons are installed in the status |
| * bar at boot time. It goes through the normal API for icons, even though it probably |
| * strictly doesn't need to. |
| */ |
| public class PhoneStatusBarPolicy { |
| private static final String TAG = "PhoneStatusBarPolicy"; |
| |
| // message codes for the handler |
| private static final int EVENT_BATTERY_CLOSE = 4; |
| |
| private static final int AM_PM_STYLE_NORMAL = 0; |
| private static final int AM_PM_STYLE_SMALL = 1; |
| private static final int AM_PM_STYLE_GONE = 2; |
| |
| private static final int AM_PM_STYLE = AM_PM_STYLE_GONE; |
| |
| private static final int INET_CONDITION_THRESHOLD = 50; |
| |
| private static final boolean SHOW_SYNC_ICON = false; |
| |
| private final Context mContext; |
| private final StatusBarManager mService; |
| private final Handler mHandler = new Handler(); |
| |
| // storage |
| private StorageManager mStorageManager; |
| |
| |
| // Assume it's all good unless we hear otherwise. We don't always seem |
| // to get broadcasts that it *is* there. |
| IccCard.State mSimState = IccCard.State.READY; |
| |
| // ringer volume |
| private boolean mVolumeVisible; |
| |
| // bluetooth device status |
| private boolean mBluetoothEnabled; |
| |
| // wifi |
| private static final int[][] sWifiSignalImages = { |
| { R.drawable.stat_sys_wifi_signal_1, |
| R.drawable.stat_sys_wifi_signal_2, |
| R.drawable.stat_sys_wifi_signal_3, |
| R.drawable.stat_sys_wifi_signal_4 }, |
| { R.drawable.stat_sys_wifi_signal_1_fully, |
| R.drawable.stat_sys_wifi_signal_2_fully, |
| R.drawable.stat_sys_wifi_signal_3_fully, |
| R.drawable.stat_sys_wifi_signal_4_fully } |
| }; |
| private static final int sWifiTemporarilyNotConnectedImage = |
| R.drawable.stat_sys_wifi_signal_0; |
| |
| private int mLastWifiSignalLevel = -1; |
| private boolean mIsWifiConnected = false; |
| |
| // state of inet connection - 0 not connected, 100 connected |
| private int mInetCondition = 0; |
| |
| // sync state |
| // If sync is active the SyncActive icon is displayed. If sync is not active but |
| // sync is failing the SyncFailing icon is displayed. Otherwise neither are displayed. |
| |
| private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { |
| @Override |
| public void onReceive(Context context, Intent intent) { |
| String action = intent.getAction(); |
| if (action.equals(Intent.ACTION_ALARM_CHANGED)) { |
| updateAlarm(intent); |
| } |
| else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) { |
| updateSyncState(intent); |
| } |
| else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) || |
| action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { |
| updateBluetooth(intent); |
| } |
| else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) || |
| action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) { |
| updateVolume(); |
| } |
| else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { |
| updateSimState(intent); |
| } |
| else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) { |
| updateTTY(intent); |
| } |
| } |
| }; |
| |
| public PhoneStatusBarPolicy(Context context) { |
| mContext = context; |
| mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE); |
| |
| // storage |
| mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); |
| mStorageManager.registerListener( |
| new com.android.systemui.usb.StorageNotification(context)); |
| |
| // TTY status |
| mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0, null); |
| mService.setIconVisibility("tty", false); |
| |
| // Cdma Roaming Indicator, ERI |
| mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_0, 0, null); |
| mService.setIconVisibility("cdma_eri", false); |
| |
| // bluetooth status |
| mService.setIcon("bluetooth", R.drawable.stat_sys_data_bluetooth, 0, null); |
| BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); |
| if (adapter != null) { |
| mBluetoothEnabled = adapter.isEnabled(); |
| } else { |
| mBluetoothEnabled = false; |
| } |
| mService.setIconVisibility("bluetooth", mBluetoothEnabled); |
| |
| // Alarm clock |
| mService.setIcon("alarm_clock", R.drawable.stat_sys_alarm, 0, null); |
| mService.setIconVisibility("alarm_clock", false); |
| |
| // Sync state |
| mService.setIcon("sync_active", R.drawable.stat_sys_sync, 0, null); |
| mService.setIcon("sync_failing", R.drawable.stat_sys_sync_error, 0, null); |
| mService.setIconVisibility("sync_active", false); |
| mService.setIconVisibility("sync_failing", false); |
| |
| // volume |
| mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0, null); |
| mService.setIconVisibility("volume", false); |
| updateVolume(); |
| |
| IntentFilter filter = new IntentFilter(); |
| |
| // Register for Intent broadcasts for... |
| filter.addAction(Intent.ACTION_ALARM_CHANGED); |
| filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED); |
| filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); |
| filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); |
| filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); |
| filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); |
| filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); |
| filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION); |
| mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); |
| } |
| |
| private final void updateAlarm(Intent intent) { |
| boolean alarmSet = intent.getBooleanExtra("alarmSet", false); |
| mService.setIconVisibility("alarm_clock", alarmSet); |
| } |
| |
| private final void updateSyncState(Intent intent) { |
| if (!SHOW_SYNC_ICON) return; |
| boolean isActive = intent.getBooleanExtra("active", false); |
| boolean isFailing = intent.getBooleanExtra("failing", false); |
| mService.setIconVisibility("sync_active", isActive); |
| // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never" |
| //mService.setIconVisibility("sync_failing", isFailing && !isActive); |
| } |
| |
| private final void updateSimState(Intent intent) { |
| String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); |
| if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { |
| mSimState = IccCard.State.ABSENT; |
| } |
| else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { |
| mSimState = IccCard.State.READY; |
| } |
| else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { |
| final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); |
| if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { |
| mSimState = IccCard.State.PIN_REQUIRED; |
| } |
| else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { |
| mSimState = IccCard.State.PUK_REQUIRED; |
| } |
| else { |
| mSimState = IccCard.State.NETWORK_LOCKED; |
| } |
| } else { |
| mSimState = IccCard.State.UNKNOWN; |
| } |
| } |
| |
| private final void updateVolume() { |
| AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); |
| final int ringerMode = audioManager.getRingerMode(); |
| final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT || |
| ringerMode == AudioManager.RINGER_MODE_VIBRATE; |
| |
| final int iconId; |
| String contentDescription = null; |
| if (audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)) { |
| iconId = R.drawable.stat_sys_ringer_vibrate; |
| contentDescription = mContext.getString(R.string.accessibility_ringer_vibrate); |
| } else { |
| iconId = R.drawable.stat_sys_ringer_silent; |
| contentDescription = mContext.getString(R.string.accessibility_ringer_silent); |
| } |
| |
| if (visible) { |
| mService.setIcon("volume", iconId, 0, contentDescription); |
| } |
| if (visible != mVolumeVisible) { |
| mService.setIconVisibility("volume", visible); |
| mVolumeVisible = visible; |
| } |
| } |
| |
| private final void updateBluetooth(Intent intent) { |
| int iconId = R.drawable.stat_sys_data_bluetooth; |
| String contentDescription = null; |
| String action = intent.getAction(); |
| if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { |
| int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); |
| mBluetoothEnabled = state == BluetoothAdapter.STATE_ON; |
| } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { |
| int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, |
| BluetoothAdapter.STATE_DISCONNECTED); |
| if (state == BluetoothAdapter.STATE_CONNECTED) { |
| iconId = R.drawable.stat_sys_data_bluetooth_connected; |
| contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected); |
| } else { |
| contentDescription = mContext.getString( |
| R.string.accessibility_bluetooth_disconnected); |
| } |
| } else { |
| return; |
| } |
| |
| mService.setIcon("bluetooth", iconId, 0, contentDescription); |
| mService.setIconVisibility("bluetooth", mBluetoothEnabled); |
| } |
| |
| private final void updateTTY(Intent intent) { |
| final String action = intent.getAction(); |
| final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false); |
| |
| if (false) Slog.v(TAG, "updateTTY: enabled: " + enabled); |
| |
| if (enabled) { |
| // TTY is on |
| if (false) Slog.v(TAG, "updateTTY: set TTY on"); |
| mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0, |
| mContext.getString(R.string.accessibility_tty_enabled)); |
| mService.setIconVisibility("tty", true); |
| } else { |
| // TTY is off |
| if (false) Slog.v(TAG, "updateTTY: set TTY off"); |
| mService.setIconVisibility("tty", false); |
| } |
| } |
| } |