Merge "Device show "No SIM card" and then showing carrier name during boot" into pi-dev

am: 2f97046a4e

Change-Id: I3f3f5d49b390dd7841ade7e33fd2ddc5e5309aa1
This commit is contained in:
Bill Lin
2018-10-24 02:49:00 -07:00
committed by android-build-merger
8 changed files with 281 additions and 29 deletions

View File

@@ -38,9 +38,5 @@
<attr name="android:textColor" format="color" />
</declare-styleable>
<declare-styleable name="CarrierText">
<attr name="allCaps" format="boolean" />
</declare-styleable>
<attr name="passwordStyle" format="reference" />
</resources>

View File

@@ -18,7 +18,7 @@
<!-- Extends RelativeLayout -->
<com.android.systemui.statusbar.phone.KeyguardStatusBarView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/keyguard_header"
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_header_height_keyguard"
@@ -73,6 +73,8 @@
android:textDirection="locale"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?attr/wallpaperTextColorSecondary"
android:singleLine="true" />
android:singleLine="true"
systemui:showMissingSim="true"
systemui:showAirplaneMode="true" />
</com.android.systemui.statusbar.phone.KeyguardStatusBarView>

View File

@@ -143,5 +143,11 @@
<attr name="rotateButtonEndAngle" format="float" />
<attr name="rotateButtonScaleX" format="float" />
<!-- Used display CarrierText in Keyguard or QS Footer -->
<declare-styleable name="CarrierText">
<attr name="allCaps" format="boolean" />
<attr name="showMissingSim" format="boolean" />
<attr name="showAirplaneMode" format="boolean" />
</declare-styleable>
</resources>

View File

