Home | History | Annotate | Download | only in hwui
      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 
     38 import java.io.PipedInputStream;
     39 import java.io.PipedOutputStream;
     40 import java.util.Random;
     41 import java.util.concurrent.ExecutorService;
     42 import java.util.concurrent.Executors;
     43 import java.util.concurrent.Future;
     44 
     45 public class PictureCaptureDemo extends Activity {
     46     @Override
     47     protected void onCreate(Bundle savedInstanceState) {
     48         super.onCreate(savedInstanceState);
     49 
     50         final LinearLayout layout = new LinearLayout(this);
     51         layout.setOrientation(LinearLayout.VERTICAL);
     52 
     53         final LinearLayout inner = new LinearLayout(this);
     54         inner.setOrientation(LinearLayout.HORIZONTAL);
     55         ProgressBar spinner = new ProgressBar(this, null, android.R.attr.progressBarStyleLarge);
     56         inner.addView(spinner,
     57                 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
     58 
     59         inner.addView(new View(this), new LayoutParams(50, 1));
     60 
     61         Picture picture = new Picture();
     62         Canvas canvas = picture.beginRecording(100, 100);
     63         canvas.drawColor(Color.RED);
     64         Paint paint = new Paint();
     65         paint.setTextSize(32);
     66         paint.setColor(Color.BLACK);
     67         canvas.drawText("Hello", 0, 50, paint);
     68         picture.endRecording();
     69 
     70         ImageView iv1 = new ImageView(this);
     71         iv1.setImageBitmap(Bitmap.createBitmap(picture, 100, 100, Bitmap.Config.ARGB_8888));
     72         inner.addView(iv1, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
     73 
     74         inner.addView(new View(this), new LayoutParams(50, 1));
     75 
     76         ImageView iv2 = new ImageView(this);
     77         iv2.setImageBitmap(Bitmap.createBitmap(picture, 100, 100, Bitmap.Config.HARDWARE));
     78         inner.addView(iv2, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
     79 
     80         layout.addView(inner,
     81                 new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
     82         // For testing with a functor in the tree
     83         WebView wv = new WebView(this);
     84         wv.setWebViewClient(new WebViewClient());
     85         wv.setWebChromeClient(new WebChromeClient());
     86         wv.loadUrl("https://google.com");
     87         layout.addView(wv, new LayoutParams(LayoutParams.MATCH_PARENT, 400));
     88 
     89         SurfaceView mySurfaceView = new SurfaceView(this);
     90         layout.addView(mySurfaceView,
     91                 new LayoutParams(LayoutParams.MATCH_PARENT, 600));
     92 
     93         setContentView(layout);
     94 
     95         mySurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
     96             private AutoCloseable mStopCapture;
     97 
     98             @Override
     99             public void surfaceCreated(SurfaceHolder holder) {
    100                 final Random rand = new Random();
    101                 mStopCapture = ViewDebug.startRenderingCommandsCapture(mySurfaceView,
    102                         mCaptureThread, (picture) -> {
    103                             if (rand.nextInt(20) == 0) {
    104                                 try {
    105                                     Thread.sleep(100);
    106                                 } catch (InterruptedException e) {
    107                                 }
    108                             }
    109                             Canvas canvas = holder.lockCanvas();
    110                             if (canvas == null) {
    111                                 return false;
    112                             }
    113                             canvas.drawPicture(picture);
    114                             holder.unlockCanvasAndPost(canvas);
    115                             picture.close();
    116                             return true;
    117                         });
    118             }
    119 
    120             @Override
    121             public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    122 
    123             }
    124 
    125             @Override
    126             public void surfaceDestroyed(SurfaceHolder holder) {
    127                 if (mStopCapture != null) {
    128                     try {
    129                         mStopCapture.close();
    130                     } catch (Exception e) {
    131                     }
    132                     mStopCapture = null;
    133                 }
    134             }
    135         });
    136     }
    137 
    138     ExecutorService mCaptureThread = Executors.newSingleThreadExecutor();
    139     ExecutorService mExecutor = Executors.newSingleThreadExecutor();
    140 
    141     Picture deepCopy(Picture src) {
    142         try {
    143             PipedInputStream inputStream = new PipedInputStream();
    144             PipedOutputStream outputStream = new PipedOutputStream(inputStream);
    145             Future<Picture> future = mExecutor.submit(() -> Picture.createFromStream(inputStream));
    146             src.writeToStream(outputStream);
    147             outputStream.close();
    148             return future.get();
    149         } catch (Exception ex) {
    150             throw new RuntimeException(ex);
    151         }
    152     }
    153 }
    154