diff options
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> |