@@ -43,11 +43,6 @@ import com.android.settingslib.WirelessUtils;
import android.telephony.TelephonyManager;
public class CarrierText extends TextView {
/** Do not show missing sim message. */
public static final int FLAG_HIDE_MISSING_SIM = 1 << 0;
/** Do not show airplane mode message. */
public static final int FLAG_HIDE_AIRPLANE_MODE = 1 << 1;
private static final boolean DEBUG = KeyguardConstants.DEBUG;
private static final String TAG = "CarrierText";
@@ -55,17 +50,23 @@ public class CarrierText extends TextView {
private final boolean mIsEmergencyCallCapable;
private boolean mTelephonyCapable;
private boolean mShowMissingSim;
private boolean mShowAirplaneMode;
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private WifiManager mWifiManager;
private boolean[] mSimErrorState = new boolean[TelephonyManager.getDefault().getPhoneCount()];
private int mFlags;
private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onRefreshCarrierInfo() {
if (DEBUG) Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: "
+ Boolean.toString(mTelephonyCapable));
updateCarrierText();
}
@@ -77,9 +78,18 @@ public class CarrierText extends TextView {
setSelected(true);
};
@Override
public void onTelephonyCapable(boolean capable) {
if (DEBUG) Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: "
+ Boolean.toString(capable));
mTelephonyCapable = capable;
updateCarrierText();
}
public void onSimStateChanged(int subId, int slotId, IccCardConstants.State simState) {
if (slotId < 0) {
Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId);
Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId
+ " mTelephonyCapable: " + Boolean.toString(mTelephonyCapable));
return;
}
@@ -91,13 +101,9 @@ public class CarrierText extends TextView {
mSimErrorState[slotId] = false;
updateCarrierText();
}
};
}
};
public void setDisplayFlags(int flags) {
mFlags = flags;
}
/**
* The status of this lock screen. Primarily used for widgets on LockScreen.
*/
@@ -110,7 +116,8 @@ public class CarrierText extends TextView {
SimLocked, // SIM card is currently locked
SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM.
SimIoError; // SIM card is faulty
SimIoError, // SIM card is faulty
SimUnknown // SIM card is unknown
}
public CarrierText(Context context) {
@@ -126,6 +133,8 @@ public class CarrierText extends TextView {
attrs, R.styleable.CarrierText, 0, 0);
try {
useAllCaps = a.getBoolean(R.styleable.CarrierText_allCaps, false);
mShowAirplaneMode = a.getBoolean(R.styleable.CarrierText_showAirplaneMode, false);
mShowMissingSim = a.getBoolean(R.styleable.CarrierText_showMissingSim, false);
} finally {
a.recycle();
}
@@ -249,12 +258,12 @@ public class CarrierText extends TextView {
}
private String getMissingSimMessage() {
return (mFlags & FLAG_HIDE_MISSING_SIM) == 0
return mShowMissingSim && mTelephonyCapable
? getContext().getString(R.string.keyguard_missing_sim_message_short) : "";
}
private String getAirplaneModeMessage() {
return (mFlags & FLAG_HIDE_AIRPLANE_MODE) == 0
return mShowAirplaneMode
? getContext().getString(R.string.airplane_mode) : "";
}
@@ -360,6 +369,9 @@ public class CarrierText extends TextView {
getContext().getText(R.string.keyguard_sim_error_message_short),
text);
break;
case SimUnknown:
carrierText = null;
break;
}
return carrierText;
@@ -408,11 +420,11 @@ public class CarrierText extends TextView {
case PERM_DISABLED:
return StatusMode.SimPermDisabled;
case UNKNOWN:
return StatusMode.SimMissing;
return StatusMode.SimUnknown;
case CARD_IO_ERROR:
return StatusMode.SimIoError;
}
return StatusMode.SimMissing;
return StatusMode.SimUnknown;
}
private static CharSequence concatenate(CharSequence plmn, CharSequence spn) {

View File

@@ -82,6 +82,7 @@ import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.Preconditions;
import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.WirelessUtils;
import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -146,6 +147,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
private static final int MSG_FINGERPRINT_AUTHENTICATION_CONTINUE = 336;
private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
private static final int MSG_TELEPHONY_CAPABLE = 338;
/** Fingerprint state: Not listening to fingerprint. */
private static final int FINGERPRINT_STATE_STOPPED = 0;
@@ -202,6 +204,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private boolean mHasLockscreenWallpaper;
private boolean mAssistantVisible;
private boolean mKeyguardOccluded;
@VisibleForTesting
protected boolean mTelephonyCapable;
// Device provisioning state
private boolean mDeviceProvisioned;
@@ -337,6 +341,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
updateLogoutEnabled();
break;
case MSG_TELEPHONY_CAPABLE:
updateTelephonyCapable((boolean)msg.obj);
break;
default:
super.handleMessage(msg);
break;
@@ -789,14 +796,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
maxChargingMicroWatt));
mHandler.sendMessage(msg);
} else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
SimData args = SimData.fromIntent(intent);
// ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
// keep compatibility with apps that aren't direct boot aware.
// SysUI should just ignore this broadcast because it was already received
// and processed previously.
if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
// Guarantee mTelephonyCapable state after SysUI crash and restart
if (args.simState == State.ABSENT) {
mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget();
}
return;
}
SimData args = SimData.fromIntent(intent);
if (DEBUG_SIM_STATES) {
Log.v(TAG, "action " + action
+ " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
@@ -1243,6 +1254,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
mUserManager = context.getSystemService(UserManager.class);
mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
updateAirplaneModeState();
}
private void updateAirplaneModeState() {
// ACTION_AIRPLANE_MODE_CHANGED do not broadcast if device set AirplaneMode ON and boot
if (!WirelessUtils.isAirplaneModeOn(mContext)
|| mHandler.hasMessages(MSG_AIRPLANE_MODE_CHANGED)) {
return;
}
mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
}
private void updateFingerprintListeningState() {
@@ -1524,6 +1545,23 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
}
/**
* Handle Telephony status during Boot for CarrierText display policy
*/
@VisibleForTesting
void updateTelephonyCapable(boolean capable){
if (capable == mTelephonyCapable) {
return;
}
mTelephonyCapable = capable;
for (WeakReference<KeyguardUpdateMonitorCallback> ref : mCallbacks) {
KeyguardUpdateMonitorCallback cb = ref.get();
if (cb != null) {
cb.onTelephonyCapable(mTelephonyCapable);
}
}
}
/**
* Handle {@link #MSG_SIM_STATE_CHANGE}
*/
@@ -1537,6 +1575,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Log.w(TAG, "invalid subId in handleSimStateChange()");
/* Only handle No SIM(ABSENT) due to handleServiceStateChange() handle other case */
if (state == State.ABSENT) {
updateTelephonyCapable(true);
}
return;
}
@@ -1565,7 +1607,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
/**
* Handle {@link #MSG_SERVICE_STATE_CHANGE}
*/
private void handleServiceStateChange(int subId, ServiceState serviceState) {
@VisibleForTesting
void handleServiceStateChange(int subId, ServiceState serviceState) {
if (DEBUG) {
Log.d(TAG,
"handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
@@ -1574,6 +1617,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Log.w(TAG, "invalid subId in handleServiceStateChange()");
return;
} else {
updateTelephonyCapable(true);
}
mServiceStates.put(subId, serviceState);
@@ -1737,6 +1782,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
callback.onRefreshCarrierInfo();
callback.onClockVisibilityChanged();
callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
callback.onTelephonyCapable(mTelephonyCapable);
for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
final SimData state = data.getValue();
callback.onSimStateChanged(state.subId, state.slotId, state.simState);

View File

@@ -116,6 +116,12 @@ public class KeyguardUpdateMonitorCallback {
*/
public void onUserSwitchComplete(int userId) { }
/**
* Called when the Telephony capable
* @param capable
*/
public void onTelephonyCapable(boolean capable) { }
/**
* Called when the SIM state changes.
* @param slotId

View File

@@ -123,8 +123,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
mMobileSignal = findViewById(R.id.mobile_signal);
mMobileRoaming = findViewById(R.id.mobile_roaming);
mCarrierText = findViewById(R.id.qs_carrier_text);
mCarrierText.setDisplayFlags(
CarrierText.FLAG_HIDE_AIRPLANE_MODE | CarrierText.FLAG_HIDE_MISSING_SIM);
mMultiUserSwitch = findViewById(R.id.multi_user_switch);
mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar);

View File

@@ -16,14 +16,22 @@
package com.android.keyguard;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.truth.Truth.*;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.systemui.SysuiTestCase;
@@ -70,6 +78,184 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
keyguardUpdateMonitor.hasSimStateJustChanged());
}
@Test
public void testTelephonyCapable_BootInitState() {
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isFalse();
}
@Test
public void testTelephonyCapable_SimState_Absent() {
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
, IccCardConstants.INTENT_VALUE_ICC_ABSENT);
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent,null, false));
mTestableLooper.processAllMessages();
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isTrue();
}
@Test
public void testTelephonyCapable_SimInvalid_ServiceState_InService() {
// SERVICE_STATE - IN_SERVICE, but SIM_STATE is invalid TelephonyCapable should be False
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Bundle data = new Bundle();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_IN_SERVICE);
state.fillInNotifierBundle(data);
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent, data, false));
mTestableLooper.processAllMessages();
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isFalse();
}
@Test
public void testTelephonyCapable_SimValid_ServiceState_PowerOff() {
// Simulate AirplaneMode case, SERVICE_STATE - POWER_OFF, check TelephonyCapable False
// Only receive ServiceState callback IN_SERVICE -> OUT_OF_SERVICE -> POWER_OFF
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
, IccCardConstants.INTENT_VALUE_ICC_LOADED);
Bundle data = new Bundle();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_POWER_OFF);
state.fillInNotifierBundle(data);
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent, data, true));
mTestableLooper.processAllMessages();
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isTrue();
}
/* Normal SIM inserted flow
* ServiceState: ---OutOfServie----->PowerOff->OutOfServie--->InService
* SimState: ----NOT_READY---->READY----------------------LOADED>>>
* Subscription: --------null---->null--->"Chunghwa Telecom"-------->>>
* System: -------------------------------BOOT_COMPLETED------>>>
* TelephonyCapable:(F)-(F)-(F)-(F)-(F)-(F)-(F)-(F)-(F)-(F)------(T)-(T)>>
*/
@Test
public void testTelephonyCapable_BootInitState_ServiceState_OutOfService() {
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Bundle data = new Bundle();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_OUT_OF_SERVICE);
state.fillInNotifierBundle(data);
intent.putExtras(data);
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent, data, false));
mTestableLooper.processAllMessages();
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isFalse();
}
@Test
public void testTelephonyCapable_BootInitState_SimState_NotReady() {
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
Bundle data = new Bundle();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_OUT_OF_SERVICE);
state.fillInNotifierBundle(data);
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
, IccCardConstants.INTENT_VALUE_ICC_NOT_READY);
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent, data, false));
mTestableLooper.processAllMessages();
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isFalse();
}
@Test
public void testTelephonyCapable_BootInitState_SimState_Ready() {
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
Bundle data = new Bundle();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_OUT_OF_SERVICE);
state.fillInNotifierBundle(data);
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
, IccCardConstants.INTENT_VALUE_ICC_READY);
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent, data, false));
mTestableLooper.processAllMessages();
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isFalse();
}
@Test
public void testTelephonyCapable_BootInitState_ServiceState_PowerOff() {
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Bundle data = new Bundle();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_POWER_OFF);
state.fillInNotifierBundle(data);
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent, data, false));
mTestableLooper.processAllMessages();
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isFalse();
}
@Test
public void testTelephonyCapable_SimValid_ServiceState_InService() {
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Bundle data = new Bundle();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_IN_SERVICE);
state.fillInNotifierBundle(data);
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent, data, true));
mTestableLooper.processAllMessages();
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isTrue();
}
@Test
public void testTelephonyCapable_SimValid_SimState_Loaded() {
TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
new TestableKeyguardUpdateMonitor(getContext());
Bundle data = new Bundle();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_IN_SERVICE);
state.fillInNotifierBundle(data);
Intent intentSimState = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intentSimState.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
, IccCardConstants.INTENT_VALUE_ICC_LOADED);
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intentSimState, data, true));
mTestableLooper.processAllMessages();
// Even SimState Loaded, still need ACTION_SERVICE_STATE_CHANGED turn on mTelephonyCapable
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isFalse();
Intent intentServiceState = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
intentSimState.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
, IccCardConstants.INTENT_VALUE_ICC_LOADED);
keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intentServiceState, data, true));
mTestableLooper.processAllMessages();
assertThat(keyguardUpdateMonitor.mTelephonyCapable).isTrue();
}
private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
int subscription = simInited
? 1/* mock subid=1 */ : SubscriptionManager.DUMMY_SUBSCRIPTION_ID_BASE;
if (data != null) intent.putExtras(data);
intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
intent.putExtra("subscription", subscription);
intent.putExtra("slot", 0/* SLOT 1 */);
return intent;
}
private class TestableKeyguardUpdateMonitor extends KeyguardUpdateMonitor {
AtomicBoolean mSimStateChanged = new AtomicBoolean(false);