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/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