Ignore SIM removed event when the system is shutting down
When the SIM is removed, the VVM account will be deactivated to protect user data. When the system is shutting down, the modem shutdown process will be interpreted as SIM removal and the event will be sent. This causes VVM to return to "not activated" state every time the phone is rebooted. If the phone is booted without signal or in airplane mode, the VVM tab will be missing since activation is not attempted without signal.
In this CL, BOOT_COMPLETED and ACTION_SHUTDOWN will be used to store the "shutting down" state in a shared preference. If the SIM is removed between ACTION_SHUTDOWN and BOOT_COMPLETED, it will be ignored.
SIM removal in FBE is already ignored. SIM removal in power off state is never handled.
If the broadcasts are missed (which is improbable), removing the SIM will not remove the VVM tab, until removing it again after the next boot.
Bug: 63642638
Test: OmtpServiceTest
PiperOrigin-RevId: 162298120
Change-Id: I8e093607529de75c28a4869861f18d28406f8042
diff --git a/java/com/android/voicemail/AndroidManifest.xml b/java/com/android/voicemail/AndroidManifest.xml
index 35beaf3..817cf1b 100644
--- a/java/com/android/voicemail/AndroidManifest.xml
+++ b/java/com/android/voicemail/AndroidManifest.xml
@@ -41,5 +41,13 @@
<data android:scheme="android_secret_code" />
</intent-filter>
</receiver>
+
+ <receiver android:name="com.android.voicemail.VoicemailPowerCycleReceiver"
+ android:exported="false">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <action android:name="android.intent.action.ACTION_SHUTDOWN" />
+ </intent-filter>
+ </receiver>
</application>
</manifest>
diff --git a/java/com/android/voicemail/VoicemailClient.java b/java/com/android/voicemail/VoicemailClient.java
index 847919a..28d2bf0 100644
--- a/java/com/android/voicemail/VoicemailClient.java
+++ b/java/com/android/voicemail/VoicemailClient.java
@@ -142,4 +142,10 @@
@NonNull
PersistableBundle getConfig(
@NonNull Context context, @Nullable PhoneAccountHandle phoneAccountHandle);
+
+ @MainThread
+ void onBoot(@NonNull Context context);
+
+ @MainThread
+ void onShutdown(@NonNull Context context);
}
diff --git a/java/com/android/voicemail/VoicemailPowerCycleReceiver.java b/java/com/android/voicemail/VoicemailPowerCycleReceiver.java
new file mode 100644
index 0000000..e9362b4
--- /dev/null
+++ b/java/com/android/voicemail/VoicemailPowerCycleReceiver.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 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.voicemail;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import com.android.dialer.common.Assert;
+
+/** Receives {@link Intent#ACTION_BOOT_COMPLETED} and {@link Intent#ACTION_SHUTDOWN} */
+public class VoicemailPowerCycleReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ VoicemailClient voicemailClient = VoicemailComponent.get(context).getVoicemailClient();
+ if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ voicemailClient.onBoot(context);
+ } else if (Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
+ voicemailClient.onShutdown(context);
+ } else {
+ throw Assert.createAssertionFailException("unexpected action: " + intent.getAction());
+ }
+ }
+}
diff --git a/java/com/android/voicemail/impl/AndroidManifest.xml b/java/com/android/voicemail/impl/AndroidManifest.xml
index 3c7df66..d3c7a4a 100644
--- a/java/com/android/voicemail/impl/AndroidManifest.xml
+++ b/java/com/android/voicemail/impl/AndroidManifest.xml
@@ -113,13 +113,6 @@
android:windowSoftInputMode="stateVisible|adjustResize">
</activity>
- <receiver android:name="com.android.voicemail.impl.VoicemailBootReceiver"
- android:exported="false">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- </receiver>
-
<receiver android:name="com.android.voicemail.impl.PackageReplacedReceiver"
android:exported="false">
<intent-filter>
diff --git a/java/com/android/voicemail/impl/OmtpService.java b/java/com/android/voicemail/impl/OmtpService.java
index b82cc5f..4db1aeb 100644
--- a/java/com/android/voicemail/impl/OmtpService.java
+++ b/java/com/android/voicemail/impl/OmtpService.java
@@ -17,9 +17,13 @@
package com.android.voicemail.impl;
import android.annotation.TargetApi;
+import android.content.Context;
import android.content.Intent;
import android.os.Build.VERSION_CODES;
import android.os.UserManager;
+import android.preference.PreferenceManager;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
import android.telecom.PhoneAccountHandle;
import android.telephony.VisualVoicemailService;
import android.telephony.VisualVoicemailSms;
@@ -40,6 +44,8 @@
public static final String EXTRA_VOICEMAIL_SMS = "extra_voicemail_sms";
+ private static final String IS_SHUTTING_DOWN = "com.android.voicemail.impl.is_shutting_down";
+
@Override
public void onCellServiceConnected(
VisualVoicemailTask task, final PhoneAccountHandle phoneAccountHandle) {
@@ -50,7 +56,7 @@
return;
}
- if (!isUserUnlocked()) {
+ if (!isUserUnlocked(this)) {
VvmLog.i(TAG, "onCellServiceConnected: user locked");
task.finish();
return;
@@ -75,7 +81,7 @@
return;
}
- if (!isUserUnlocked()) {
+ if (!isUserUnlocked(this)) {
LegacyModeSmsHandler.handle(this, sms);
return;
}
@@ -105,12 +111,18 @@
return;
}
- if (!isUserUnlocked()) {
+ if (!isUserUnlocked(this)) {
VvmLog.i(TAG, "onSimRemoved: user locked");
task.finish();
return;
}
+ if (isShuttingDown(this)) {
+ VvmLog.i(TAG, "onSimRemoved: system shutting down, ignoring");
+ task.finish();
+ return;
+ }
+
Logger.get(this).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
VvmAccountManager.removeAccount(this, phoneAccountHandle);
task.finish();
@@ -124,7 +136,7 @@
task.finish();
return;
}
- if (!isUserUnlocked()) {
+ if (!isUserUnlocked(this)) {
VvmLog.i(TAG, "onStopped: user locked");
task.finish();
return;
@@ -132,6 +144,22 @@
Logger.get(this).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
}
+ @MainThread
+ static void onBoot(@NonNull Context context) {
+ VvmLog.i(TAG, "onBoot");
+ Assert.isTrue(isUserUnlocked(context));
+ Assert.isMainThread();
+ setShuttingDown(context, false);
+ }
+
+ @MainThread
+ static void onShutdown(@NonNull Context context) {
+ VvmLog.i(TAG, "onShutdown");
+ Assert.isTrue(isUserUnlocked(context));
+ Assert.isMainThread();
+ setShuttingDown(context, true);
+ }
+
private boolean isModuleEnabled() {
return VoicemailComponent.get(this).getVoicemailClient().isVoicemailModuleEnabled();
}
@@ -150,8 +178,20 @@
return true;
}
- private boolean isUserUnlocked() {
- UserManager userManager = getSystemService(UserManager.class);
+ private static boolean isUserUnlocked(@NonNull Context context) {
+ UserManager userManager = context.getSystemService(UserManager.class);
return userManager.isUserUnlocked();
}
+
+ private static void setShuttingDown(Context context, boolean value) {
+ PreferenceManager.getDefaultSharedPreferences(context)
+ .edit()
+ .putBoolean(IS_SHUTTING_DOWN, value)
+ .apply();
+ }
+
+ private static boolean isShuttingDown(Context context) {
+ return PreferenceManager.getDefaultSharedPreferences(context)
+ .getBoolean(IS_SHUTTING_DOWN, false);
+ }
}
diff --git a/java/com/android/voicemail/impl/VoicemailBootReceiver.java b/java/com/android/voicemail/impl/VoicemailBootReceiver.java
deleted file mode 100644
index 0a3e61a..0000000
--- a/java/com/android/voicemail/impl/VoicemailBootReceiver.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Copyright (C) 2017 The Android Open Source Project
- *
- * <p>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
- *
- * <p>http://www.apache.org/licenses/LICENSE-2.0
- *
- * <p>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.voicemail.impl;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import com.android.voicemail.VoicemailComponent;
-
-/** Receives {@link Intent#ACTION_BOOT_COMPLETED} for the voicemail module. */
-public class VoicemailBootReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!VoicemailComponent.get(context).getVoicemailClient().isVoicemailModuleEnabled()) {
- return;
- }
- StatusCheckJobService.schedule(context);
- }
-}
diff --git a/java/com/android/voicemail/impl/VoicemailClientImpl.java b/java/com/android/voicemail/impl/VoicemailClientImpl.java
index 96cd534..1b98903 100644
--- a/java/com/android/voicemail/impl/VoicemailClientImpl.java
+++ b/java/com/android/voicemail/impl/VoicemailClientImpl.java
@@ -20,6 +20,7 @@
import android.os.PersistableBundle;
import android.provider.VoicemailContract.Status;
import android.provider.VoicemailContract.Voicemails;
+import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.os.BuildCompat;
@@ -141,6 +142,19 @@
return new OmtpVvmCarrierConfigHelper(context, phoneAccountHandle).getConfig();
}
+ @Override
+ @MainThread
+ public void onBoot(@NonNull Context context) {
+ OmtpService.onBoot(context);
+ StatusCheckJobService.schedule(context);
+ }
+
+ @Override
+ @MainThread
+ public void onShutdown(@NonNull Context context) {
+ OmtpService.onShutdown(context);
+ }
+
@TargetApi(VERSION_CODES.O)
@Override
public void appendOmtpVoicemailSelectionClause(
diff --git a/java/com/android/voicemail/stub/StubVoicemailClient.java b/java/com/android/voicemail/stub/StubVoicemailClient.java
index 9a89e30..e5d5145 100644
--- a/java/com/android/voicemail/stub/StubVoicemailClient.java
+++ b/java/com/android/voicemail/stub/StubVoicemailClient.java
@@ -93,4 +93,10 @@
@NonNull Context context, @Nullable PhoneAccountHandle phoneAccountHandle) {
return new PersistableBundle();
}
+
+ @Override
+ public void onBoot(@NonNull Context context) {}
+
+ @Override
+ public void onShutdown(@NonNull Context context) {}
}