SysUI: Separate SignalControllers into separate files
and remove the TODO that says to do it. Change-Id: I54ac3f27f9246aea87d21f2a1da6608ae675aae6
This commit is contained in:
@@ -0,0 +1,545 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.telephony.TelephonyIntents;
|
||||
import com.android.internal.telephony.cdma.EriInfo;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class MobileSignalController extends SignalController<
|
||||
MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> {
|
||||
private final TelephonyManager mPhone;
|
||||
private final String mNetworkNameDefault;
|
||||
private final String mNetworkNameSeparator;
|
||||
@VisibleForTesting
|
||||
final PhoneStateListener mPhoneStateListener;
|
||||
// Save entire info for logging, we only use the id.
|
||||
private final SubscriptionInfo mSubscriptionInfo;
|
||||
|
||||
// @VisibleForDemoMode
|
||||
final SparseArray<MobileIconGroup> mNetworkToIconLookup;
|
||||
|
||||
// Since some pieces of the phone state are interdependent we store it locally,
|
||||
// this could potentially become part of MobileState for simplification/complication
|
||||
// of code.
|
||||
private IccCardConstants.State mSimState = IccCardConstants.State.READY;
|
||||
private int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
|
||||
private int mDataState = TelephonyManager.DATA_DISCONNECTED;
|
||||
private ServiceState mServiceState;
|
||||
private SignalStrength mSignalStrength;
|
||||
private MobileIconGroup mDefaultIcons;
|
||||
private Config mConfig;
|
||||
|
||||
// TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
|
||||
// need listener lists anymore.
|
||||
public MobileSignalController(Context context, Config config, boolean hasMobileData,
|
||||
TelephonyManager phone, List<NetworkSignalChangedCallback> signalCallbacks,
|
||||
List<SignalCluster> signalClusters, NetworkControllerImpl networkController,
|
||||
SubscriptionInfo info) {
|
||||
super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
|
||||
NetworkCapabilities.TRANSPORT_CELLULAR, signalCallbacks, signalClusters,
|
||||
networkController);
|
||||
mNetworkToIconLookup = new SparseArray<>();
|
||||
mConfig = config;
|
||||
mPhone = phone;
|
||||
mSubscriptionInfo = info;
|
||||
mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId());
|
||||
mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator);
|
||||
mNetworkNameDefault = getStringIfExists(
|
||||
com.android.internal.R.string.lockscreen_carrier_default);
|
||||
|
||||
mapIconSets();
|
||||
|
||||
mLastState.networkName = mCurrentState.networkName = mNetworkNameDefault;
|
||||
mLastState.enabled = mCurrentState.enabled = hasMobileData;
|
||||
mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons;
|
||||
// Get initial data sim state.
|
||||
updateDataSim();
|
||||
}
|
||||
|
||||
public void setConfiguration(Config config) {
|
||||
mConfig = config;
|
||||
mapIconSets();
|
||||
updateTelephony();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get (the mobile parts of) the carrier string.
|
||||
*
|
||||
* @param currentLabel can be used for concatenation, currently just empty
|
||||
* @param connected whether the device has connection to the internet at all
|
||||
* @param isMobileLabel whether to always return the network or just when data is connected
|
||||
*/
|
||||
public String getLabel(String currentLabel, boolean connected, boolean isMobileLabel) {
|
||||
if (!mCurrentState.enabled) {
|
||||
return "";
|
||||
} else {
|
||||
String mobileLabel = "";
|
||||
// We want to show the carrier name if in service and either:
|
||||
// - We are connected to mobile data, or
|
||||
// - We are not connected to mobile data, as long as the *reason* packets are not
|
||||
// being routed over that link is that we have better connectivity via wifi.
|
||||
// If data is disconnected for some other reason but wifi (or ethernet/bluetooth)
|
||||
// is connected, we show nothing.
|
||||
// Otherwise (nothing connected) we show "No internet connection".
|
||||
if (mCurrentState.dataConnected) {
|
||||
mobileLabel = mCurrentState.networkName;
|
||||
} else if (connected || mCurrentState.isEmergency) {
|
||||
if (mCurrentState.connected || mCurrentState.isEmergency) {
|
||||
// The isEmergencyOnly test covers the case of a phone with no SIM
|
||||
mobileLabel = mCurrentState.networkName;
|
||||
}
|
||||
} else {
|
||||
mobileLabel = mContext.getString(
|
||||
R.string.status_bar_settings_signal_meter_disconnected);
|
||||
}
|
||||
|
||||
if (currentLabel.length() != 0) {
|
||||
currentLabel = currentLabel + mNetworkNameSeparator;
|
||||
}
|
||||
// Now for things that should only be shown when actually using mobile data.
|
||||
if (isMobileLabel) {
|
||||
return currentLabel + mobileLabel;
|
||||
} else {
|
||||
return currentLabel
|
||||
+ (mCurrentState.dataConnected ? mobileLabel : currentLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getDataContentDescription() {
|
||||
return getIcons().mDataContentDescription;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected IccCardConstants.State getSimState() {
|
||||
return mSimState;
|
||||
}
|
||||
|
||||
public void setAirplaneMode(boolean airplaneMode) {
|
||||
mCurrentState.airplaneMode = airplaneMode;
|
||||
notifyListenersIfNecessary();
|
||||
}
|
||||
|
||||
public void setInetCondition(int inetCondition, int inetConditionForNetwork) {
|
||||
// For mobile data, use general inet condition for phone signal indexing,
|
||||
// and network specific for data indexing (I think this might be a bug, but
|
||||
// keeping for now).
|
||||
// TODO: Update with explanation of why.
|
||||
mCurrentState.inetForNetwork = inetConditionForNetwork;
|
||||
setInetCondition(inetCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start listening for phone state changes.
|
||||
*/
|
||||
public void registerListener() {
|
||||
mPhone.listen(mPhoneStateListener,
|
||||
PhoneStateListener.LISTEN_SERVICE_STATE
|
||||
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
|
||||
| PhoneStateListener.LISTEN_CALL_STATE
|
||||
| PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
|
||||
| PhoneStateListener.LISTEN_DATA_ACTIVITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop listening for phone state changes.
|
||||
*/
|
||||
public void unregisterListener() {
|
||||
mPhone.listen(mPhoneStateListener, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a mapping of data network types to icon groups for simple and quick use in
|
||||
* updateTelephony.
|
||||
*/
|
||||
private void mapIconSets() {
|
||||
mNetworkToIconLookup.clear();
|
||||
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyIcons.THREE_G);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyIcons.THREE_G);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyIcons.THREE_G);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyIcons.THREE_G);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UMTS, TelephonyIcons.THREE_G);
|
||||
|
||||
if (!mConfig.showAtLeast3G) {
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
TelephonyIcons.UNKNOWN);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE, TelephonyIcons.E);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA, TelephonyIcons.ONE_X);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyIcons.ONE_X);
|
||||
|
||||
mDefaultIcons = TelephonyIcons.G;
|
||||
} else {
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
TelephonyIcons.THREE_G);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE,
|
||||
TelephonyIcons.THREE_G);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA,
|
||||
TelephonyIcons.THREE_G);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT,
|
||||
TelephonyIcons.THREE_G);
|
||||
mDefaultIcons = TelephonyIcons.THREE_G;
|
||||
}
|
||||
|
||||
MobileIconGroup hGroup = TelephonyIcons.THREE_G;
|
||||
if (mConfig.hspaDataDistinguishable) {
|
||||
hGroup = TelephonyIcons.H;
|
||||
}
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSDPA, hGroup);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSUPA, hGroup);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPA, hGroup);
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPAP, hGroup);
|
||||
|
||||
if (mConfig.show4gForLte) {
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.FOUR_G);
|
||||
} else {
|
||||
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.LTE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyListeners() {
|
||||
MobileIconGroup icons = getIcons();
|
||||
|
||||
String contentDescription = getStringIfExists(getContentDescription());
|
||||
String dataContentDescription = getStringIfExists(icons.mDataContentDescription);
|
||||
// Only send data sim callbacks to QS.
|
||||
if (mCurrentState.dataSim) {
|
||||
int qsTypeIcon = mCurrentState.dataConnected ?
|
||||
icons.mQsDataType[mCurrentState.inetForNetwork] : 0;
|
||||
int length = mSignalsChangedCallbacks.size();
|
||||
for (int i = 0; i < length; i++) {
|
||||
mSignalsChangedCallbacks.get(i).onMobileDataSignalChanged(mCurrentState.enabled
|
||||
&& !mCurrentState.isEmergency && !mCurrentState.airplaneMode,
|
||||
getQsCurrentIconId(), contentDescription,
|
||||
qsTypeIcon,
|
||||
mCurrentState.dataConnected && mCurrentState.activityIn,
|
||||
mCurrentState.dataConnected && mCurrentState.activityOut,
|
||||
dataContentDescription,
|
||||
mCurrentState.isEmergency ? null : mCurrentState.networkName,
|
||||
// Only wide if actually showing something.
|
||||
icons.mIsWide && qsTypeIcon != 0);
|
||||
}
|
||||
}
|
||||
boolean showDataIcon = mCurrentState.dataConnected && mCurrentState.inetForNetwork != 0
|
||||
|| mCurrentState.iconGroup == TelephonyIcons.ROAMING;
|
||||
int typeIcon = showDataIcon ? icons.mDataType : 0;
|
||||
int signalClustersLength = mSignalClusters.size();
|
||||
for (int i = 0; i < signalClustersLength; i++) {
|
||||
mSignalClusters.get(i).setMobileDataIndicators(
|
||||
mCurrentState.enabled && !mCurrentState.airplaneMode,
|
||||
getCurrentIconId(),
|
||||
typeIcon,
|
||||
contentDescription,
|
||||
dataContentDescription,
|
||||
// Only wide if actually showing something.
|
||||
icons.mIsWide && typeIcon != 0,
|
||||
mSubscriptionInfo.getSubscriptionId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MobileState cleanState() {
|
||||
return new MobileState();
|
||||
}
|
||||
|
||||
private boolean hasService() {
|
||||
if (mServiceState != null) {
|
||||
// Consider the device to be in service if either voice or data
|
||||
// service is available. Some SIM cards are marketed as data-only
|
||||
// and do not support voice service, and on these SIM cards, we
|
||||
// want to show signal bars for data service as well as the "no
|
||||
// service" or "emergency calls only" text that indicates that voice
|
||||
// is not available.
|
||||
switch (mServiceState.getVoiceRegState()) {
|
||||
case ServiceState.STATE_POWER_OFF:
|
||||
return false;
|
||||
case ServiceState.STATE_OUT_OF_SERVICE:
|
||||
case ServiceState.STATE_EMERGENCY_ONLY:
|
||||
return mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCdma() {
|
||||
return (mSignalStrength != null) && !mSignalStrength.isGsm();
|
||||
}
|
||||
|
||||
public boolean isEmergencyOnly() {
|
||||
return (mServiceState != null && mServiceState.isEmergencyOnly());
|
||||
}
|
||||
|
||||
private boolean isRoaming() {
|
||||
if (isCdma()) {
|
||||
final int iconMode = mServiceState.getCdmaEriIconMode();
|
||||
return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
|
||||
&& (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
|
||||
|| iconMode == EriInfo.ROAMING_ICON_MODE_FLASH);
|
||||
} else {
|
||||
return mServiceState != null && mServiceState.getRoaming();
|
||||
}
|
||||
}
|
||||
|
||||
public void handleBroadcast(Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) {
|
||||
updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
|
||||
intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
|
||||
intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
|
||||
intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
|
||||
notifyListenersIfNecessary();
|
||||
} else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
|
||||
updateDataSim();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDataSim() {
|
||||
int defaultDataSub = SubscriptionManager.getDefaultDataSubId();
|
||||
if (SubscriptionManager.isValidSubscriptionId(defaultDataSub)) {
|
||||
mCurrentState.dataSim = defaultDataSub == mSubscriptionInfo.getSubscriptionId();
|
||||
} else {
|
||||
// There doesn't seem to be a data sim selected, however if
|
||||
// there isn't a MobileSignalController with dataSim set, then
|
||||
// QS won't get any callbacks and will be blank. Instead
|
||||
// lets just assume we are the data sim (which will basically
|
||||
// show one at random) in QS until one is selected. The user
|
||||
// should pick one soon after, so we shouldn't be in this state
|
||||
// for long.
|
||||
mCurrentState.dataSim = true;
|
||||
}
|
||||
notifyListenersIfNecessary();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the network's name based on incoming spn and plmn.
|
||||
*/
|
||||
void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
|
||||
if (CHATTY) {
|
||||
Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
|
||||
+ " showPlmn=" + showPlmn + " plmn=" + plmn);
|
||||
}
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (showPlmn && plmn != null) {
|
||||
str.append(plmn);
|
||||
}
|
||||
if (showSpn && spn != null) {
|
||||
if (str.length() != 0) {
|
||||
str.append(mNetworkNameSeparator);
|
||||
}
|
||||
str.append(spn);
|
||||
}
|
||||
if (str.length() != 0) {
|
||||
mCurrentState.networkName = str.toString();
|
||||
} else {
|
||||
mCurrentState.networkName = mNetworkNameDefault;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current state based on mServiceState, mSignalStrength, mDataNetType,
|
||||
* mDataState, and mSimState. It should be called any time one of these is updated.
|
||||
* This will call listeners if necessary.
|
||||
*/
|
||||
private final void updateTelephony() {
|
||||
if (DEBUG) {
|
||||
Log.d(mTag, "updateTelephonySignalStrength: hasService=" + hasService()
|
||||
+ " ss=" + mSignalStrength);
|
||||
}
|
||||
mCurrentState.connected = hasService() && mSignalStrength != null;
|
||||
if (mCurrentState.connected) {
|
||||
if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
|
||||
mCurrentState.level = mSignalStrength.getCdmaLevel();
|
||||
} else {
|
||||
mCurrentState.level = mSignalStrength.getLevel();
|
||||
}
|
||||
}
|
||||
if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) {
|
||||
mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType);
|
||||
} else {
|
||||
mCurrentState.iconGroup = mDefaultIcons;
|
||||
}
|
||||
mCurrentState.dataConnected = mCurrentState.connected
|
||||
&& mDataState == TelephonyManager.DATA_CONNECTED;
|
||||
|
||||
if (isRoaming()) {
|
||||
mCurrentState.iconGroup = TelephonyIcons.ROAMING;
|
||||
}
|
||||
if (isEmergencyOnly() != mCurrentState.isEmergency) {
|
||||
mCurrentState.isEmergency = isEmergencyOnly();
|
||||
mNetworkController.recalculateEmergency();
|
||||
}
|
||||
// Fill in the network name if we think we have it.
|
||||
if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null
|
||||
&& mServiceState.getOperatorAlphaShort() != null) {
|
||||
mCurrentState.networkName = mServiceState.getOperatorAlphaShort();
|
||||
}
|
||||
notifyListenersIfNecessary();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setActivity(int activity) {
|
||||
mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT
|
||||
|| activity == TelephonyManager.DATA_ACTIVITY_IN;
|
||||
mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT
|
||||
|| activity == TelephonyManager.DATA_ACTIVITY_OUT;
|
||||
notifyListenersIfNecessary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw) {
|
||||
super.dump(pw);
|
||||
pw.println(" mSubscription=" + mSubscriptionInfo + ",");
|
||||
pw.println(" mServiceState=" + mServiceState + ",");
|
||||
pw.println(" mSignalStrength=" + mSignalStrength + ",");
|
||||
pw.println(" mDataState=" + mDataState + ",");
|
||||
pw.println(" mDataNetType=" + mDataNetType + ",");
|
||||
}
|
||||
|
||||
class MobilePhoneStateListener extends PhoneStateListener {
|
||||
public MobilePhoneStateListener(int subId) {
|
||||
super(subId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
|
||||
if (DEBUG) {
|
||||
Log.d(mTag, "onSignalStrengthsChanged signalStrength=" + signalStrength +
|
||||
((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
|
||||
}
|
||||
mSignalStrength = signalStrength;
|
||||
updateTelephony();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceStateChanged(ServiceState state) {
|
||||
if (DEBUG) {
|
||||
Log.d(mTag, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
|
||||
+ " dataState=" + state.getDataRegState());
|
||||
}
|
||||
mServiceState = state;
|
||||
updateTelephony();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataConnectionStateChanged(int state, int networkType) {
|
||||
if (DEBUG) {
|
||||
Log.d(mTag, "onDataConnectionStateChanged: state=" + state
|
||||
+ " type=" + networkType);
|
||||
}
|
||||
mDataState = state;
|
||||
mDataNetType = networkType;
|
||||
updateTelephony();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataActivity(int direction) {
|
||||
if (DEBUG) {
|
||||
Log.d(mTag, "onDataActivity: direction=" + direction);
|
||||
}
|
||||
setActivity(direction);
|
||||
}
|
||||
};
|
||||
|
||||
static class MobileIconGroup extends SignalController.IconGroup {
|
||||
final int mDataContentDescription; // mContentDescriptionDataType
|
||||
final int mDataType;
|
||||
final boolean mIsWide;
|
||||
final int[] mQsDataType;
|
||||
|
||||
public MobileIconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc,
|
||||
int sbNullState, int qsNullState, int sbDiscState, int qsDiscState,
|
||||
int discContentDesc, int dataContentDesc, int dataType, boolean isWide,
|
||||
int[] qsDataType) {
|
||||
super(name, sbIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState,
|
||||
qsDiscState, discContentDesc);
|
||||
mDataContentDescription = dataContentDesc;
|
||||
mDataType = dataType;
|
||||
mIsWide = isWide;
|
||||
mQsDataType = qsDataType;
|
||||
}
|
||||
}
|
||||
|
||||
static class MobileState extends SignalController.State {
|
||||
String networkName;
|
||||
boolean dataSim;
|
||||
boolean dataConnected;
|
||||
boolean isEmergency;
|
||||
boolean airplaneMode;
|
||||
int inetForNetwork;
|
||||
|
||||
@Override
|
||||
public void copyFrom(State s) {
|
||||
super.copyFrom(s);
|
||||
MobileState state = (MobileState) s;
|
||||
dataSim = state.dataSim;
|
||||
networkName = state.networkName;
|
||||
dataConnected = state.dataConnected;
|
||||
inetForNetwork = state.inetForNetwork;
|
||||
isEmergency = state.isEmergency;
|
||||
airplaneMode = state.airplaneMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString(StringBuilder builder) {
|
||||
super.toString(builder);
|
||||
builder.append(',');
|
||||
builder.append("dataSim=").append(dataSim).append(',');
|
||||
builder.append("networkName=").append(networkName).append(',');
|
||||
builder.append("dataConnected=").append(dataConnected).append(',');
|
||||
builder.append("inetForNetwork=").append(inetForNetwork).append(',');
|
||||
builder.append("isEmergency=").append(isEmergency).append(',');
|
||||
builder.append("airplaneMode=").append(airplaneMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o)
|
||||
&& Objects.equals(((MobileState) o).networkName, networkName)
|
||||
&& ((MobileState) o).dataSim == dataSim
|
||||
&& ((MobileState) o).dataConnected == dataConnected
|
||||
&& ((MobileState) o).isEmergency == isEmergency
|
||||
&& ((MobileState) o).airplaneMode == airplaneMode
|
||||
&& ((MobileState) o).inetForNetwork == inetForNetwork;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 static com.android.systemui.statusbar.policy.NetworkControllerImpl.TAG;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.format.DateFormat;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Common base class for handling signal for both wifi and mobile data.
|
||||
*/
|
||||
public abstract class SignalController<T extends SignalController.State,
|
||||
I extends SignalController.IconGroup> {
|
||||
// Save the previous SignalController.States of all SignalControllers for dumps.
|
||||
static final boolean RECORD_HISTORY = true;
|
||||
// If RECORD_HISTORY how many to save, must be a power of 2.
|
||||
static final int HISTORY_SIZE = 16;
|
||||
|
||||
protected static final boolean DEBUG = NetworkControllerImpl.DEBUG;
|
||||
protected static final boolean CHATTY = NetworkControllerImpl.CHATTY;
|
||||
|
||||
protected final String mTag;
|
||||
protected final T mCurrentState;
|
||||
protected final T mLastState;
|
||||
protected final int mTransportType;
|
||||
protected final Context mContext;
|
||||
// The owner of the SignalController (i.e. NetworkController will maintain the following
|
||||
// lists and call notifyListeners whenever the list has changed to ensure everyone
|
||||
// is aware of current state.
|
||||
protected final List<NetworkSignalChangedCallback> mSignalsChangedCallbacks;
|
||||
protected final List<SignalCluster> mSignalClusters;
|
||||
protected final NetworkControllerImpl mNetworkController;
|
||||
|
||||
// Save the previous HISTORY_SIZE states for logging.
|
||||
private final State[] mHistory;
|
||||
// Where to copy the next state into.
|
||||
private int mHistoryIndex;
|
||||
|
||||
public SignalController(String tag, Context context, int type,
|
||||
List<NetworkSignalChangedCallback> signalCallbacks,
|
||||
List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
|
||||
mTag = TAG + "." + tag;
|
||||
mNetworkController = networkController;
|
||||
mTransportType = type;
|
||||
mContext = context;
|
||||
mSignalsChangedCallbacks = signalCallbacks;
|
||||
mSignalClusters = signalClusters;
|
||||
mCurrentState = cleanState();
|
||||
mLastState = cleanState();
|
||||
if (RECORD_HISTORY) {
|
||||
mHistory = new State[HISTORY_SIZE];
|
||||
for (int i = 0; i < HISTORY_SIZE; i++) {
|
||||
mHistory[i] = cleanState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public T getState() {
|
||||
return mCurrentState;
|
||||
}
|
||||
|
||||
public int getTransportType() {
|
||||
return mTransportType;
|
||||
}
|
||||
|
||||
public void setInetCondition(int inetCondition) {
|
||||
mCurrentState.inetCondition = inetCondition;
|
||||
notifyListenersIfNecessary();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used at the end of demo mode to clear out any ugly state that it has created.
|
||||
* Since we haven't had any callbacks, then isDirty will not have been triggered,
|
||||
* so we can just take the last good state directly from there.
|
||||
*
|
||||
* Used for demo mode.
|
||||
*/
|
||||
public void resetLastState() {
|
||||
mCurrentState.copyFrom(mLastState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the state of this signal controller has changed and
|
||||
* needs to trigger callbacks related to it.
|
||||
*/
|
||||
public boolean isDirty() {
|
||||
if (!mLastState.equals(mCurrentState)) {
|
||||
if (DEBUG) {
|
||||
Log.d(mTag, "Change in state from: " + mLastState + "\n"
|
||||
+ "\tto: " + mCurrentState);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void saveLastState() {
|
||||
if (RECORD_HISTORY) {
|
||||
recordLastState();
|
||||
}
|
||||
// Updates the current time.
|
||||
mCurrentState.time = System.currentTimeMillis();
|
||||
mLastState.copyFrom(mCurrentState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the signal icon for QS based on current state of connected, enabled, and level.
|
||||
*/
|
||||
public int getQsCurrentIconId() {
|
||||
if (mCurrentState.connected) {
|
||||
return getIcons().mQsIcons[mCurrentState.inetCondition][mCurrentState.level];
|
||||
} else if (mCurrentState.enabled) {
|
||||
return getIcons().mQsDiscState;
|
||||
} else {
|
||||
return getIcons().mQsNullState;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the signal icon for SB based on current state of connected, enabled, and level.
|
||||
*/
|
||||
public int getCurrentIconId() {
|
||||
if (mCurrentState.connected) {
|
||||
return getIcons().mSbIcons[mCurrentState.inetCondition][mCurrentState.level];
|
||||
} else if (mCurrentState.enabled) {
|
||||
return getIcons().mSbDiscState;
|
||||
} else {
|
||||
return getIcons().mSbNullState;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the content description id for the signal based on current state of connected and
|
||||
* level.
|
||||
*/
|
||||
public int getContentDescription() {
|
||||
if (mCurrentState.connected) {
|
||||
return getIcons().mContentDesc[mCurrentState.level];
|
||||
} else {
|
||||
return getIcons().mDiscContentDesc;
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyListenersIfNecessary() {
|
||||
if (isDirty()) {
|
||||
saveLastState();
|
||||
notifyListeners();
|
||||
mNetworkController.refreshCarrierLabel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource if resId is not 0, and an empty string otherwise.
|
||||
*/
|
||||
protected String getStringIfExists(int resId) {
|
||||
return resId != 0 ? mContext.getString(resId) : "";
|
||||
}
|
||||
|
||||
protected I getIcons() {
|
||||
return (I) mCurrentState.iconGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the last state of any changes, so we can log the current
|
||||
* and last value of any state data.
|
||||
*/
|
||||
protected void recordLastState() {
|
||||
mHistory[mHistoryIndex++ & (HISTORY_SIZE - 1)].copyFrom(mLastState);
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println(" - " + mTag + " -----");
|
||||
pw.println(" Current State: " + mCurrentState);
|
||||
if (RECORD_HISTORY) {
|
||||
// Count up the states that actually contain time stamps, and only display those.
|
||||
int size = 0;
|
||||
for (int i = 0; i < HISTORY_SIZE; i++) {
|
||||
if (mHistory[i].time != 0) size++;
|
||||
}
|
||||
// Print out the previous states in ordered number.
|
||||
for (int i = mHistoryIndex + HISTORY_SIZE - 1;
|
||||
i >= mHistoryIndex + HISTORY_SIZE - size; i--) {
|
||||
pw.println(" Previous State(" + (mHistoryIndex + HISTORY_SIZE - i) + "): "
|
||||
+ mHistory[i & (HISTORY_SIZE - 1)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger callbacks based on current state. The callbacks should be completely
|
||||
* based on current state, and only need to be called in the scenario where
|
||||
* mCurrentState != mLastState.
|
||||
*/
|
||||
public abstract void notifyListeners();
|
||||
|
||||
/**
|
||||
* Generate a blank T.
|
||||
*/
|
||||
protected abstract T cleanState();
|
||||
|
||||
/*
|
||||
* Holds icons for a given state. Arrays are generally indexed as inet
|
||||
* state (full connectivity or not) first, and second dimension as
|
||||
* signal strength.
|
||||
*/
|
||||
static class IconGroup {
|
||||
final int[][] mSbIcons;
|
||||
final int[][] mQsIcons;
|
||||
final int[] mContentDesc;
|
||||
final int mSbNullState;
|
||||
final int mQsNullState;
|
||||
final int mSbDiscState;
|
||||
final int mQsDiscState;
|
||||
final int mDiscContentDesc;
|
||||
// For logging.
|
||||
final String mName;
|
||||
|
||||
public IconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc,
|
||||
int sbNullState, int qsNullState, int sbDiscState, int qsDiscState,
|
||||
int discContentDesc) {
|
||||
mName = name;
|
||||
mSbIcons = sbIcons;
|
||||
mQsIcons = qsIcons;
|
||||
mContentDesc = contentDesc;
|
||||
mSbNullState = sbNullState;
|
||||
mQsNullState = qsNullState;
|
||||
mSbDiscState = sbDiscState;
|
||||
mQsDiscState = qsDiscState;
|
||||
mDiscContentDesc = discContentDesc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IconGroup(" + mName + ")";
|
||||
}
|
||||
}
|
||||
|
||||
static class State {
|
||||
boolean connected;
|
||||
boolean enabled;
|
||||
boolean activityIn;
|
||||
boolean activityOut;
|
||||
int level;
|
||||
IconGroup iconGroup;
|
||||
int inetCondition;
|
||||
int rssi; // Only for logging.
|
||||
|
||||
// Not used for comparison, just used for logging.
|
||||
long time;
|
||||
|
||||
public void copyFrom(State state) {
|
||||
connected = state.connected;
|
||||
enabled = state.enabled;
|
||||
level = state.level;
|
||||
iconGroup = state.iconGroup;
|
||||
inetCondition = state.inetCondition;
|
||||
activityIn = state.activityIn;
|
||||
activityOut = state.activityOut;
|
||||
rssi = state.rssi;
|
||||
time = state.time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (time != 0) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
toString(builder);
|
||||
return builder.toString();
|
||||
} else {
|
||||
return "Empty " + getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
protected void toString(StringBuilder builder) {
|
||||
builder.append("connected=").append(connected).append(',')
|
||||
.append("enabled=").append(enabled).append(',')
|
||||
.append("level=").append(level).append(',')
|
||||
.append("inetCondition=").append(inetCondition).append(',')
|
||||
.append("iconGroup=").append(iconGroup).append(',')
|
||||
.append("activityIn=").append(activityIn).append(',')
|
||||
.append("activityOut=").append(activityOut).append(',')
|
||||
.append("rssi=").append(rssi).append(',')
|
||||
.append("lastModified=").append(DateFormat.format("MM-dd hh:mm:ss", time));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!o.getClass().equals(getClass())) {
|
||||
return false;
|
||||
}
|
||||
State other = (State) o;
|
||||
return other.connected == connected
|
||||
&& other.enabled == enabled
|
||||
&& other.level == level
|
||||
&& other.inetCondition == inetCondition
|
||||
&& other.iconGroup == iconGroup
|
||||
&& other.activityIn == activityIn
|
||||
&& other.activityOut == activityOut
|
||||
&& other.rssi == rssi;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
package com.android.systemui.statusbar.policy;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl.MobileSignalController.MobileIconGroup;
|
||||
import com.android.systemui.statusbar.policy.MobileSignalController.MobileIconGroup;
|
||||
|
||||
class TelephonyIcons {
|
||||
//***** Signal strength icons
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class WifiSignalController extends
|
||||
SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
|
||||
private final WifiManager mWifiManager;
|
||||
private final AsyncChannel mWifiChannel;
|
||||
private final boolean mHasMobileData;
|
||||
|
||||
public WifiSignalController(Context context, boolean hasMobileData,
|
||||
List<NetworkSignalChangedCallback> signalCallbacks,
|
||||
List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
|
||||
super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
|
||||
signalCallbacks, signalClusters, networkController);
|
||||
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
mHasMobileData = hasMobileData;
|
||||
Handler handler = new WifiHandler();
|
||||
mWifiChannel = new AsyncChannel();
|
||||
Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger();
|
||||
if (wifiMessenger != null) {
|
||||
mWifiChannel.connect(context, handler, wifiMessenger);
|
||||
}
|
||||
// WiFi only has one state.
|
||||
mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup(
|
||||
"Wi-Fi Icons",
|
||||
WifiIcons.WIFI_SIGNAL_STRENGTH,
|
||||
WifiIcons.QS_WIFI_SIGNAL_STRENGTH,
|
||||
AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
|
||||
WifiIcons.WIFI_NO_NETWORK,
|
||||
WifiIcons.QS_WIFI_NO_NETWORK,
|
||||
WifiIcons.WIFI_NO_NETWORK,
|
||||
WifiIcons.QS_WIFI_NO_NETWORK,
|
||||
AccessibilityContentDescriptions.WIFI_NO_CONNECTION
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WifiState cleanState() {
|
||||
return new WifiState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyListeners() {
|
||||
// only show wifi in the cluster if connected or if wifi-only
|
||||
boolean wifiVisible = mCurrentState.enabled
|
||||
&& (mCurrentState.connected || !mHasMobileData);
|
||||
String wifiDesc = wifiVisible ? mCurrentState.ssid : null;
|
||||
boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
|
||||
String contentDescription = getStringIfExists(getContentDescription());
|
||||
int length = mSignalsChangedCallbacks.size();
|
||||
for (int i = 0; i < length; i++) {
|
||||
mSignalsChangedCallbacks.get(i).onWifiSignalChanged(mCurrentState.enabled,
|
||||
mCurrentState.connected, getQsCurrentIconId(),
|
||||
ssidPresent && mCurrentState.activityIn,
|
||||
ssidPresent && mCurrentState.activityOut, contentDescription, wifiDesc);
|
||||
}
|
||||
|
||||
int signalClustersLength = mSignalClusters.size();
|
||||
for (int i = 0; i < signalClustersLength; i++) {
|
||||
mSignalClusters.get(i).setWifiIndicators(wifiVisible, getCurrentIconId(),
|
||||
contentDescription);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract wifi state directly from broadcasts about changes in wifi state.
|
||||
*/
|
||||
public void handleBroadcast(Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
|
||||
mCurrentState.enabled = 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);
|
||||
mCurrentState.connected = networkInfo != null && networkInfo.isConnected();
|
||||
// If Connected grab the signal strength and ssid.
|
||||
if (mCurrentState.connected) {
|
||||
// try getting it out of the intent first
|
||||
WifiInfo info = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO) != null
|
||||
? (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO)
|
||||
: mWifiManager.getConnectionInfo();
|
||||
if (info != null) {
|
||||
mCurrentState.ssid = getSsid(info);
|
||||
} else {
|
||||
mCurrentState.ssid = null;
|
||||
}
|
||||
} else if (!mCurrentState.connected) {
|
||||
mCurrentState.ssid = null;
|
||||
}
|
||||
} else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
|
||||
// Default to -200 as its below WifiManager.MIN_RSSI.
|
||||
mCurrentState.rssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
|
||||
mCurrentState.level = WifiManager.calculateSignalLevel(
|
||||
mCurrentState.rssi, WifiIcons.WIFI_LEVEL_COUNT);
|
||||
}
|
||||
|
||||
notifyListenersIfNecessary();
|
||||
}
|
||||
|
||||
private String getSsid(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();
|
||||
int length = networks.size();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (networks.get(i).networkId == info.getNetworkId()) {
|
||||
return networks.get(i).SSID;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setActivity(int wifiActivity) {
|
||||
mCurrentState.activityIn = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
|
||||
|| wifiActivity == WifiManager.DATA_ACTIVITY_IN;
|
||||
mCurrentState.activityOut = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
|
||||
|| wifiActivity == WifiManager.DATA_ACTIVITY_OUT;
|
||||
notifyListenersIfNecessary();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler to receive the data activity on wifi.
|
||||
*/
|
||||
private class WifiHandler extends Handler {
|
||||
@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 {
|
||||
Log.e(mTag, "Failed to connect to wifi");
|
||||
}
|
||||
break;
|
||||
case WifiManager.DATA_ACTIVITY_NOTIFICATION:
|
||||
setActivity(msg.arg1);
|
||||
break;
|
||||
default:
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class WifiState extends SignalController.State {
|
||||
String ssid;
|
||||
|
||||
@Override
|
||||
public void copyFrom(State s) {
|
||||
super.copyFrom(s);
|
||||
WifiState state = (WifiState) s;
|
||||
ssid = state.ssid;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString(StringBuilder builder) {
|
||||
super.toString(builder);
|
||||
builder.append(',').append("ssid=").append(ssid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o)
|
||||
&& Objects.equals(((WifiState) o).ssid, ssid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkCapabilities;
|
||||
@@ -26,13 +33,19 @@ import android.test.AndroidTestCase;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.telephony.TelephonyIntents;
|
||||
import com.android.internal.telephony.cdma.EriInfo;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl.MobileSignalController;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
|
||||
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NetworkControllerBaseTest extends AndroidTestCase {
|
||||
private static final String TAG = "NetworkControllerBaseTest";
|
||||
protected static final int DEFAULT_LEVEL = 2;
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
@@ -18,7 +27,11 @@ import android.telephony.TelephonyManager;
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.telephony.TelephonyIntents;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl.MobileSignalController;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user