diff options
author | twyen <twyen@google.com> | 2018-03-23 10:50:16 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-03-26 22:18:10 -0700 |
commit | b9b64d3935bb05169afb23375ebe38fb846e78c8 (patch) | |
tree | c426338572d2f500797ad751aacd9b834f561c00 /java | |
parent | 509a80d3ec56da2bc1c1cf1d438623f6ccad1654 (diff) |
Implement wifi emergency calling warning
The warning is shown when there is no service, and the carrier requires the message to be shown because they cannot make emergency call over wifi.
Bug: 68030294
Test: Unit tests, integration tests.
PiperOrigin-RevId: 190241868
Change-Id: Ia6b838ac1e8e62ad6b40d97c1cf1a970491c1e6f
Diffstat (limited to 'java')
4 files changed, 142 insertions, 28 deletions
diff --git a/java/com/android/dialer/dialpadview/DialpadFragment.java b/java/com/android/dialer/dialpadview/DialpadFragment.java index 833b91f59..6f8d677e8 100644 --- a/java/com/android/dialer/dialpadview/DialpadFragment.java +++ b/java/com/android/dialer/dialpadview/DialpadFragment.java @@ -16,6 +16,7 @@ package com.android.dialer.dialpadview; +import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; @@ -34,6 +35,8 @@ import android.graphics.BitmapFactory; import android.media.AudioManager; import android.media.ToneGenerator; import android.net.Uri; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Trace; import android.provider.Contacts.People; @@ -48,6 +51,7 @@ import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telephony.PhoneNumberFormattingTextWatcher; import android.telephony.PhoneNumberUtils; +import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.text.Editable; import android.text.Selection; @@ -75,6 +79,7 @@ import android.widget.TextView; import com.android.contacts.common.dialog.CallSubjectDialog; import com.android.contacts.common.util.StopWatch; import com.android.dialer.animation.AnimUtils; +import com.android.dialer.animation.AnimUtils.AnimationCallback; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.Assert; @@ -141,7 +146,18 @@ public class DialpadFragment extends Fragment private static final String PREF_DIGITS_FILLED_BY_INTENT = "pref_digits_filled_by_intent"; private static final String PREF_IS_DIALPAD_SLIDE_OUT = "pref_is_dialpad_slide_out"; + /** + * Hidden key in carrier config to determine if no emergency call over wifi warning is required. + * + * <p>"Time delay (in ms) after which we show the notification for emergency calls, while the + * device is registered over WFC. Default value is -1, which indicates that this notification is + * not pertinent for a particular carrier. We've added a delay to prevent false positives." + */ + @VisibleForTesting + static final String KEY_EMERGENCY_NOTIFICATION_DELAY_INT = "emergency_notification_delay_int"; + private static Optional<String> currentCountryIsoForTesting = Optional.absent(); + private static Boolean showEmergencyCallWarningForTest = null; private final Object toneGeneratorLock = new Object(); /** Set of dialpad keys that are currently being pressed */ @@ -303,6 +319,7 @@ public class DialpadFragment extends Fragment activity.invalidateOptionsMenu(); updateMenuOverflowButton(wasEmptyBeforeTextChange); } + updateDialpadHint(); } // DTMF Tones do not need to be played here any longer - @@ -439,6 +456,73 @@ public class DialpadFragment extends Fragment return fragmentView; } + /** + * The dialpad hint is a TextView overlaid above the digit EditText. {@link EditText#setHint(int)} + * is not used because the digits has auto resize and makes setting the size of the hint + * difficult. + */ + private void updateDialpadHint() { + TextView hint = dialpadView.getDigitsHint(); + if (!TextUtils.isEmpty(digits.getText())) { + hint.setVisibility(View.GONE); + return; + } + + if (shouldShowEmergencyCallWarning(getContext())) { + hint.setText(getContext().getString(R.string.dialpad_hint_emergency_calling_not_available)); + hint.setVisibility(View.VISIBLE); + return; + } + hint.setVisibility(View.GONE); + } + + /** + * Only show the "emergency call not available" warning when on wifi call and carrier requires it. + * + * <p>internal method tested because the conditions cannot be setup in espresso, and the layout + * cannot be inflated in robolectric. + */ + @SuppressWarnings("missingPermission") + @TargetApi(VERSION_CODES.O) + @VisibleForTesting + static boolean shouldShowEmergencyCallWarning(Context context) { + if (showEmergencyCallWarningForTest != null) { + return showEmergencyCallWarningForTest; + } + if (VERSION.SDK_INT < VERSION_CODES.O) { + return false; + } + if (!PermissionsUtil.hasReadPhoneStatePermissions(context)) { + return false; + } + TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class); + // A delay of -1 means wifi emergency call is available/the warning is not required. + if (telephonyManager.getCarrierConfig().getInt(KEY_EMERGENCY_NOTIFICATION_DELAY_INT, -1) + == -1) { + return false; + } + + // TelephonyManager.getVoiceNetworkType() Doesn't always return NETWORK_TYPE_IWLAN when on wifi. + // other wifi calling checks are hidden API. Emergency calling is not available without service + // regardless of the wifi state so this check is omitted. + + switch (telephonyManager.getServiceState().getState()) { + case ServiceState.STATE_OUT_OF_SERVICE: + case ServiceState.STATE_POWER_OFF: + return true; + case ServiceState.STATE_EMERGENCY_ONLY: + case ServiceState.STATE_IN_SERVICE: + return false; + default: + throw new AssertionError("unknown state " + telephonyManager.getServiceState().getState()); + } + } + + @VisibleForTesting + static void setShowEmergencyCallWarningForTest(Boolean value) { + showEmergencyCallWarningForTest = value; + } + @Override public void onAttach(Context context) { super.onAttach(context); @@ -732,6 +816,8 @@ public class DialpadFragment extends Fragment overflowMenuButton.setOnClickListener(this); overflowMenuButton.setVisibility(isDigitsEmpty() ? View.INVISIBLE : View.VISIBLE); + updateDialpadHint(); + if (firstLaunch) { // The onHiddenChanged callback does not get called the first time the fragment is // attached, so call it ourselves here. @@ -1392,7 +1478,16 @@ public class DialpadFragment extends Fragment if (transitionIn) { AnimUtils.fadeIn(overflowMenuButton, AnimUtils.DEFAULT_DURATION); } else { - AnimUtils.fadeOut(overflowMenuButton, AnimUtils.DEFAULT_DURATION); + AnimUtils.fadeOut( + overflowMenuButton, + AnimUtils.DEFAULT_DURATION, + new AnimationCallback() { + @Override + public void onAnimationEnd() { + // AnimUtils will set the visibility to GONE and cause the layout to move around. + overflowMenuButton.setVisibility(View.INVISIBLE); + } + }); } } diff --git a/java/com/android/dialer/dialpadview/DialpadView.java b/java/com/android/dialer/dialpadview/DialpadView.java index 58ba233bd..1bd8bad4f 100644 --- a/java/com/android/dialer/dialpadview/DialpadView.java +++ b/java/com/android/dialer/dialpadview/DialpadView.java @@ -82,6 +82,7 @@ public class DialpadView extends LinearLayout { private final int translateDistance; private EditText digits; + private TextView digitsHint; private ImageButton delete; private View overflowMenuButton; private ViewGroup rateContainer; @@ -134,6 +135,7 @@ public class DialpadView extends LinearLayout { setupKeypad(); digits = (EditText) findViewById(R.id.digits); + digitsHint = findViewById(R.id.digits_hint); delete = (ImageButton) findViewById(R.id.deleteButton); overflowMenuButton = findViewById(R.id.dialpad_overflow); rateContainer = (ViewGroup) findViewById(R.id.rate_container); @@ -311,6 +313,10 @@ public class DialpadView extends LinearLayout { return digits; } + public TextView getDigitsHint() { + return digitsHint; + } + public ImageButton getDeleteButton() { return delete; } diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml index 13c11f1ce..69d23a9b6 100644 --- a/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml @@ -13,9 +13,8 @@ See the License for the specific language governing permissions and limitations under the License. --> -<view xmlns:android="http://schemas.android.com/apk/res/android" +<com.android.dialer.dialpadview.DialpadView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/dialpad_view" - class="com.android.dialer.dialpadview.DialpadView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="bottom" @@ -100,29 +99,39 @@ android:tint="?attr/dialpad_icon_tint" android:tintMode="src_in" android:visibility="gone"/> - - <view xmlns:ex="http://schemas.android.com/apk/res-auto" - android:id="@+id/digits" - class="com.android.dialer.dialpadview.DigitsEditText" - android:textStyle="normal" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="@android:color/transparent" - android:cursorVisible="false" - android:focusableInTouchMode="true" - android:fontFamily="sans-serif" - android:freezesText="true" - android:gravity="center" - android:importantForAutofill="no" - android:maxLines="1" - android:scrollHorizontally="true" - android:singleLine="true" - android:textColor="?attr/dialpad_text_color" - android:textCursorDrawable="@null" - android:textSize="?attr/dialpad_digits_adjustable_text_size" - ex:resizing_text_min_size="@dimen/dialpad_digits_text_min_size"/> - + <FrameLayout android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1"> + <TextView android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/digits_hint" + android:focusable="false" + android:gravity="center" + android:textSize="14sp" + android:textColor="@color/secondary_text_color" + android:visibility="gone" + /> + <com.android.dialer.dialpadview.DigitsEditText + xmlns:ex="http://schemas.android.com/apk/res-auto" + android:id="@+id/digits" + android:textStyle="normal" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/transparent" + android:cursorVisible="false" + android:focusableInTouchMode="true" + android:fontFamily="sans-serif" + android:freezesText="true" + android:gravity="center" + android:importantForAutofill="no" + android:maxLines="1" + android:scrollHorizontally="true" + android:singleLine="true" + android:textColor="?attr/dialpad_text_color" + android:textCursorDrawable="@null" + android:textSize="?attr/dialpad_digits_adjustable_text_size" + ex:resizing_text_min_size="@dimen/dialpad_digits_text_min_size"/> + </FrameLayout> <ImageButton android:id="@+id/deleteButton" android:layout_width="wrap_content" @@ -152,4 +161,4 @@ android:layout_width="match_parent" android:layout_height="@dimen/dialpad_space_below_keys"/> -</view> +</com.android.dialer.dialpadview.DialpadView> diff --git a/java/com/android/dialer/dialpadview/res/values/strings.xml b/java/com/android/dialer/dialpadview/res/values/strings.xml index 51367b644..5d8d8e6a5 100644 --- a/java/com/android/dialer/dialpadview/res/values/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values/strings.xml @@ -97,7 +97,11 @@ Ignored if empty. --> <string name="config_prohibited_phone_number_regexp" translatable="false"></string> + <!-- Warning hint shown in the dialpad input field when emergency call (911, etc.) cannot be made. + [CHAR_LIMIT=60] --> + <string name="dialpad_hint_emergency_calling_not_available">Emergency calling not available</string> + <!-- Dialog message which is shown when the user tries to make a phone call to prohibited phone numbers [CHAR LIMIT=NONE] --> - <string msgid="4313552620858880999" name="dialog_phone_call_prohibited_message">Can\'t call this number</string> + <string name="dialog_phone_call_prohibited_message" msgid="4313552620858880999">Can\'t call this number</string> </resources> |