Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d21b8fde authored by Ta-wei Yen's avatar Ta-wei Yen Committed by Android (Google) Code Review
Browse files

Merge "Use separate AnswerFragment for Talkback" into ub-contactsdialer-a-dev

parents dd5274dc 37adc985
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
     limitations under the License.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/fab_blue" />
    <item android:drawable="@drawable/fab_green"/>
    <item>
        <bitmap
            android:gravity="center"
+104 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2013 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~      http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:background="@color/glowpad_background_color">
    <RelativeLayout
        android:id="@+id/accessible_answer_fragment_answer"
        android:orientation="vertical"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:clickable="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp">
        <ImageView
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:src="@drawable/ic_lockscreen_answer_activated_layer"
            android:layout_centerInParent="true">
        </ImageView>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/description_target_answer"
            android:textSize="12sp"
            android:textColor="@color/accessible_answer_hint_text_color"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="8dp"/>
    </RelativeLayout>
    <RelativeLayout
        android:id="@+id/accessible_answer_fragment_decline"
        android:orientation="vertical"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:clickable="true"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp">
        <ImageView
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:src="@drawable/ic_lockscreen_decline_activated_layer"
            android:layout_centerInParent="true">
        </ImageView>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/description_target_decline"
            android:textSize="12sp"
            android:textColor="@color/accessible_answer_hint_text_color"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="8dp"/>
    </RelativeLayout>
    <LinearLayout
        android:id="@+id/accessible_answer_fragment_text"
        android:orientation="vertical"
        android:layout_width="92dp"
        android:layout_height="92dp"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:clickable="true"
        android:layout_alignParentEnd="false"
        android:layout_alignParentStart="false"
        android:layout_above="@+id/accessible_answer_fragment_decline"
        android:layout_alignWithParentIfMissing="false"
        android:layout_alignParentTop="false"
        android:layout_alignParentLeft="false"
        android:layout_alignParentBottom="false"
        android:layout_alignParentRight="false"
        android:layout_centerHorizontal="true"
        android:contentDescription="@string/description_target_send_sms"
        android:gravity="center">
        <ImageView
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:src="@drawable/ic_lockscreen_text">
        </ImageView>
    </LinearLayout>

</RelativeLayout>
 No newline at end of file
+4 −1
Original line number Diff line number Diff line
@@ -73,11 +73,14 @@
    <color name="glowpad_text_widget_ring_color">#ffffff</color>
    <color name="glowpad_widget_active_color">#ffffff</color>
    <color name="glowpad_text_widget_normal_tint">#cccccc</color>
    <color name="glowpad_call_widget_normal_tint">@color/dialtacts_theme_color</color>
    <color name="glowpad_call_widget_normal_tint">#00c853</color>
    <color name="glowpad_end_call_widget_normal_tint">#ff1744</color>
    <color name="glowpad_incoming_widget_tint">#a3a3a3</color>
    <color name="glowpad_incoming_widget_background_tint">#ffffff</color>

    <!-- 70% opacity, white. -->
    <color name="accessible_answer_hint_text_color">#B2FFFFFF</color>

    <!-- 20% opacity, theme color. -->
    <color name="incall_dialpad_touch_tint">#330288d1</color>

+157 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.incallui;

import android.os.Bundle;
import android.telecom.VideoProfile;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import com.android.dialer.R;

/**
 * AnswerFragment to use when touch exploration is enabled in accessibility.
 */
public class AccessibleAnswerFragment extends AnswerFragment {

    private static final String TAG = AccessibleAnswerFragment.class.getSimpleName();
    private static final int SWIPE_THRESHOLD = 100;

    private View mAnswer;
    private View mDecline;
    private View mText;

    private TouchListener mTouchListener;
    private GestureDetector mGestureDetector;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        ViewGroup group = (ViewGroup) inflater.inflate(R.layout.accessible_answer_fragment,
                container, false);

