1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.wallpaper.picker;
17 
18 import android.annotation.StringRes;
19 import android.content.Context;
20 import android.util.AttributeSet;
21 import android.view.GestureDetector;
22 import android.view.MotionEvent;
23 import android.view.View;
24 import android.widget.FrameLayout;
25 
26 import androidx.core.view.AccessibilityDelegateCompat;
27 import androidx.core.view.ViewCompat;
28 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
29 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
30 
31 /** A frame layout that listens to touch events and routes them to another view. */
32 public class TouchForwardingLayout extends FrameLayout {
33 
34     private View mView;
35     private boolean mForwardingEnabled;
36     private GestureDetector mGestureDetector;
37 
TouchForwardingLayout(Context context, AttributeSet attrs)38     public TouchForwardingLayout(Context context, AttributeSet attrs) {
39         super(context, attrs);
40         mGestureDetector = new GestureDetector(context,
41                 new GestureDetector.SimpleOnGestureListener() {
42                     @Override
43                     public boolean onSingleTapConfirmed(MotionEvent e) {
44                         return performClick();
45                     }
46                 });
47     }
48 
49     @Override
dispatchTouchEvent(MotionEvent ev)50     public boolean dispatchTouchEvent(MotionEvent ev) {
51         mGestureDetector.onTouchEvent(ev);
52         if (mView != null && mForwardingEnabled) {
53             mView.dispatchTouchEvent(ev);
54         }
55         return true;
56     }
57 
58     /** Set the view that the touch events are routed to */
setTargetView(View view)59     public void setTargetView(View view) {
60         mView = view;
61     }
62 
setForwardingEnabled(boolean forwardingEnabled)63     public void setForwardingEnabled(boolean forwardingEnabled) {
64         mForwardingEnabled = forwardingEnabled;
65     }
66 
67     /**
68      * Sets an Accessibility ACTION_CLICK to describe the TouchForwardingLayout onClick action.
69      * @param actionDescriptionRes The String resource describing the talkback double-tap action.
70      */
setOnClickAccessibilityDescription(@tringRes int actionDescriptionRes)71     public void setOnClickAccessibilityDescription(@StringRes int actionDescriptionRes) {
72         ViewCompat.setAccessibilityDelegate(this, new AccessibilityDelegateCompat() {
73             @Override
74             public void onInitializeAccessibilityNodeInfo(View host,
75                     AccessibilityNodeInfoCompat info) {
76                 super.onInitializeAccessibilityNodeInfo(host, info);
77                 CharSequence description = host.getResources().getString(actionDescriptionRes);
78                 AccessibilityActionCompat clickAction = new AccessibilityActionCompat(
79                         AccessibilityNodeInfoCompat.ACTION_CLICK, description);
80                 info.addAction(clickAction);
81             }
82         });
83     }
84 }
85