1/* 2 * Copyright (C) 2014 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 17package com.android.systemui.recents.views; 18 19import android.content.Context; 20import android.graphics.Canvas; 21import android.graphics.Paint; 22import android.graphics.Rect; 23import android.util.AttributeSet; 24import android.util.Pair; 25import android.view.View; 26import android.widget.FrameLayout; 27import android.widget.SeekBar; 28import com.android.systemui.R; 29import com.android.systemui.recents.RecentsConfiguration; 30 31import java.util.ArrayList; 32 33/** 34 * A full screen overlay layer that allows us to draw views from throughout the system on the top 35 * most layer. 36 */ 37public class DebugOverlayView extends FrameLayout implements SeekBar.OnSeekBarChangeListener { 38 39 public interface DebugOverlayViewCallbacks { 40 public void onPrimarySeekBarChanged(float progress); 41 public void onSecondarySeekBarChanged(float progress); 42 } 43 44 final static int sCornerRectSize = 50; 45 46 RecentsConfiguration mConfig; 47 DebugOverlayViewCallbacks mCb; 48 49 ArrayList<Pair<Rect, Integer>> mRects = new ArrayList<Pair<Rect, Integer>>(); 50 String mText; 51 Paint mDebugOutline = new Paint(); 52 Paint mTmpPaint = new Paint(); 53 Rect mTmpRect = new Rect(); 54 boolean mEnabled = true; 55 56 SeekBar mPrimarySeekBar; 57 SeekBar mSecondarySeekBar; 58 59 public DebugOverlayView(Context context) { 60 this(context, null); 61 } 62 63 public DebugOverlayView(Context context, AttributeSet attrs) { 64 this(context, attrs, 0); 65 } 66 67 public DebugOverlayView(Context context, AttributeSet attrs, int defStyleAttr) { 68 this(context, attrs, defStyleAttr, 0); 69 } 70 71 public DebugOverlayView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 72 super(context, attrs, defStyleAttr, defStyleRes); 73 mConfig = RecentsConfiguration.getInstance(); 74 mDebugOutline.setColor(0xFFff0000); 75 mDebugOutline.setStyle(Paint.Style.STROKE); 76 mDebugOutline.setStrokeWidth(8f); 77 setWillNotDraw(false); 78 } 79 80 public void setCallbacks(DebugOverlayViewCallbacks cb) { 81 mCb = cb; 82 } 83 84 @Override 85 protected void onFinishInflate() { 86 mPrimarySeekBar = (SeekBar) findViewById(R.id.debug_seek_bar_1); 87 mPrimarySeekBar.setOnSeekBarChangeListener(this); 88 mSecondarySeekBar = (SeekBar) findViewById(R.id.debug_seek_bar_2); 89 mSecondarySeekBar.setOnSeekBarChangeListener(this); 90 } 91 92 /** Enables the debug overlay drawing. */ 93 public void enable() { 94 mEnabled = true; 95 setVisibility(View.VISIBLE); 96 } 97 98 /** Disables the debug overlay drawing. */ 99 public void disable() { 100 mEnabled = false; 101 setVisibility(View.GONE); 102 } 103 104 /** Clears all debug rects. */ 105 public void clear() { 106 mRects.clear(); 107 } 108 109 /** Adds a rect to be drawn. */ 110 void addRect(Rect r, int color) { 111 mRects.add(new Pair<Rect, Integer>(r, color)); 112 invalidate(); 113 } 114 115 /** Adds a view's global rect to be drawn. */ 116 void addViewRect(View v, int color) { 117 Rect vr = new Rect(); 118 v.getGlobalVisibleRect(vr); 119 mRects.add(new Pair<Rect, Integer>(vr, color)); 120 invalidate(); 121 } 122 123 /** Adds a rect, relative to a given view to be drawn. */ 124 void addRectRelativeToView(View v, Rect r, int color) { 125 Rect vr = new Rect(); 126 v.getGlobalVisibleRect(vr); 127 r.offsetTo(vr.left, vr.top); 128 mRects.add(new Pair<Rect, Integer>(r, color)); 129 invalidate(); 130 } 131 132 /** Sets the debug text at the bottom of the screen. */ 133 void setText(String message) { 134 mText = message; 135 invalidate(); 136 } 137 138 @Override 139 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 140 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 141 addRect(new Rect(0, 0, sCornerRectSize, sCornerRectSize), 0xFFff0000); 142 addRect(new Rect(getMeasuredWidth() - sCornerRectSize, getMeasuredHeight() - sCornerRectSize, 143 getMeasuredWidth(), getMeasuredHeight()), 0xFFff0000); 144 } 145 146 @Override 147 protected void onDraw(Canvas canvas) { 148 if (mEnabled) { 149 // Draw the outline 150 canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mDebugOutline); 151 152 // Draw the rects 153 int numRects = mRects.size(); 154 for (int i = 0; i < numRects; i++) { 155 Pair<Rect, Integer> r = mRects.get(i); 156 mTmpPaint.setColor(r.second); 157 canvas.drawRect(r.first, mTmpPaint); 158 } 159 160 // Draw the text 161 if (mText != null && mText.length() > 0) { 162 mTmpPaint.setColor(0xFFff0000); 163 mTmpPaint.setTextSize(60); 164 mTmpPaint.getTextBounds(mText, 0, 1, mTmpRect); 165 canvas.drawText(mText, 10f, getMeasuredHeight() - mTmpRect.height() - mConfig.systemInsets.bottom, mTmpPaint); 166 } 167 } 168 } 169 170 /**** SeekBar.OnSeekBarChangeListener Implementation ****/ 171 172 @Override 173 public void onStopTrackingTouch(SeekBar seekBar) { 174 // Do nothing 175 } 176 177 @Override 178 public void onStartTrackingTouch(SeekBar seekBar) { 179 // Do nothing 180 } 181 182 @Override 183 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 184 if (seekBar == mPrimarySeekBar) { 185 mCb.onPrimarySeekBarChanged((float) progress / mPrimarySeekBar.getMax()); 186 } else if (seekBar == mSecondarySeekBar) { 187 mCb.onSecondarySeekBarChanged((float) progress / mSecondarySeekBar.getMax()); 188 } 189 } 190} 191