1 /*
2  * Copyright (C) 2021 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 
17 package com.android.car.rotaryplayground;
18 
19 import static com.android.car.ui.utils.RotaryConstants.BOTTOM_BOUND_OFFSET_FOR_NUDGE;
20 import static com.android.car.ui.utils.RotaryConstants.LEFT_BOUND_OFFSET_FOR_NUDGE;
21 import static com.android.car.ui.utils.RotaryConstants.RIGHT_BOUND_OFFSET_FOR_NUDGE;
22 import static com.android.car.ui.utils.RotaryConstants.TOP_BOUND_OFFSET_FOR_NUDGE;
23 
24 import android.content.Context;
25 import android.graphics.Canvas;
26 import android.graphics.Color;
27 import android.graphics.Paint;
28 import android.os.Bundle;
29 import android.util.AttributeSet;
30 import android.view.SurfaceView;
31 import android.view.accessibility.AccessibilityNodeInfo;
32 
33 import androidx.annotation.Nullable;
34 
35 /**
36  * A SurfaceView that allows to set its perceived bounds for the purposes of finding the nudge
37  * target.
38  */
39 public class CustomSurfaceView extends SurfaceView {
40 
41     /**
42      * The offset (in pixels) of the SurfaceView's bounds for the purposes of finding the nudge
43      * target.
44      */
45     private int mLeftOffset;
46     private int mRightOffset;
47     private int mTopOffset;
48     private int mBottomOffset;
49 
CustomSurfaceView(Context context)50     public CustomSurfaceView(Context context) {
51         super(context);
52     }
53 
CustomSurfaceView(Context context, @Nullable AttributeSet attrs)54     public CustomSurfaceView(Context context, @Nullable AttributeSet attrs) {
55         super(context, attrs);
56     }
57 
CustomSurfaceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr)58     public CustomSurfaceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
59         super(context, attrs, defStyleAttr);
60     }
61 
CustomSurfaceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)62     public CustomSurfaceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
63             int defStyleRes) {
64         super(context, attrs, defStyleAttr, defStyleRes);
65     }
66 
67     /**
68      * Sets the offset (in pixels) of the SurfaceView's bounds.
69      * <p>
70      * It only affects the perceived bounds for the purposes of finding the nudge target.
71      * This doesn't affect the view's bounds. This method should only be used when this view
72      * overlaps other focusable views so that nudge targeting is ambiguous.
73      */
setBoundsOffset(int left, int top, int right, int bottom)74     public void setBoundsOffset(int left, int top, int right, int bottom) {
75         mLeftOffset = left;
76         mTopOffset = top;
77         mRightOffset = right;
78         mBottomOffset = bottom;
79     }
80 
81     @Override
onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info)82     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
83         super.onInitializeAccessibilityNodeInfo(info);
84         if (mLeftOffset == 0 && mTopOffset == 0 && mRightOffset == 0 && mBottomOffset == 0) {
85             return;
86         }
87         Bundle bundle = info.getExtras();
88         bundle.putInt(LEFT_BOUND_OFFSET_FOR_NUDGE, mLeftOffset);
89         bundle.putInt(RIGHT_BOUND_OFFSET_FOR_NUDGE, mRightOffset);
90         bundle.putInt(TOP_BOUND_OFFSET_FOR_NUDGE, mTopOffset);
91         bundle.putInt(BOTTOM_BOUND_OFFSET_FOR_NUDGE, mBottomOffset);
92     }
93 
94     @Override
onDraw(Canvas canvas)95     protected void onDraw(Canvas canvas) {
96         super.onDraw(canvas);
97 
98         // Draw a text for demonstration purpose.
99         Paint paint = new Paint();
100         paint.setColor(Color.BLACK);
101         paint.setTextSize(40);
102         canvas.drawText("SurfaceView", 400, 200, paint);
103     }
104 }
105