Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2019 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 android.systemui.cts;
     18 
     19 import android.graphics.Canvas;
     20 import android.graphics.Color;
     21 import android.graphics.ColorFilter;
     22 import android.graphics.CornerPathEffect;
     23 import android.graphics.DashPathEffect;
     24 import android.graphics.Insets;
     25 import android.graphics.Paint;
     26 import android.graphics.Path;
     27 import android.graphics.Point;
     28 import android.graphics.Rect;
     29 import android.graphics.drawable.Drawable;
     30 import android.view.MotionEvent;
     31 import android.view.View;
     32 import android.view.WindowInsets;
     33 
     34 import java.util.ArrayList;
     35 import java.util.List;
     36 
     37 public class WindowInsetsPresenterDrawable extends Drawable implements View.OnTouchListener {
     38     private static final int GAP = 15;
     39     private final Path mPath;
     40     private final Paint mMandatorySystemGesturePaint;
     41     private final Paint mSystemGesturePaint;
     42     private final Paint mSystemWindowPaint;
     43     private final Paint mTappableElementPaint;
     44     private final Paint mTouchPaint;
     45     private final Paint mTouchTrackPaint;
     46     private final List<Point> mAllActionPoints;
     47     private final List<Point> mActionCancelPoints;
     48     private final List<Point> mActionDownPoints;
     49     private final List<Point> mActionUpPoints;
     50     private WindowInsets mWindowInsets;
     51     private float mLastX;
     52     private float mLastY;
     53 
     54     /**
     55      * Initial 4 paints and 1 path for drawing.
     56      * initial mPointList for recording the touch points.
     57      */
     58     public WindowInsetsPresenterDrawable() {
     59         mMandatorySystemGesturePaint = new Paint();
     60         mMandatorySystemGesturePaint.setStrokeWidth(2);
     61         mMandatorySystemGesturePaint.setStyle(Paint.Style.STROKE);
     62         mMandatorySystemGesturePaint.setColor(Color.RED);
     63         mMandatorySystemGesturePaint.setPathEffect(new DashPathEffect(new float[]{GAP, GAP * 3},
     64                 0));
     65 
     66         mSystemGesturePaint = new Paint();
     67         mSystemGesturePaint.setStrokeWidth(2);
     68         mSystemGesturePaint.setStyle(Paint.Style.STROKE);
     69         mSystemGesturePaint.setColor(Color.GREEN);
     70         mSystemGesturePaint.setPathEffect(new DashPathEffect(new float[]{GAP, GAP, GAP * 2},
     71                 0));
     72 
     73         mTappableElementPaint = new Paint();
     74         mTappableElementPaint.setStrokeWidth(2);
     75         mTappableElementPaint.setStyle(Paint.Style.STROKE);
     76         mTappableElementPaint.setColor(Color.BLUE);
     77         mTappableElementPaint.setPathEffect(new DashPathEffect(new float[]{GAP * 2, GAP, GAP}, 0));
     78 
     79         mSystemWindowPaint = new Paint();
     80         mSystemWindowPaint.setStrokeWidth(2);
     81         mSystemWindowPaint.setStyle(Paint.Style.STROKE);
     82         mSystemWindowPaint.setColor(Color.YELLOW);
     83         mSystemWindowPaint.setPathEffect(new DashPathEffect(new float[]{0, GAP * 3, GAP}, 0));
     84 
     85         mTouchPaint = new Paint();
     86         mTouchPaint.setColor(0x4ffff070);
     87         mTouchPaint.setStrokeWidth(10);
     88         mTouchPaint.setStyle(Paint.Style.FILL_AND_STROKE);
     89 
     90         mPath = new Path();
     91         mTouchTrackPaint = new Paint();
     92         mTouchTrackPaint.setColor(Color.WHITE);
     93         mTouchTrackPaint.setStrokeWidth(1);
     94         mTouchTrackPaint.setStyle(Paint.Style.STROKE);
     95         mTouchTrackPaint.setPathEffect(new CornerPathEffect(5));
     96 
     97         mAllActionPoints = new ArrayList<>();
     98         mActionCancelPoints = new ArrayList<>();
     99         mActionDownPoints = new ArrayList<>();
    100         mActionUpPoints = new ArrayList<>();
    101     }
    102 
    103 
    104     public WindowInsetsPresenterDrawable(WindowInsets windowInsets) {
    105         this();
    106         mWindowInsets = windowInsets;
    107     }
    108 
    109     @Override
    110     public void setBounds(Rect bounds) {
    111         super.setBounds(bounds);
    112     }
    113 
    114     private void drawInset(Canvas canvas, Insets insets, Paint paint) {
    115         final Rect rect = getBounds();
    116 
    117         if (insets.left > 0) {
    118             canvas.drawRect(0, 0, insets.left, rect.bottom, paint);
    119         }
    120         if (insets.top > 0) {
    121             canvas.drawRect(0, 0, rect.width(), insets.top, paint);
    122         }
    123         if (insets.right > 0) {
    124             canvas.drawRect(rect.width() - insets.right, 0, rect.width(), rect.bottom,
    125                     paint);
    126         }
    127         if (insets.bottom > 0) {
    128             canvas.drawRect(0, rect.height() - insets.bottom, rect.width(), rect.height(),
    129                     paint);
    130         }
    131     }
    132 
    133     @Override
    134     public void draw(Canvas canvas) {
    135         canvas.save();
    136 
    137         if (mWindowInsets != null) {
    138             drawInset(canvas, mWindowInsets.getSystemGestureInsets(), mSystemGesturePaint);
    139             drawInset(canvas, mWindowInsets.getMandatorySystemGestureInsets(),
    140                     mMandatorySystemGesturePaint);
    141             drawInset(canvas, mWindowInsets.getTappableElementInsets(), mTappableElementPaint);
    142             drawInset(canvas, mWindowInsets.getSystemWindowInsets(), mSystemWindowPaint);
    143         }
    144 
    145         if (mAllActionPoints.size() > 0) {
    146             canvas.drawPath(mPath, mTouchTrackPaint);
    147 
    148             for (Point p : mAllActionPoints) {
    149                 canvas.drawPoint(p.x, p.y, mTouchPaint);
    150             }
    151         }
    152 
    153         canvas.restore();
    154     }
    155 
    156     @Override
    157     public void setAlpha(int alpha) {
    158         /* do noting, only for implement abstract method */
    159     }
    160 
    161     @Override
    162     public void setColorFilter(ColorFilter colorFilter) {
    163         /* do noting, only for implement abstract method */
    164     }
    165 
    166     @Override
    167     public int getOpacity() {
    168         return 255; /* not transparent */
    169     }
    170 
    171     /**
    172      * To set the IwndowInsets that is showed on this drawable.
    173      * @param windowInsets the WindowInsets will show.
    174      */
    175     public void setWindowInsets(WindowInsets windowInsets) {
    176         if (windowInsets != null) {
    177             mWindowInsets = new WindowInsets.Builder(windowInsets).build();
    178             invalidateSelf();
    179         }
    180     }
    181 
    182     @Override
    183     public boolean onTouch(View v, MotionEvent event) {
    184         Point p;
    185         switch (event.getAction()) {
    186             case MotionEvent.ACTION_DOWN:
    187                 mPath.moveTo(event.getX(), event.getY());
    188                 p = new Point((int) event.getX(), (int) event.getY());
    189                 mAllActionPoints.add(p);
    190                 mActionDownPoints.add(p);
    191                 mLastX = event.getX();
    192                 mLastY = event.getY();
    193                 invalidateSelf();
    194 
    195                 break;
    196             case MotionEvent.ACTION_UP:
    197                 mPath.lineTo(event.getX(), event.getY());
    198                 p = new Point((int) event.getX(), (int) event.getY());
    199                 mAllActionPoints.add(p);
    200                 mActionUpPoints.add(p);
    201                 invalidateSelf();
    202                 break;
    203             case MotionEvent.ACTION_MOVE:
    204                 mPath.quadTo(mLastX, mLastY, event.getX(), event.getY());
    205                 p = new Point((int) event.getX(), (int) event.getY());
    206                 mAllActionPoints.add(p);
    207                 mLastX = event.getX();
    208                 mLastY = event.getY();
    209                 invalidateSelf();
    210                 break;
    211             case MotionEvent.ACTION_CANCEL:
    212                 mPath.lineTo(event.getX(), event.getY());
    213                 p = new Point((int) event.getX(), (int) event.getY());
    214                 mAllActionPoints.add(p);
    215                 mActionCancelPoints.add(p);
    216                 break;
    217             default:
    218                 break;
    219         }
    220         return false;
    221     }
    222 
    223     public List<Point> getActionCancelPoints() {
    224         return mActionCancelPoints;
    225     }
    226 
    227     public List<Point> getActionDownPoints() {
    228         return mActionDownPoints;
    229     }
    230 
    231     public List<Point> getActionUpPoints() {
    232         return mActionUpPoints;
    233     }
    234 }
    235