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