| /* |
| * Copyright (C) 2010 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.policy; |
| |
| import java.io.FileDescriptor; |
| import java.io.PrintWriter; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import android.content.BroadcastReceiver; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.content.res.Resources; |
| import android.net.ConnectivityManager; |
| import android.net.NetworkInfo; |
| import android.net.wifi.SupplicantState; |
| import android.net.wifi.WifiConfiguration; |
| import android.net.wifi.WifiInfo; |
| import android.net.wifi.WifiManager; |
| import android.os.Binder; |
| import android.os.Handler; |
| import android.os.HandlerThread; |
| import android.os.Looper; |
| import android.os.Message; |
| import android.os.Messenger; |
| import android.os.RemoteException; |
| import android.provider.Settings; |
| import android.provider.Telephony; |
| import android.telephony.PhoneStateListener; |
| import android.telephony.ServiceState; |
| import android.telephony.SignalStrength; |
| import android.telephony.TelephonyManager; |
| import android.util.Slog; |
| import android.view.View; |
| import android.widget.ImageView; |
| import android.widget.TextView; |
| |
| import com.android.internal.app.IBatteryStats; |
| import com.android.internal.telephony.IccCard; |
| import com.android.internal.telephony.TelephonyIntents; |
| import com.android.internal.telephony.cdma.EriInfo; |
| import com.android.server.am.BatteryStatsService; |
| import com.android.internal.util.AsyncChannel; |
| |
| import com.android.systemui.R; |
| |
| public class NetworkController extends BroadcastReceiver { |
| // debug |
| static final String TAG = "StatusBar.NetworkController"; |
| static final boolean DEBUG = false; |
| |
| // telephony |
| boolean mHspaDataDistinguishable; |
| final TelephonyManager mPhone; |
| boolean mDataConnected; |
| IccCard.State mSimState = IccCard.State.READY; |
| int mPhoneState = TelephonyManager.CALL_STATE_IDLE; |
| int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN; |
| int mDataState = TelephonyManager.DATA_DISCONNECTED; |
| int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE; |
| ServiceState mServiceState; |
| SignalStrength mSignalStrength; |
| int[] mDataIconList = TelephonyIcons.DATA_G[0]; |
| String mNetworkName; |
| String mNetworkNameDefault; |
| String mNetworkNameSeparator; |
| int mPhoneSignalIconId; |
| int mDataDirectionIconId; |
| int mDataDirectionOverlayIconId; |
| int mDataSignalIconId; |
| int mDataTypeIconId; |
| boolean mDataActive; |
| |
| // wifi |
| final WifiManager mWifiManager; |
| AsyncChannel mWifiChannel; |
| boolean mWifiEnabled, mWifiConnected; |
| int mWifiLevel; |
| String mWifiSsid; |
| int mWifiIconId; |
| |
| // bluetooth |
| private boolean mBluetoothTethered = false; |
| private int mBluetoothTetherIconId = |
| com.android.internal.R.drawable.stat_sys_tether_bluetooth; |
| |
| // data connectivity (regardless of state, can we access the internet?) |
| // state of inet connection - 0 not connected, 100 connected |
| private int mInetCondition = 0; |
| private static final int INET_CONDITION_THRESHOLD = 50; |
| |
| // our ui |
| Context mContext; |
| ArrayList<ImageView> mPhoneSignalIconViews = new ArrayList<ImageView>(); |
| ArrayList<ImageView> mDataDirectionIconViews = new ArrayList<ImageView>(); |
| ArrayList<ImageView> mDataDirectionOverlayIconViews = new ArrayList<ImageView>(); |
| ArrayList<ImageView> mWifiIconViews = new ArrayList<ImageView>(); |
| ArrayList<ImageView> mCombinedSignalIconViews = new ArrayList<ImageView>(); |
| ArrayList<ImageView> mDataTypeIconViews = new ArrayList<ImageView>(); |
| ArrayList<TextView> mLabelViews = new ArrayList<TextView>(); |
| int mLastPhoneSignalIconId = -1; |
| int mLastDataDirectionIconId = -1; |
| int mLastDataDirectionOverlayIconId = -1; |
| int mLastWifiIconId = -1; |
| int mLastCombinedSignalIconId = -1; |
| int mLastDataTypeIconId = -1; |
| String mLastLabel = ""; |
| |
| // yuck -- stop doing this here and put it in the framework |
| IBatteryStats mBatteryStats; |
| |
| /** |
| * Construct this controller object and register for updates. |
| */ |
| public NetworkController(Context context) { |
| mContext = context; |
| |
| // telephony |
| mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); |
| mPhone.listen(mPhoneStateListener, |
| PhoneStateListener.LISTEN_SERVICE_STATE |
| | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS |
| | PhoneStateListener.LISTEN_CALL_STATE |
| | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
| | PhoneStateListener.LISTEN_DATA_ACTIVITY); |
| mHspaDataDistinguishable = mContext.getResources().getBoolean( |
| R.bool.config_hspa_data_distinguishable); |
| mNetworkNameSeparator = mContext.getString(R.string.status_bar_network_name_separator); |
| mNetworkNameDefault = mContext.getString( |
| com.android.internal.R.string.lockscreen_carrier_default); |
| mNetworkName = mNetworkNameDefault; |
| |
| // wifi |
| mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); |
| HandlerThread handlerThread = new HandlerThread("WifiServiceThread"); |
| handlerThread.start(); |
| Handler handler = new WifiHandler(handlerThread.getLooper()); |
| mWifiChannel = new AsyncChannel(); |
| Messenger wifiMessenger = mWifiManager.getMessenger(); |
| if (wifiMessenger != null) { |
| mWifiChannel.connect(mContext, handler, wifiMessenger); |
| } |
| |
| // broadcasts |
| IntentFilter filter = new IntentFilter(); |
| filter.addAction(WifiManager.RSSI_CHANGED_ACTION); |
| filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); |
| filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); |
| filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); |
| filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION); |
| filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); |
| filter.addAction(ConnectivityManager.INET_CONDITION_ACTION); |
| filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); |
| context.registerReceiver(this, filter); |
| |
| // yuck |
| mBatteryStats = BatteryStatsService.getService(); |
| } |
| |
| public void addPhoneSignalIconView(ImageView v) { |
| mPhoneSignalIconViews.add(v); |
| } |
| |
| public void addDataDirectionIconView(ImageView v) { |
| mDataDirectionIconViews.add(v); |
| } |
| |
| public void addDataDirectionOverlayIconView(ImageView v) { |
| mDataDirectionOverlayIconViews.add(v); |
| } |
| |
| public void addWifiIconView(ImageView v) { |
| mWifiIconViews.add(v); |
| } |
| |
| public void addCombinedSignalIconView(ImageView v) { |
| mCombinedSignalIconViews.add(v); |
| } |
| |
| public void addDataTypeIconView(ImageView v) { |
| mDataTypeIconViews.add(v); |
| } |
| |
| public void addLabelView(TextView v) { |
| mLabelViews.add(v); |
| } |
| |
| @Override |
| public void onReceive(Context context, Intent intent) { |
| final String action = intent.getAction(); |
| if (action.equals(WifiManager.RSSI_CHANGED_ACTION) |
| || action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) |
| || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { |
| updateWifiState(intent); |
| refreshViews(); |
| } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { |
| updateSimState(intent); |
| updateDataIcon(); |
| refreshViews(); |
| } else if (action.equals(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION)) { |
| updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false), |
| intent.getStringExtra(Telephony.Intents.EXTRA_SPN), |
| intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false), |
| intent.getStringExtra(Telephony.Intents.EXTRA_PLMN)); |
| refreshViews(); |
| } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) || |
| action.equals(ConnectivityManager.INET_CONDITION_ACTION)) { |
| updateConnectivity(intent); |
| refreshViews(); |
| } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { |
| refreshViews(); |
| } |
| } |
| |
| |
| // ===== Telephony ============================================================== |
| |
| PhoneStateListener mPhoneStateListener = new PhoneStateListener() { |
| @Override |
| public void onSignalStrengthsChanged(SignalStrength signalStrength) { |
| if (DEBUG) { |
| Slog.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength); |
| } |
| mSignalStrength = signalStrength; |
| updateTelephonySignalStrength(); |
| refreshViews(); |
| } |
| |
| @Override |
| public void onServiceStateChanged(ServiceState state) { |
| if (DEBUG) { |
| Slog.d(TAG, "onServiceStateChanged state=" + state.getState()); |
| } |
| mServiceState = state; |
| updateTelephonySignalStrength(); |
| updateDataIcon(); |
| refreshViews(); |
| } |
| |
| @Override |
| public void onCallStateChanged(int state, String incomingNumber) { |
| if (DEBUG) { |
| Slog.d(TAG, "onCallStateChanged state=" + state); |
| } |
| // In cdma, if a voice call is made, RSSI should switch to 1x. |
| if (isCdma()) { |
| updateTelephonySignalStrength(); |
| refreshViews(); |
| } |
| } |
| |
| @Override |
| public void onDataConnectionStateChanged(int state, int networkType) { |
| if (DEBUG) { |
| Slog.d(TAG, "onDataConnectionStateChanged: state=" + state |
| + " type=" + networkType); |
| } |
| mDataState = state; |
| mDataNetType = networkType; |
| updateDataNetType(); |
| updateDataIcon(); |
| refreshViews(); |
| } |
| |
| @Override |
| public void onDataActivity(int direction) { |
| if (DEBUG) { |
| Slog.d(TAG, "onDataActivity: direction=" + direction); |
| } |
| mDataActivity = direction; |
| updateDataIcon(); |
| refreshViews(); |
| } |
| }; |
| |
| 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 boolean isCdma() { |
| return (mSignalStrength != null) && !mSignalStrength.isGsm(); |
| } |
| |
| private boolean hasService() { |
| if (mServiceState != null) { |
| switch (mServiceState.getState()) { |
| case ServiceState.STATE_OUT_OF_SERVICE: |
| case ServiceState.STATE_POWER_OFF: |
| return false; |
| default: |
| return true; |
| } |
| } else { |
| return false; |
| } |
| } |
| |
| private final void updateTelephonySignalStrength() { |
| // Display signal strength while in "emergency calls only" mode |
| if (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly())) { |
| //Slog.d(TAG, "updateTelephonySignalStrength: no service"); |
| if (Settings.System.getInt(mContext.getContentResolver(), |
| Settings.System.AIRPLANE_MODE_ON, 0) == 1) { |
| mPhoneSignalIconId = R.drawable.stat_sys_signal_flightmode; |
| mDataSignalIconId = R.drawable.stat_sys_signal_flightmode; |
| } else { |
| mPhoneSignalIconId = R.drawable.stat_sys_signal_null; |
| mDataSignalIconId = R.drawable.stat_sys_signal_0; // note we use 0 instead of null |
| } |
| } else { |
| if (mSignalStrength == null) { |
| mPhoneSignalIconId = R.drawable.stat_sys_signal_null; |
| mDataSignalIconId = R.drawable.stat_sys_signal_0; // note we use 0 instead of null |
| } else { |
| int iconLevel; |
| int[] iconList; |
| iconLevel = mSignalStrength.getLevel(); |
| if (isCdma()) { |
| if (isCdmaEri()) { |
| iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition]; |
| } else { |
| iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition]; |
| } |
| } else { |
| // Though mPhone is a Manager, this call is not an IPC |
| if (mPhone.isNetworkRoaming()) { |
| iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition]; |
| } else { |
| iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition]; |
| } |
| } |
| mPhoneSignalIconId = iconList[iconLevel]; |
| mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel]; |
| } |
| } |
| } |
| |
| private final void updateDataNetType() { |
| switch (mDataNetType) { |
| case TelephonyManager.NETWORK_TYPE_UNKNOWN: |
| mDataIconList = TelephonyIcons.DATA_G[mInetCondition]; |
| mDataTypeIconId = 0; |
| break; |
| case TelephonyManager.NETWORK_TYPE_EDGE: |
| mDataIconList = TelephonyIcons.DATA_E[mInetCondition]; |
| mDataTypeIconId = R.drawable.stat_sys_signal_edge; |
| break; |
| case TelephonyManager.NETWORK_TYPE_UMTS: |
| mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; |
| mDataTypeIconId = R.drawable.stat_sys_signal_3g; |
| break; |
| case TelephonyManager.NETWORK_TYPE_HSDPA: |
| case TelephonyManager.NETWORK_TYPE_HSUPA: |
| case TelephonyManager.NETWORK_TYPE_HSPA: |
| if (mHspaDataDistinguishable) { |
| mDataIconList = TelephonyIcons.DATA_H[mInetCondition]; |
| mDataTypeIconId = R.drawable.stat_sys_signal_hsdpa; |
| } else { |
| mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; |
| mDataTypeIconId = R.drawable.stat_sys_signal_3g; |
| } |
| break; |
| case TelephonyManager.NETWORK_TYPE_CDMA: |
| // display 1xRTT for IS95A/B |
| mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; |
| mDataTypeIconId = R.drawable.stat_sys_signal_1x; |
| break; |
| case TelephonyManager.NETWORK_TYPE_1xRTT: |
| mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; |
| mDataTypeIconId = R.drawable.stat_sys_signal_1x; |
| break; |
| case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through |
| case TelephonyManager.NETWORK_TYPE_EVDO_A: |
| case TelephonyManager.NETWORK_TYPE_EVDO_B: |
| case TelephonyManager.NETWORK_TYPE_EHRPD: |
| mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; |
| mDataTypeIconId = R.drawable.stat_sys_signal_3g; |
| break; |
| case TelephonyManager.NETWORK_TYPE_LTE: |
| mDataIconList = TelephonyIcons.DATA_4G[mInetCondition]; |
| mDataTypeIconId = R.drawable.stat_sys_signal_4g; |
| break; |
| default: |
| mDataIconList = TelephonyIcons.DATA_G[mInetCondition]; |
| mDataTypeIconId = R.drawable.stat_sys_signal_gprs; |
| break; |
| } |
| if ((isCdma() && isCdmaEri()) || mPhone.isNetworkRoaming()) { |
| mDataTypeIconId = R.drawable.stat_sys_signal_roam; |
| } |
| } |
| |
| boolean isCdmaEri() { |
| final int iconIndex = mServiceState.getCdmaEriIconIndex(); |
| if (iconIndex != EriInfo.ROAMING_INDICATOR_OFF) { |
| final int iconMode = mServiceState.getCdmaEriIconMode(); |
| if (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL |
| || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private final void updateDataIcon() { |
| int iconId; |
| boolean visible = true; |
| |
| if (!isCdma()) { |
| // GSM case, we have to check also the sim state |
| if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) { |
| if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { |
| switch (mDataActivity) { |
| case TelephonyManager.DATA_ACTIVITY_IN: |
| iconId = mDataIconList[1]; |
| break; |
| case TelephonyManager.DATA_ACTIVITY_OUT: |
| iconId = mDataIconList[2]; |
| break; |
| case TelephonyManager.DATA_ACTIVITY_INOUT: |
| iconId = mDataIconList[3]; |
| break; |
| default: |
| iconId = mDataIconList[0]; |
| break; |
| } |
| mDataDirectionIconId = iconId; |
| } else { |
| iconId = 0; |
| visible = false; |
| } |
| } else { |
| iconId = R.drawable.stat_sys_no_sim; |
| } |
| } else { |
| // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT |
| if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { |
| switch (mDataActivity) { |
| case TelephonyManager.DATA_ACTIVITY_IN: |
| iconId = mDataIconList[1]; |
| break; |
| case TelephonyManager.DATA_ACTIVITY_OUT: |
| iconId = mDataIconList[2]; |
| break; |
| case TelephonyManager.DATA_ACTIVITY_INOUT: |
| iconId = mDataIconList[3]; |
| break; |
| case TelephonyManager.DATA_ACTIVITY_DORMANT: |
| default: |
| iconId = mDataIconList[0]; |
| break; |
| } |
| } else { |
| iconId = 0; |
| visible = false; |
| } |
| } |
| |
| // yuck - this should NOT be done by the status bar |
| long ident = Binder.clearCallingIdentity(); |
| try { |
| mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible); |
| } catch (RemoteException e) { |
| } finally { |
| Binder.restoreCallingIdentity(ident); |
| } |
| |
| mDataDirectionIconId = iconId; |
| mDataConnected = visible; |
| } |
| |
| void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) { |
| if (false) { |
| Slog.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn |
| + " showPlmn=" + showPlmn + " plmn=" + plmn); |
| } |
| StringBuilder str = new StringBuilder(); |
| boolean something = false; |
| if (showPlmn && plmn != null) { |
| str.append(plmn); |
| something = true; |
| } |
| if (showSpn && spn != null) { |
| if (something) { |
| str.append(mNetworkNameSeparator); |
| } |
| str.append(spn); |
| something = true; |
| } |
| if (something) { |
| mNetworkName = str.toString(); |
| } else { |
| mNetworkName = mNetworkNameDefault; |
| } |
| } |
| |
| // ===== Wifi =================================================================== |
| |
| class WifiHandler extends Handler { |
| |
| WifiHandler(Looper looper) { |
| super(looper); |
| } |
| |
| @Override |
| public void handleMessage(Message msg) { |
| switch (msg.what) { |
| case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: |
| if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { |
| mWifiChannel.sendMessage(Message.obtain(this, |
| AsyncChannel.CMD_CHANNEL_FULL_CONNECTION)); |
| } else { |
| Slog.e(TAG, "Failed to connect to wifi"); |
| } |
| break; |
| case WifiManager.DATA_ACTIVITY_NOTIFICATION: |
| int dataActivity = msg.arg1; |
| /* TODO: update icons based on data activity */ |
| switch (dataActivity) { |
| case WifiManager.DATA_ACTIVITY_IN: |
| break; |
| case WifiManager.DATA_ACTIVITY_OUT: |
| break; |
| case WifiManager.DATA_ACTIVITY_INOUT: |
| break; |
| case WifiManager.DATA_ACTIVITY_NONE: |
| break; |
| } |
| break; |
| default: |
| //Ignore |
| break; |
| } |
| } |
| } |
| |
| private void updateWifiState(Intent intent) { |
| final String action = intent.getAction(); |
| if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { |
| mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, |
| WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; |
| |
| } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { |
| final NetworkInfo networkInfo = (NetworkInfo) |
| intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); |
| boolean wasConnected = mWifiConnected; |
| mWifiConnected = networkInfo != null && networkInfo.isConnected(); |
| // If we just connected, grab the inintial signal strength and ssid |
| if (mWifiConnected && !wasConnected) { |
| WifiInfo info = mWifiManager.getConnectionInfo(); |
| if (info != null) { |
| mWifiLevel = WifiManager.calculateSignalLevel(info.getRssi(), |
| WifiIcons.WIFI_LEVEL_COUNT); |
| mWifiSsid = huntForSsid(info); |
| } else { |
| mWifiLevel = 0; |
| mWifiSsid = null; |
| } |
| } else if (!mWifiConnected) { |
| mWifiLevel = 0; |
| mWifiSsid = null; |
| } |
| |
| } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { |
| if (mWifiConnected) { |
| final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200); |
| mWifiLevel = WifiManager.calculateSignalLevel(newRssi, WifiIcons.WIFI_LEVEL_COUNT); |
| } |
| } |
| |
| updateWifiIcons(); |
| } |
| |
| private void updateWifiIcons() { |
| if (mWifiConnected) { |
| mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[mInetCondition][mWifiLevel]; |
| } else { |
| mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]; |
| } |
| } |
| |
| private String huntForSsid(WifiInfo info) { |
| String ssid = info.getSSID(); |
| if (ssid != null) { |
| return ssid; |
| } |
| // OK, it's not in the connectionInfo; we have to go hunting for it |
| List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks(); |
| for (WifiConfiguration net : networks) { |
| if (net.networkId == info.getNetworkId()) { |
| return net.SSID; |
| } |
| } |
| return null; |
| } |
| |
| |
| // ===== Full or limited Internet connectivity ================================== |
| |
| private void updateConnectivity(Intent intent) { |
| NetworkInfo info = (NetworkInfo)(intent.getParcelableExtra( |
| ConnectivityManager.EXTRA_NETWORK_INFO)); |
| int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0); |
| |
| int inetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0); |
| |
| switch (info.getType()) { |
| case ConnectivityManager.TYPE_MOBILE: |
| mInetCondition = inetCondition; |
| updateDataNetType(); |
| updateDataIcon(); |
| updateTelephonySignalStrength(); // apply any change in connectionStatus |
| break; |
| case ConnectivityManager.TYPE_WIFI: |
| mInetCondition = inetCondition; |
| updateWifiIcons(); |
| break; |
| case ConnectivityManager.TYPE_BLUETOOTH: |
| mInetCondition = inetCondition; |
| if (info != null) { |
| mBluetoothTethered = info.isConnected() ? true: false; |
| } else { |
| mBluetoothTethered = false; |
| } |
| break; |
| } |
| } |
| |
| |
| // ===== Update the views ======================================================= |
| |
| // figure out what to show- there should be one connected network or nothing |
| // General order of preference is: wifi, 3G than bluetooth. This might vary by product. |
| void refreshViews() { |
| Context context = mContext; |
| |
| int combinedSignalIconId; |
| int dataDirectionOverlayIconId = 0; |
| int dataTypeIconId; |
| String label; |
| int N; |
| |
| if (mWifiConnected) { |
| if (mWifiSsid == null) { |
| label = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid); |
| } else { |
| label = mWifiSsid; |
| } |
| combinedSignalIconId = mWifiIconId; |
| dataTypeIconId = 0; |
| } else if (mDataConnected) { |
| label = mNetworkName; |
| combinedSignalIconId = mDataSignalIconId; |
| switch (mDataActivity) { |
| case TelephonyManager.DATA_ACTIVITY_IN: |
| dataDirectionOverlayIconId = R.drawable.stat_sys_signal_in; |
| break; |
| case TelephonyManager.DATA_ACTIVITY_OUT: |
| dataDirectionOverlayIconId = R.drawable.stat_sys_signal_out; |
| break; |
| case TelephonyManager.DATA_ACTIVITY_INOUT: |
| dataDirectionOverlayIconId = R.drawable.stat_sys_signal_inout; |
| break; |
| default: |
| dataDirectionOverlayIconId = 0; |
| break; |
| } |
| combinedSignalIconId = mDataSignalIconId; |
| dataTypeIconId = mDataTypeIconId; |
| } else if (mBluetoothTethered) { |
| label = mContext.getString(R.string.bluetooth_tethered); |
| combinedSignalIconId = mBluetoothTetherIconId; |
| dataTypeIconId = 0; |
| } else { |
| label = context.getString(R.string.status_bar_settings_signal_meter_disconnected); |
| combinedSignalIconId = mDataSignalIconId; |
| dataTypeIconId = 0; |
| } |
| |
| if (false) { |
| Slog.d(TAG, "refreshViews combinedSignalIconId=0x" |
| + Integer.toHexString(combinedSignalIconId) |
| + "/" + getResourceName(combinedSignalIconId) |
| + " dataDirectionOverlayIconId=0x" + Integer.toHexString(dataDirectionOverlayIconId) |
| + " mDataActivity=" + mDataActivity |
| + " mPhoneSignalIconId=0x" + Integer.toHexString(mPhoneSignalIconId) |
| + " mDataDirectionIconId=0x" + Integer.toHexString(mDataDirectionIconId) |
| + " mDataSignalIconId=0x" + Integer.toHexString(mDataSignalIconId) |
| + " mDataTypeIconId=0x" + Integer.toHexString(mDataTypeIconId) |
| + " mWifiIconId=0x" + Integer.toHexString(mWifiIconId) |
| + " mBluetoothTetherIconId=0x" + Integer.toHexString(mBluetoothTetherIconId)); |
| } |
| |
| // the phone icon on phones |
| if (mLastPhoneSignalIconId != mPhoneSignalIconId) { |
| mLastPhoneSignalIconId = mPhoneSignalIconId; |
| N = mPhoneSignalIconViews.size(); |
| for (int i=0; i<N; i++) { |
| final ImageView v = mPhoneSignalIconViews.get(i); |
| v.setImageResource(mPhoneSignalIconId); |
| } |
| } |
| |
| // the data icon on phones |
| if (mLastDataDirectionIconId != mDataDirectionIconId) { |
| mLastDataDirectionIconId = mDataDirectionIconId; |
| N = mDataDirectionIconViews.size(); |
| for (int i=0; i<N; i++) { |
| final ImageView v = mDataDirectionIconViews.get(i); |
| v.setImageResource(mDataDirectionIconId); |
| } |
| } |
| |
| // the wifi icon on phones |
| if (mLastWifiIconId != mWifiIconId) { |
| mLastWifiIconId = mWifiIconId; |
| N = mWifiIconViews.size(); |
| for (int i=0; i<N; i++) { |
| final ImageView v = mWifiIconViews.get(i); |
| v.setImageResource(mWifiIconId); |
| } |
| } |
| |
| // the combined data signal icon |
| if (mLastCombinedSignalIconId != combinedSignalIconId) { |
| mLastCombinedSignalIconId = combinedSignalIconId; |
| N = mCombinedSignalIconViews.size(); |
| for (int i=0; i<N; i++) { |
| final ImageView v = mCombinedSignalIconViews.get(i); |
| v.setImageResource(combinedSignalIconId); |
| } |
| } |
| |
| // the data network type overlay |
| if (mLastDataTypeIconId != dataTypeIconId) { |
| mLastDataTypeIconId = dataTypeIconId; |
| N = mDataTypeIconViews.size(); |
| for (int i=0; i<N; i++) { |
| final ImageView v = mDataTypeIconViews.get(i); |
| if (dataTypeIconId == 0) { |
| v.setVisibility(View.INVISIBLE); |
| } else { |
| v.setVisibility(View.VISIBLE); |
| v.setImageResource(dataTypeIconId); |
| } |
| } |
| } |
| |
| // the data direction overlay |
| if (mLastDataDirectionOverlayIconId != dataDirectionOverlayIconId) { |
| Slog.d(TAG, "changing data overlay icon id to " + dataDirectionOverlayIconId); |
| mLastDataDirectionOverlayIconId = dataDirectionOverlayIconId; |
| N = mDataDirectionOverlayIconViews.size(); |
| for (int i=0; i<N; i++) { |
| final ImageView v = mDataDirectionOverlayIconViews.get(i); |
| if (dataDirectionOverlayIconId == 0) { |
| v.setVisibility(View.INVISIBLE); |
| } else { |
| v.setVisibility(View.VISIBLE); |
| v.setImageResource(dataDirectionOverlayIconId); |
| } |
| } |
| } |
| |
| // the label in the notification panel |
| if (!mLastLabel.equals(label)) { |
| mLastLabel = label; |
| N = mLabelViews.size(); |
| for (int i=0; i<N; i++) { |
| TextView v = mLabelViews.get(i); |
| v.setText(label); |
| } |
| } |
| } |
| |
| public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { |
| pw.println(" - telephony ------"); |
| pw.print(" mHspaDataDistinguishable="); |
| pw.println(mHspaDataDistinguishable); |
| pw.print(" mDataConnected="); |
| pw.println(mDataConnected); |
| pw.print(" mSimState="); |
| pw.println(mSimState); |
| pw.print(" mPhoneState="); |
| pw.println(mPhoneState); |
| pw.print(" mDataState="); |
| pw.println(mDataState); |
| pw.print(" mDataActivity="); |
| pw.println(mDataActivity); |
| pw.print(" mServiceState="); |
| pw.println(mServiceState.toString()); |
| pw.print(" mNetworkName="); |
| pw.println(mNetworkName); |
| pw.print(" mNetworkNameDefault="); |
| pw.println(mNetworkNameDefault); |
| pw.print(" mNetworkNameSeparator="); |
| pw.println(mNetworkNameSeparator); |
| pw.print(" mPhoneSignalIconId=0x"); |
| pw.print(Integer.toHexString(mPhoneSignalIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mPhoneSignalIconId)); |
| pw.print(" mDataDirectionIconId="); |
| pw.print(Integer.toHexString(mDataDirectionIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mDataDirectionIconId)); |
| pw.print(" mDataSignalIconId="); |
| pw.print(Integer.toHexString(mDataSignalIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mDataSignalIconId)); |
| pw.print(" mDataTypeIconId="); |
| pw.print(Integer.toHexString(mDataTypeIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mDataTypeIconId)); |
| |
| pw.println(" - wifi ------"); |
| pw.print(" mWifiEnabled="); |
| pw.println(mWifiEnabled); |
| pw.print(" mWifiConnected="); |
| pw.println(mWifiConnected); |
| pw.print(" mWifiLevel="); |
| pw.println(mWifiLevel); |
| pw.print(" mWifiSsid="); |
| pw.println(mWifiSsid); |
| pw.print(" mWifiIconId="); |
| pw.println(mWifiIconId); |
| |
| pw.println(" - Bluetooth ----"); |
| pw.print(" mBtReverseTethered="); |
| pw.println(mBluetoothTethered); |
| |
| pw.println(" - connectivity ------"); |
| pw.print(" mInetCondition="); |
| pw.println(mInetCondition); |
| |
| pw.println(" - icons ------"); |
| pw.print(" mLastPhoneSignalIconId=0x"); |
| pw.print(Integer.toHexString(mLastPhoneSignalIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mLastPhoneSignalIconId)); |
| pw.print(" mLastDataDirectionIconId=0x"); |
| pw.print(Integer.toHexString(mLastDataDirectionIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mLastDataDirectionIconId)); |
| pw.print(" mLastDataDirectionOverlayIconId=0x"); |
| pw.print(Integer.toHexString(mLastDataDirectionOverlayIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mLastDataDirectionOverlayIconId)); |
| pw.print(" mLastWifiIconId=0x"); |
| pw.print(Integer.toHexString(mLastWifiIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mLastWifiIconId)); |
| pw.print(" mLastCombinedSignalIconId=0x"); |
| pw.print(Integer.toHexString(mLastCombinedSignalIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mLastCombinedSignalIconId)); |
| pw.print(" mLastDataTypeIconId=0x"); |
| pw.print(Integer.toHexString(mLastDataTypeIconId)); |
| pw.print("/"); |
| pw.println(getResourceName(mLastCombinedSignalIconId)); |
| pw.print(" mLastLabel="); |
| pw.print(mLastLabel); |
| } |
| |
| private String getResourceName(int resId) { |
| if (resId == 0) { |
| final Resources res = mContext.getResources(); |
| try { |
| return res.getResourceName(resId); |
| } catch (android.content.res.Resources.NotFoundException ex) { |
| return "(unknown)"; |
| } |
| } else { |
| return "(null)"; |
| } |
| } |
| |
| } |