VoWifi Emergency Call Notification
- Display a dialog when user clicks notification
- If user clicks Ok + Do not show again, remove notification and
dialog
- If user clicks Ok, remove dialog
- If user clicks Cancel, disable WFC setting
Bug: 179122732
Test: Manually verified by simulating
Change-Id: I9e2a7ea4e80e669584cacfdb176a53fd15bfa446
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8828c3a..99e1b43 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -104,6 +104,7 @@
<protected-broadcast android:name= "com.android.phone.settings.CARRIER_PROVISIONING" />
<protected-broadcast android:name= "com.android.phone.settings.TRIGGER_CARRIER_PROVISIONING" />
+ <protected-broadcast android:name= "com.android.internal.telephony.ACTION_VOWIFI_ENABLED" />
<!-- For Vendor Debugging in Telephony -->
<protected-broadcast android:name="android.telephony.action.ANOMALY_REPORTED" />
@@ -575,6 +576,17 @@
</intent-filter>
</activity>
+ <activity android:name="LimitedServiceActivity"
+ android:exported="true"
+ android:excludeFromRecents="true"
+ android:launchMode="singleTask"
+ android:taskAffinity=""
+ android:theme="@android:style/Theme.Translucent.NoTitleBar">
+ <intent-filter android:priority="1000">
+ <action android:name = "com.android.internal.telephony.ACTION_VOWIFI_ENABLED" />
+ </intent-filter>
+ </activity>
+
<activity android:name="MMIDialogActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:excludeFromRecents="true"
diff --git a/res/layout/frag_limited_service_alert_dialog.xml b/res/layout/frag_limited_service_alert_dialog.xml
new file mode 100644
index 0000000..ad9d378
--- /dev/null
+++ b/res/layout/frag_limited_service_alert_dialog.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+/*
+ * Copyright (C) 2022 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.
+ */
+-->
+
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scrollbars="none">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/limited_service_top_padding"
+ android:paddingStart="@dimen/limited_service_margin_start_end"
+ android:paddingEnd="@dimen/limited_service_margin_start_end"
+ android:paddingBottom="@dimen/limited_service_bottom_padding"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/limited_service_text_bottom_padding"
+ android:text="@string/limited_service_alert_dialog_description"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="16sp"/>
+
+ <CheckBox
+ android:id="@+id/do_not_show"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:buttonTint="?android:attr/textColorPrimary"
+ android:focusable="true"
+ android:clickable="true"
+ android:text="@string/do_not_show_again"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="14sp"/>
+ </LinearLayout>
+</ScrollView>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index e1742d8..3eb1a12 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -225,4 +225,10 @@
<dimen name="dialpad_button_height">43dp</dimen>
<dimen name="dialpad_button_width">43dp</dimen>
<!-- End of Shortcut view vertical dimens. -->
+
+ <!-- values for limited service -->
+ <dimen name="limited_service_top_padding">24dp</dimen>
+ <dimen name="limited_service_bottom_padding">4dp</dimen>
+ <dimen name="limited_service_margin_start_end">24dp</dimen>
+ <dimen name="limited_service_text_bottom_padding">10dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1684e89..d744834 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2196,4 +2196,16 @@
<!-- Telephony notification channel name for a channel containing SIP accounts removed
notificatios -->
<string name="notification_channel_sip_account">Deprecated SIP accounts</string>
+
+ <!-- Instruction text to notify user that emergency calls may not be possible when voice is
+ enabled over wifi. [CHAR LIMIT=NONE] -->
+ <string name="limited_service_alert_dialog_description"><xliff:g id="spn" example="Operator">%s</xliff:g> doesn\'t support emergency calls over Wi-Fi.
+\n\nEmergency calls will be placed through a mobile network. If there\'s limited mobile coverage,
+ your emergency call may not go through.
+</string>
+ <!-- Option to hide the popup dialog if it is not necessary for the user. [CHAR LIMIT=40] -->
+ <string name="do_not_show_again">Don\'t show again</string>
+ <!-- Option to turn off wifi calling -->
+ <string name="turn_off_wfc">Turn off Wi-Fi calling</string>
+ <string name="unavailable_emergency_calls_notification_name">Emergency calls may be unavailable</string>
</resources>
diff --git a/src/com/android/phone/LimitedServiceActivity.java b/src/com/android/phone/LimitedServiceActivity.java
new file mode 100644
index 0000000..fd6c176
--- /dev/null
+++ b/src/com/android/phone/LimitedServiceActivity.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2022 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.phone;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
+import android.telephony.ims.ImsMmTelManager;
+import android.telephony.TelephonyManager;
+import android.telephony.SubscriptionManager;
+import android.util.Log;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.TextView;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.FragmentActivity;
+import com.android.internal.telephony.CarrierServiceStateTracker;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
+
+public class LimitedServiceActivity extends FragmentActivity {
+
+ private static final String LOG_TAG = "LimitedServiceActivity";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.d(LOG_TAG, "Started LimitedServiceActivity");
+ int phoneId = getIntent().getExtras().getInt(PhoneConstants.PHONE_KEY);
+ LimitedServiceAlertDialogFragment newFragment = LimitedServiceAlertDialogFragment.
+ newInstance(phoneId);
+ newFragment.show(getSupportFragmentManager(), null);
+ }
+
+ public static class LimitedServiceAlertDialogFragment extends DialogFragment {
+ private static final String TAG = "LimitedServiceAlertDialog";
+ private static final int EVENT_IMS_CAPABILITIES_CHANGED = 1;
+ private static final String KEY_PHONE_ID = "key_phone_id";
+ private Phone mPhone;
+ private int mPhoneId;
+ private TelephonyManager mTelephonyManager;
+ private Handler mHandler;
+
+ public static LimitedServiceAlertDialogFragment newInstance(int phoneId) {
+ LimitedServiceAlertDialogFragment frag = new LimitedServiceAlertDialogFragment();
+ Log.i(TAG, "LimitedServiceAlertDialog for phoneId:" + phoneId);
+ Bundle args = new Bundle();
+ args.putInt(KEY_PHONE_ID, phoneId);
+ frag.setArguments(args);
+ return frag;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle bundle) {
+ mPhoneId = getArguments().getInt(KEY_PHONE_ID);
+ mPhone = PhoneFactory.getPhone(mPhoneId);
+ mTelephonyManager = getContext().getSystemService(TelephonyManager.class).
+ createForSubscriptionId(mPhone.getSubId());
+ mHandler = new MsgHandler();
+ mPhone.getServiceStateTracker().registerForImsCapabilityChanged(mHandler,
+ EVENT_IMS_CAPABILITIES_CHANGED, null);
+ if (!SubscriptionManager.isValidPhoneId(mPhoneId)) return null;
+ super.onCreateDialog(bundle);
+ View dialogView = View.inflate(getActivity(),
+ R.layout.frag_limited_service_alert_dialog, null);
+ TextView textView = (TextView) dialogView.findViewById(R.id.message);
+ Resources res = getResources();
+ String description = String.format(res.getString(
+ R.string.limited_service_alert_dialog_description),
+ mPhone.getServiceStateTracker().getServiceProviderNameOrPlmn().trim());
+ textView.setText(description);
+ CheckBox alertCheckBox = dialogView.findViewById(R.id.do_not_show);
+ SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(
+ mPhone.getContext());
+ Log.i(TAG, "onCreateDialog " + Phone.KEY_DO_NOT_SHOW_LIMITED_SERVICE_ALERT +
+ mPhone.getSubId() + ":" + pref.getBoolean
+ (Phone.KEY_DO_NOT_SHOW_LIMITED_SERVICE_ALERT + mPhone.getSubId(), false));
+
+ AlertDialog alertDialog =
+ new AlertDialog.Builder(getActivity(),
+ android.R.style.Theme_DeviceDefault_Dialog_Alert)
+ .setTitle(R.string.unavailable_emergency_calls_notification_name)
+ .setView(dialogView)
+ .setNegativeButton(
+ R.string.turn_off_wfc,
+ (dialog, which) -> onNegativeButtonClicked())
+ .setPositiveButton(
+ android.R.string.ok,
+ (dialog, which) -> onPositiveButtonClicked(pref,
+ alertCheckBox.isChecked()))
+ .create();
+ this.setCancelable(false);
+ return alertDialog;
+ }
+
+ private void onNegativeButtonClicked() {
+ Log.d(TAG, "onNegativeButtonClicked");
+ SubscriptionManager subscriptionManager = (SubscriptionManager) getContext().
+ getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ int[] subIds = subscriptionManager.getSubscriptionIds(mPhoneId);
+ if (subIds != null && subIds.length > 0 && SubscriptionManager.
+ isValidSubscriptionId(subIds[0])) {
+ ImsMmTelManager imsMmTelMgr = ImsMmTelManager.
+ createForSubscriptionId(subIds[0]);
+ Log.i(TAG, "Disabling WFC setting");
+ imsMmTelMgr.setVoWiFiSettingEnabled(false);
+ }
+ cleanUp();
+ }
+
+ private void onPositiveButtonClicked(@NonNull SharedPreferences preferences,
+ boolean isChecked) {
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putBoolean(Phone.KEY_DO_NOT_SHOW_LIMITED_SERVICE_ALERT + PhoneFactory.
+ getPhone(mPhoneId).getSubId(), isChecked);
+ editor.apply();
+ Log.i(TAG, "onPositiveButtonClicked isChecked:" + isChecked + " phoneId:" + mPhoneId
+ + " do not show preference:" + preferences.getBoolean
+ (Phone.KEY_DO_NOT_SHOW_LIMITED_SERVICE_ALERT + mPhone.getSubId(), false));
+ if (isChecked) {
+ NotificationManager sNotificationManager = (NotificationManager) getContext().
+ getSystemService(NOTIFICATION_SERVICE);
+ sNotificationManager.cancel(CarrierServiceStateTracker.EMERGENCY_NOTIFICATION_TAG,
+ mPhone.getSubId());
+ }
+ cleanUp();
+ }
+
+ private void cleanUp() {
+ mPhone.getServiceStateTracker().unregisterForImsCapabilityChanged(mHandler);
+ dismiss();
+ getActivity().finish();
+ }
+
+ private class MsgHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_IMS_CAPABILITIES_CHANGED:
+ if (!mTelephonyManager.isWifiCallingAvailable()) {
+ cleanUp();
+ }
+ break;
+ }
+ }
+ }
+ }
+}