        mTouchListener = new TouchListener();
        mGestureDetector = new GestureDetector(getContext(), new SimpleOnGestureListener() {
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                    float velocityY) {
                return AccessibleAnswerFragment.this.onFling(e1, e2, velocityX, velocityX);
            }
        });

        mAnswer = group.findViewById(R.id.accessible_answer_fragment_answer);
        mAnswer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "Answer Button Clicked");
                onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext());
            }
        });
        mDecline = group.findViewById(R.id.accessible_answer_fragment_decline);
        mDecline.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "Decline Button Clicked");
                onDecline(getContext());
            }
        });

        mText = group.findViewById(R.id.accessible_answer_fragment_text);
        mText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "Text Button Clicked");
                onText();
            }
        });
        return group;
    }

    @Override
    public void onResume() {
        super.onResume();
        // Intercept all touch events for full screen swiping gesture.
        InCallActivity activity = (InCallActivity) getActivity();
        activity.setDispatchTouchEventListener(mTouchListener);
    }

    @Override
    public void onPause() {
        super.onPause();
        InCallActivity activity = (InCallActivity) getActivity();
        activity.setDispatchTouchEventListener(null);
    }

    private class TouchListener implements View.OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return mGestureDetector.onTouchEvent(event);
        }
    }

    private boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        if (hasPendingDialogs()) {
            return false;
        }

        float diffY = e2.getY() - e1.getY();
        float diffX = e2.getX() - e1.getX();
        if (Math.abs(diffX) > Math.abs(diffY)) {
            if (Math.abs(diffX) > SWIPE_THRESHOLD) {
                if (diffX > 0) {
                    onSwipeRight();
                } else {
                    onSwipeLeft();
                }
            }
            return true;
        } else if (Math.abs(diffY) > SWIPE_THRESHOLD) {
            if (diffY > 0) {
                onSwipeDown();
            } else {
                onSwipeUp();
            }
            return true;
        }

        return false;
    }

    private void onSwipeUp() {
        Log.d(TAG, "onSwipeUp");
        onText();
    }

    private void onSwipeDown() {
        Log.d(TAG, "onSwipeDown");
    }

    private void onSwipeLeft() {
        Log.d(TAG, "onSwipeLeft");
        onDecline(getContext());
    }

    private void onSwipeRight() {
        Log.d(TAG, "onSwipeRight");
        onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext());
    }
}
+49 −145
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.telecom.VideoProfile;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
@@ -34,17 +33,17 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.android.dialer.R;

import java.util.ArrayList;
import java.util.List;


/**
 *
 * Provides only common interface and functions. Should be derived to implement the actual UI.
 */
