Faster Emergency Dialer new UI design
- Change the layout parameter to match UI guideline.
- Emergency info button need double tap to launch Emergency information.
- Emergency info button vertical margin will changed when emergency
shortcut button more than 2.
Test: Manually
Bug: 111967652
Change-Id: Ibdd105e6da9f4c9b548b83420ba1b27ef88c82b9
diff --git a/src/com/android/phone/EccShortcutAdapter.java b/src/com/android/phone/EccShortcutAdapter.java
index deeb82f..e14b90a 100644
--- a/src/com/android/phone/EccShortcutAdapter.java
+++ b/src/com/android/phone/EccShortcutAdapter.java
@@ -186,15 +186,15 @@
switch (type) {
case POLICE:
description = mPoliceDescription;
- material.iconRes = R.drawable.ic_shield_white_24;
+ material.iconRes = R.drawable.ic_local_police_gm2_24px;
break;
case AMBULANCE:
description = mAmbulanceDescription;
- material.iconRes = R.drawable.ic_emergency_number_24;
+ material.iconRes = R.drawable.ic_local_hospital_gm2_24px;
break;
case FIRE:
description = mFireDescription;
- material.iconRes = R.drawable.ic_fire_white_24;
+ material.iconRes = R.drawable.ic_local_fire_department_gm2_24px;
break;
default:
// ignore unknown types
@@ -204,7 +204,7 @@
material.description = description;
} else {
// concatenate multiple types
- material.iconRes = R.drawable.ic_emergency_number_24;
+ material.iconRes = R.drawable.ic_local_hospital_gm2_24px;
material.description = context.getString(R.string.description_concat_format,
material.description, description);
}
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index 66701d5..1fbbd33 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -108,17 +108,12 @@
* moved into a shared base class that would live in the framework?
* Or could we figure out some way to move *this* class into apps/Contacts
* also?
- *
- * TODO: Implement emergency dialer shortcut.
- * Emergency dialer shortcut offer a local emergency number list. Directly clicking a call button
- * to place an emergency phone call without entering numbers from dialpad.
- * TODO item:
- * 1.integrate emergency phone number table.
*/
public class EmergencyDialer extends Activity implements View.OnClickListener,
View.OnLongClickListener, View.OnKeyListener, TextWatcher,
DialpadKeyButton.OnPressedListener, ColorExtractor.OnColorsChangedListener,
- EmergencyShortcutButton.OnConfirmClickListener, SensorEventListener {
+ EmergencyShortcutButton.OnConfirmClickListener, SensorEventListener,
+ EmergencyInfoGroup.OnConfirmClickListener {
private class MetricsWriter {
// Metrics constants indicating the entry type that user opened emergency dialer.
@@ -244,6 +239,8 @@
private EmergencyActionGroup mEmergencyActionGroup;
+ private EmergencyInfoGroup mEmergencyInfoGroup;
+
// close activity when screen turns off
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -451,6 +448,8 @@
mEmergencyActionGroup = (EmergencyActionGroup) findViewById(R.id.emergency_action_group);
+ mEmergencyInfoGroup = (EmergencyInfoGroup) findViewById(R.id.emergency_info_button);
+
if (mAreEmergencyDialerShortcutsEnabled) {
mEccInfoHelper = new EccInfoHelper(new IsoToEccProtobufRepository());
setupEmergencyShortcutsView();
@@ -606,6 +605,17 @@
}
@Override
+ public void onConfirmClick(EmergencyInfoGroup button) {
+ if (button == null) return;
+
+ mUserActions |= MetricsWriter.USER_ACTION_OPEN_EMERGENCY_INFO;
+ Intent intent = (Intent) button.getTag(R.id.tag_intent);
+ if (intent != null) {
+ startActivity(intent);
+ }
+ }
+
+ @Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.deleteButton: {
@@ -629,14 +639,6 @@
switchView(mDialpadView, mEmergencyShortcutView, true);
return;
}
- case R.id.emergency_info_button: {
- mUserActions |= MetricsWriter.USER_ACTION_OPEN_EMERGENCY_INFO;
- Intent intent = (Intent) view.getTag(R.id.tag_intent);
- if (intent != null) {
- startActivity(intent);
- }
- return;
- }
}
}
@@ -1099,8 +1101,7 @@
final View dialpadButton = findViewById(R.id.floating_action_button_dialpad);
dialpadButton.setOnClickListener(this);
- final View emergencyInfoButton = findViewById(R.id.emergency_info_button);
- emergencyInfoButton.setOnClickListener(this);
+ mEmergencyInfoGroup.setOnConfirmClickListener(this);
// EmergencyActionGroup is replaced by EmergencyInfoGroup.
mEmergencyActionGroup.setVisibility(View.GONE);
@@ -1179,10 +1180,15 @@
shortcutButtonContainer.addView(button);
}
- // update emergency numbers title for numerous buttons.
+ // Update emergency numbers title for numerous buttons.
if (mEmergencyShortcutButtonList.size() > 1) {
emergencyNumberTitle.setText(getString(
R.string.numerous_emergency_numbers_title));
+ // Update mEmergencyInfoGroup margin to avoid UI overlay when
+ // emergency shortcut button more than 2.
+ if (mEmergencyShortcutButtonList.size() > 2) {
+ mEmergencyInfoGroup.updateLayoutMargin();
+ }
} else {
emergencyNumberTitle.setText(getText(R.string.single_emergency_number_title));
}
@@ -1205,6 +1211,7 @@
*/
private void onPreTouchEvent(MotionEvent event) {
mEmergencyActionGroup.onPreTouchEvent(event);
+ mEmergencyInfoGroup.onPreTouchEvent(event);
if (mEmergencyShortcutButtonList != null) {
for (EmergencyShortcutButton button : mEmergencyShortcutButtonList) {
@@ -1218,6 +1225,7 @@
*/
private void onPostTouchEvent(MotionEvent event) {
mEmergencyActionGroup.onPostTouchEvent(event);
+ mEmergencyInfoGroup.onPostTouchEvent(event);
if (mEmergencyShortcutButtonList != null) {
for (EmergencyShortcutButton button : mEmergencyShortcutButtonList) {
diff --git a/src/com/android/phone/EmergencyInfoGroup.java b/src/com/android/phone/EmergencyInfoGroup.java
index d0dc322..5c01834 100644
--- a/src/com/android/phone/EmergencyInfoGroup.java
+++ b/src/com/android/phone/EmergencyInfoGroup.java
@@ -16,6 +16,8 @@
package com.android.phone;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
@@ -27,7 +29,10 @@
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.AttributeSet;
+import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewAnimationUtils;
+import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -44,23 +49,60 @@
* EmergencyInfoGroup display user icon and user name. And it is an entry point to
* Emergency Information.
*/
-public class EmergencyInfoGroup extends FrameLayout {
- private ImageView mEmergencyInfoImage;
+public class EmergencyInfoGroup extends FrameLayout implements View.OnClickListener {
+ // Time to hide view of confirmation.
+ private static final long HIDE_DELAY_MS = 3000;
+ private static final int[] ICON_VIEWS =
+ {R.id.emergency_info_image, R.id.confirmed_emergency_info_image};
+
private TextView mEmergencyInfoName;
- private TextView mEmergencyInfoHint;
private View mEmergencyInfoButton;
+ private View mEmergencyInfoConfirmButton;
+
+ private MotionEvent mPendingTouchEvent;
+ private OnConfirmClickListener mOnConfirmClickListener;
+
+ private boolean mConfirmViewHiding;
public EmergencyInfoGroup(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
+ /**
+ * Interface definition for a callback to be invoked when the view of confirmation on emergency
+ * info button is clicked.
+ */
+ public interface OnConfirmClickListener {
+ /**
+ * Called when the view of confirmation on emergency info button has been clicked.
+ *
+ * @param button The shortcut button that was clicked.
+ */
+ void onConfirmClick(EmergencyInfoGroup button);
+ }
+
+ /**
+ * Register a callback {@link OnConfirmClickListener} to be invoked when view of confirmation
+ * is clicked.
+ *
+ * @param onConfirmClickListener The callback that will run.
+ */
+ public void setOnConfirmClickListener(OnConfirmClickListener onConfirmClickListener) {
+ mOnConfirmClickListener = onConfirmClickListener;
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mEmergencyInfoButton = findViewById(R.id.emergency_info_button);
- mEmergencyInfoImage = (ImageView) findViewById(R.id.emergency_info_image);
+ mEmergencyInfoButton = findViewById(R.id.emergency_info_view);
mEmergencyInfoName = (TextView) findViewById(R.id.emergency_info_name);
- mEmergencyInfoHint = (TextView) findViewById(R.id.emergency_info_hint);
+
+ mEmergencyInfoConfirmButton = findViewById(R.id.emergency_info_confirm_view);
+
+ mEmergencyInfoButton.setOnClickListener(this);
+ mEmergencyInfoConfirmButton.setOnClickListener(this);
+
+ mConfirmViewHiding = true;
}
@Override
@@ -71,12 +113,6 @@
}
}
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- updateLayoutHeight();
- }
-
private void setupButtonInfo() {
List<ResolveInfo> infos;
@@ -92,8 +128,8 @@
final String packageName = infos.get(0).activityInfo.packageName;
final Intent intent = new Intent(TelephonyManager.ACTION_EMERGENCY_ASSISTANCE)
.setPackage(packageName);
- mEmergencyInfoButton.setTag(R.id.tag_intent, intent);
- mEmergencyInfoImage.setImageDrawable(getCircularUserIcon());
+ setTag(R.id.tag_intent, intent);
+ setUserIcon();
visible = true;
}
@@ -102,6 +138,13 @@
setVisibility(visible ? View.VISIBLE : View.GONE);
}
+ private void setUserIcon() {
+ for (int iconView : ICON_VIEWS) {
+ ImageView userIcon = findViewById(iconView);
+ userIcon.setImageDrawable(getCircularUserIcon());
+ }
+ }
+
/**
* Get user icon.
*
@@ -134,15 +177,124 @@
R.string.emergency_information_owner_hint) : userName;
}
- private void updateLayoutHeight() {
+ /**
+ * Called by the activity before a touch event is dispatched to the view hierarchy.
+ */
+ public void onPreTouchEvent(MotionEvent event) {
+ mPendingTouchEvent = event;
+ }
+
+ /**
+ * Called by the activity after a touch event is dispatched to the view hierarchy.
+ */
+ public void onPostTouchEvent(MotionEvent event) {
+ // Hide the confirmation button if a touch event was delivered to the activity but not to
+ // this view.
+ if (mPendingTouchEvent != null) {
+ hideSelectedButton();
+ }
+ mPendingTouchEvent = null;
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ boolean handled = super.dispatchTouchEvent(event);
+ if (mPendingTouchEvent == event && handled) {
+ mPendingTouchEvent = null;
+ }
+ return handled;
+ }
+
+ @Override
+ public void onClick(View view) {
+ switch (view.getId()) {
+ case R.id.emergency_info_view:
+ if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
+ if (mOnConfirmClickListener != null) {
+ mOnConfirmClickListener.onConfirmClick(this);
+ }
+ } else {
+ revealSelectedButton();
+ }
+ break;
+ case R.id.emergency_info_confirm_view:
+ if (mOnConfirmClickListener != null) {
+ mOnConfirmClickListener.onConfirmClick(this);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void revealSelectedButton() {
+ mConfirmViewHiding = false;
+
+ mEmergencyInfoConfirmButton.setVisibility(View.VISIBLE);
+ int centerX = mEmergencyInfoButton.getLeft() + mEmergencyInfoButton.getWidth() / 2;
+ int centerY = mEmergencyInfoButton.getTop() + mEmergencyInfoButton.getHeight() / 2;
+ Animator reveal = ViewAnimationUtils.createCircularReveal(
+ mEmergencyInfoConfirmButton,
+ centerX,
+ centerY,
+ 0,
+ Math.max(centerX, mEmergencyInfoConfirmButton.getWidth() - centerX)
+ + Math.max(centerY, mEmergencyInfoConfirmButton.getHeight() - centerY));
+ reveal.start();
+
+ postDelayed(mCancelSelectedButtonRunnable, HIDE_DELAY_MS);
+ mEmergencyInfoConfirmButton.requestFocus();
+ }
+
+ private void hideSelectedButton() {
+ if (mConfirmViewHiding || mEmergencyInfoConfirmButton.getVisibility() != VISIBLE) {
+ return;
+ }
+
+ mConfirmViewHiding = true;
+
+ removeCallbacks(mCancelSelectedButtonRunnable);
+ int centerX =
+ mEmergencyInfoConfirmButton.getLeft() + mEmergencyInfoConfirmButton.getWidth() / 2;
+ int centerY =
+ mEmergencyInfoConfirmButton.getTop() + mEmergencyInfoConfirmButton.getHeight() / 2;
+ Animator reveal = ViewAnimationUtils.createCircularReveal(
+ mEmergencyInfoConfirmButton,
+ centerX,
+ centerY,
+ Math.max(centerX, mEmergencyInfoButton.getWidth() - centerX)
+ + Math.max(centerY, mEmergencyInfoButton.getHeight() - centerY),
+ 0);
+ reveal.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mEmergencyInfoConfirmButton.setVisibility(INVISIBLE);
+ }
+ });
+ reveal.start();
+
+ mEmergencyInfoButton.requestFocus();
+ }
+
+ private final Runnable mCancelSelectedButtonRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (!isAttachedToWindow()) return;
+ hideSelectedButton();
+ }
+ };
+
+ /**
+ * Update layout margin when emergency shortcut button more than 2.
+ */
+ public void updateLayoutMargin() {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();
- // Update height if mEmergencyInfoHint text line more than 1.
- // EmergencyInfoGroup max line is 2, eclipse type "end" will be adopt if string too long.
- params.height =
- mEmergencyInfoHint.getLineCount() > 1 ? getResources().getDimensionPixelSize(
- R.dimen.emergency_info_button_multiline_height)
- : getResources().getDimensionPixelSize(
- R.dimen.emergency_info_button_singleline_height);
+
+ params.topMargin = getResources().getDimensionPixelSize(
+ R.dimen.emergency_info_button_fix_margin_vertical);
+ params.bottomMargin = getResources().getDimensionPixelSize(
+ R.dimen.emergency_info_button_fix_margin_vertical);
+
setLayoutParams(params);
}
}
\ No newline at end of file