summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/dialpadview
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/dialpadview')
-rw-r--r--java/com/android/dialer/dialpadview/DialpadFragment.java97
-rw-r--r--java/com/android/dialer/dialpadview/DialpadView.java6
-rw-r--r--java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml61
-rw-r--r--java/com/android/dialer/dialpadview/res/values/strings.xml6
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>