public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresenter.AnswerUi>
        implements GlowPadWrapper.AnswerListener, AnswerPresenter.AnswerUi {
public abstract class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresenter.AnswerUi>
        implements AnswerPresenter.AnswerUi {

    public static final int TARGET_SET_FOR_AUDIO_WITHOUT_SMS = 0;
    public static final int TARGET_SET_FOR_AUDIO_WITH_SMS = 1;
@@ -52,6 +51,13 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
    public static final int TARGET_SET_FOR_VIDEO_WITH_SMS = 3;
    public static final int TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST = 4;

    /**
     * This fragment implement no UI at all. Derived class should do it.
     */
    @Override
    public abstract View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState);

    /**
     * The popup showing the list of canned responses.
     *
@@ -70,11 +76,6 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente

    private final List<String> mSmsResponses = new ArrayList<>();

    private GlowPadWrapper mGlowpad;

    public AnswerFragment() {
    }

    @Override
    public AnswerPresenter createPresenter() {
        return InCallPresenter.getInstance().getAnswerPresenter();
@@ -85,113 +86,6 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
        return this;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mGlowpad = (GlowPadWrapper) inflater.inflate(R.layout.answer_fragment,
                container, false);

        Log.d(this, "Creating view for answer fragment ", this);
        Log.d(this, "Created from activity", getActivity());
        mGlowpad.setAnswerListener(this);

        return mGlowpad;
    }

    @Override
    public void onDestroyView() {
        Log.d(this, "onDestroyView");
        if (mGlowpad != null) {
            mGlowpad.stopPing();
            mGlowpad = null;
        }
        super.onDestroyView();
    }

    @Override
    public void onShowAnswerUi(boolean shown) {
        Log.d(this, "Show answer UI: " + shown);
        if (shown) {
            mGlowpad.startPing();
        } else {
            mGlowpad.stopPing();
        }
    }

    /**
     * Sets targets on the glowpad according to target set identified by the parameter.
     * @param targetSet Integer identifying the set of targets to use.
     */
    public void showTargets(int targetSet) {
        showTargets(targetSet, VideoProfile.STATE_BIDIRECTIONAL);
    }

    /**
     * Sets targets on the glowpad according to target set identified by the parameter.
     * @param targetSet Integer identifying the set of targets to use.
     */
    @Override
    public void showTargets(int targetSet, int videoState) {
        final int targetResourceId;
        final int targetDescriptionsResourceId;
        final int directionDescriptionsResourceId;
        final int handleDrawableResourceId;
        mGlowpad.setVideoState(videoState);

        switch (targetSet) {
            case TARGET_SET_FOR_AUDIO_WITH_SMS:
                targetResourceId = R.array.incoming_call_widget_audio_with_sms_targets;
                targetDescriptionsResourceId =
                        R.array.incoming_call_widget_audio_with_sms_target_descriptions;
                directionDescriptionsResourceId =
                        R.array.incoming_call_widget_audio_with_sms_direction_descriptions;
                handleDrawableResourceId = R.drawable.ic_incall_audio_handle;
                break;
            case TARGET_SET_FOR_VIDEO_WITHOUT_SMS:
                targetResourceId = R.array.incoming_call_widget_video_without_sms_targets;
                targetDescriptionsResourceId =
                        R.array.incoming_call_widget_video_without_sms_target_descriptions;
                directionDescriptionsResourceId =
                        R.array.incoming_call_widget_video_without_sms_direction_descriptions;
                handleDrawableResourceId = R.drawable.ic_incall_video_handle;
                break;
            case TARGET_SET_FOR_VIDEO_WITH_SMS:
                targetResourceId = R.array.incoming_call_widget_video_with_sms_targets;
                targetDescriptionsResourceId =
                        R.array.incoming_call_widget_video_with_sms_target_descriptions;
                directionDescriptionsResourceId =
                        R.array.incoming_call_widget_video_with_sms_direction_descriptions;
                handleDrawableResourceId = R.drawable.ic_incall_video_handle;
                break;
            case TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST:
                targetResourceId =
                    R.array.incoming_call_widget_video_request_targets;
                targetDescriptionsResourceId =
                        R.array.incoming_call_widget_video_request_target_descriptions;
                directionDescriptionsResourceId = R.array
                        .incoming_call_widget_video_request_target_direction_descriptions;
                handleDrawableResourceId = R.drawable.ic_incall_video_handle;
                break;
            case TARGET_SET_FOR_AUDIO_WITHOUT_SMS:
            default:
                targetResourceId = R.array.incoming_call_widget_audio_without_sms_targets;
                targetDescriptionsResourceId =
                        R.array.incoming_call_widget_audio_without_sms_target_descriptions;
                directionDescriptionsResourceId =
                        R.array.incoming_call_widget_audio_without_sms_direction_descriptions;
                handleDrawableResourceId = R.drawable.ic_incall_audio_handle;
                break;
        }

        if (targetResourceId != mGlowpad.getTargetResourceId()) {
            mGlowpad.setTargetResources(targetResourceId);
            mGlowpad.setTargetDescriptionsResourceId(targetDescriptionsResourceId);
            mGlowpad.setDirectionDescriptionsResourceId(directionDescriptionsResourceId);
            mGlowpad.setHandleDrawable(handleDrawableResourceId);
            mGlowpad.reset(false);
        }
    }

    @Override
    public void showMessageDialog() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
@@ -207,9 +101,7 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
                new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialogInterface) {
                        if (mGlowpad != null) {
                            mGlowpad.startPing();
                        }
                        onMessageDialogCancel();
                        dismissCannedResponsePopup();
                        getPresenter().onDismissDialog();
                    }
@@ -239,7 +131,7 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
     * This is safe to call even if the popup is already dismissed, and even if you never called
     * showRespondViaSmsPopup() in the first place.
     */
    private void dismissCannedResponsePopup() {
    protected void dismissCannedResponsePopup() {
        if (mCannedResponsePopup != null) {
            mCannedResponsePopup.dismiss();  // safe even if already dismissed
            mCannedResponsePopup = null;
@@ -282,8 +174,8 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                        // The order is arranged in a way that the popup will be destroyed when the
                        // InCallActivity is about to finish.
                                // The order is arranged in a way that the popup will be destroyed
                                // when the InCallActivity is about to finish.
                                final String textMessage = et.getText().toString().trim();
                                dismissCustomMessagePopup();
                                getPresenter().rejectCallWithMessage(textMessage);
@@ -352,23 +244,19 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
        return getActivity();
    }

    @Override
    public void onAnswer(int videoState, Context context) {
        Log.d(this, "onAnswer videoState=" + videoState + " context=" + context);
        getPresenter().onAnswer(videoState, context);
    }

    @Override
    public void onDecline(Context context) {
        getPresenter().onDecline(context);
    }

    @Override
    public void onDeclineUpgradeRequest(Context context) {
        InCallPresenter.getInstance().declineUpgradeRequest(context);
    }

    @Override
    public void onText() {
        getPresenter().onText();
    }
@@ -400,4 +288,20 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
            }
        }
    }

    public void onShowAnswerUi(boolean shown) {
        // Do Nothing
    }

    public void showTargets(int targetSet) {
        // Do Nothing
    }

    public void showTargets(int targetSet, int videoState) {
        // Do Nothing
    }

    protected void onMessageDialogCancel() {
        // Do nothing.
    }
}
Loading