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 com.android.test.hwui; 18 19 import android.app.Activity; 20 import android.graphics.Bitmap; 21 import android.graphics.Canvas; 22 import android.graphics.Color; 23 import android.graphics.Paint; 24 import android.graphics.Picture; 25 import android.os.Bundle; 26 import android.view.SurfaceHolder; 27 import android.view.SurfaceView; 28 import android.view.View; 29 import android.view.ViewDebug; 30 import android.webkit.WebChromeClient; 31 import android.webkit.WebView; 32 import android.webkit.WebViewClient; 33 import android.widget.ImageView; 34 import android.widget.LinearLayout; 35 import android.widget.LinearLayout.LayoutParams; 36 import android.widget.ProgressBar; 37 import android.widget.TextView; 38 39 import java.io.ByteArrayInputStream; 40 import java.io.ByteArrayOutputStream; 41 import java.io.IOException; 42 import java.io.OutputStream; 43 import java.util.Random; 44 import java.util.concurrent.Executors; 45 46 public class PictureCaptureDemo extends Activity { 47 @Override onCreate(Bundle savedInstanceState)48 protected void onCreate(Bundle savedInstanceState) { 49 super.onCreate(savedInstanceState); 50 51 final LinearLayout layout = new LinearLayout(this); 52 layout.setOrientation(LinearLayout.VERTICAL); 53 54 final LinearLayout inner = new LinearLayout(this); 55 inner.setOrientation(LinearLayout.HORIZONTAL); 56 ProgressBar spinner = new ProgressBar(this, null, android.R.attr.progressBarStyleLarge); 57 inner.addView(spinner, 58 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 59 60 inner.addView(new View(this), new LayoutParams(50, 1)); 61 62 Picture picture = new Picture(); 63 Canvas canvas = picture.beginRecording(100, 100); 64 canvas.drawColor(Color.RED); 65 Paint paint = new Paint(); 66 paint.setTextSize(32); 67 paint.setColor(Color.BLACK); 68 canvas.drawText("Hello", 0, 50, paint); 69 picture.endRecording(); 70 71 ImageView iv1 = new ImageView(this); 72 iv1.setImageBitmap(Bitmap.createBitmap(picture, 100, 100, Bitmap.Config.ARGB_8888)); 73 inner.addView(iv1, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 74 75 inner.addView(new View(this), new LayoutParams(50, 1)); 76 77 ImageView iv2 = new ImageView(this); 78 iv2.setImageBitmap(Bitmap.createBitmap(picture, 100, 100, Bitmap.Config.HARDWARE)); 79 inner.addView(iv2, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 80 81 TextView hello = new TextView(this); 82 hello.setText("I'm on a layer!"); 83 hello.setLayerType(View.LAYER_TYPE_HARDWARE, null); 84 inner.addView(hello, 85 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 86 87 layout.addView(inner, 88 new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); 89 // For testing with a functor in the tree 90 WebView wv = new WebView(this); 91 wv.setWebViewClient(new WebViewClient()); 92 wv.setWebChromeClient(new WebChromeClient()); 93 wv.loadUrl("https://google.com"); 94 LayoutParams wvParams = new LayoutParams(LayoutParams.MATCH_PARENT, 400); 95 wvParams.bottomMargin = 50; 96 layout.addView(wv, wvParams); 97 98 SurfaceView mySurfaceView = new SurfaceView(this); 99 layout.addView(mySurfaceView, 100 new LayoutParams(LayoutParams.MATCH_PARENT, 600, 1f)); 101 102 setContentView(layout); 103 104 mySurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { 105 private AutoCloseable mStopCapture; 106 107 @Override 108 public void surfaceCreated(SurfaceHolder holder) { 109 final Random rand = new Random(); 110 OutputStream renderingStream = new ByteArrayOutputStream() { 111 @Override 112 public void flush() throws IOException { 113 Picture picture = Picture.createFromStream( 114 new ByteArrayInputStream(buf, 0, count)); 115 Canvas canvas = holder.lockCanvas(); 116 if (canvas != null && picture != null) { 117 canvas.drawPicture(picture); 118 holder.unlockCanvasAndPost(canvas); 119 } 120 reset(); 121 } 122 }; 123 124 mStopCapture = ViewDebug.startRenderingCommandsCapture(mySurfaceView, 125 Executors.newSingleThreadExecutor(), () -> { 126 if (rand.nextInt(20) == 0) { 127 try { 128 Thread.sleep(100); 129 } catch (InterruptedException e) { 130 } 131 } 132 return renderingStream; 133 }); 134 } 135 136 @Override 137 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 138 139 } 140 141 @Override 142 public void surfaceDestroyed(SurfaceHolder holder) { 143 if (mStopCapture != null) { 144 try { 145 mStopCapture.close(); 146 } catch (Exception e) { 147 } 148 mStopCapture = null; 149 } 150 } 151 }); 152 } 153 } 154