1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 package org.skia.canvasproof; 9 10 import android.app.Activity; 11 import android.content.res.AssetManager; 12 import android.graphics.Picture; 13 import android.opengl.GLSurfaceView; 14 import android.os.Bundle; 15 import android.util.Log; 16 import android.view.Gravity; 17 import android.view.MotionEvent; 18 import android.view.View; 19 import android.widget.LinearLayout.LayoutParams; 20 import android.widget.LinearLayout; 21 import java.io.File; 22 import java.io.IOException; 23 import java.io.InputStream; 24 25 public class CanvasProofActivity extends Activity { 26 private static final String TAG = "CanvasProofActivity"; 27 private GaneshPictureRenderer ganeshPictureRenderer; 28 private HwuiPictureView hwuiPictureView; 29 private GLSurfaceView ganeshPictureView; 30 private LinearLayout splitPaneView; 31 private View currentView; 32 private float x, y; 33 private int resourcesIndex; 34 private class PictureAsset { 35 public String path; 36 public long ptr; 37 public Picture picture; 38 }; 39 private PictureAsset[] assets; 40 41 @SuppressWarnings("deprecation") // purposely using this ReadPicture(InputStream inputStream)42 private static Picture ReadPicture(InputStream inputStream) 43 throws IOException { 44 Picture p = null; 45 try { 46 p = Picture.createFromStream(inputStream); 47 } catch (java.lang.Exception e) { 48 Log.e(TAG, "Exception in Picture.createFromStream", e); 49 } 50 inputStream.close(); 51 return p; 52 } 53 getAssetPaths()54 private void getAssetPaths() { 55 String directory = "skps"; 56 AssetManager mgr = this.getAssets(); 57 assert (mgr != null); 58 String[] resources; 59 try { 60 resources = mgr.list(directory); 61 } catch (IOException e) { 62 Log.e(TAG, "IOException in getAssetPaths", e); 63 return; 64 } 65 if (resources == null || resources.length == 0) { 66 Log.e(TAG, "SKP assets should be packaged in " + 67 ".../apps/canvasproof/src/main/assets/skps/" + 68 ", but none were found."); 69 return; 70 } 71 CreateSkiaPicture.init(); 72 this.assets = new PictureAsset[resources.length]; 73 for (int i = 0; i < resources.length; ++i) { 74 String path = directory + File.separator + resources[i]; 75 this.assets[i] = new PictureAsset(); 76 this.assets[i].path = path; 77 try { 78 this.assets[i].ptr = CreateSkiaPicture.create(mgr.open(path)); 79 if (0 == this.assets[i].ptr) { 80 Log.e(TAG, "CreateSkiaPicture.create returned 0 " + path); 81 } 82 Picture p = CanvasProofActivity.ReadPicture(mgr.open(path)); 83 if (null == p) { 84 Log.e(TAG, "CanvasProofActivity.ReadPicture.create " + 85 "returned null " + path); 86 } else if (0 == p.getHeight() || 0 == p.getWidth()) { 87 Log.e(TAG, "CanvasProofActivity.ReadPicture.create " + 88 "empty picture" + path); 89 p = null; 90 } 91 this.assets[i].picture = p; 92 } catch (IOException e) { 93 Log.e(TAG, "IOException in getAssetPaths " + path + e); 94 return; 95 } 96 } 97 } 98 nextView()99 private void nextView() { 100 if (this.currentView == this.hwuiPictureView) { 101 this.currentView = this.ganeshPictureView; 102 this.ganeshPictureView.setRenderMode( 103 GLSurfaceView.RENDERMODE_CONTINUOUSLY); 104 } else if (this.currentView == null || 105 this.currentView == this.ganeshPictureView) { 106 this.setContentView(new View(this)); 107 LayoutParams layoutParams = 108 new LayoutParams( 109 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 0.5f); 110 this.ganeshPictureView.setLayoutParams(layoutParams); 111 this.ganeshPictureView.setRenderMode( 112 GLSurfaceView.RENDERMODE_WHEN_DIRTY); 113 this.splitPaneView.addView(this.ganeshPictureView); 114 this.hwuiPictureView.setLayoutParams(layoutParams); 115 this.splitPaneView.addView(this.hwuiPictureView); 116 this.currentView = this.splitPaneView; 117 this.hwuiPictureView.fullTime = false; 118 } else if (this.currentView == this.splitPaneView) { 119 this.splitPaneView.removeAllViews(); 120 this.currentView = this.hwuiPictureView; 121 this.hwuiPictureView.fullTime = true; 122 } else { 123 Log.e(TAG, "unexpected value"); 124 this.setContentView(null); 125 return; 126 } 127 this.setContentView(this.currentView); 128 this.currentView.invalidate(); 129 } 130 nextPicture(int d)131 private void nextPicture(int d) { 132 if (this.assets == null) { 133 Log.w(TAG, "this.assets == null"); 134 return; 135 } 136 assert (this.assets.length > 0); 137 resourcesIndex = (resourcesIndex + d) % this.assets.length; 138 while (resourcesIndex < 0) { 139 resourcesIndex += this.assets.length; 140 } 141 while (resourcesIndex >= this.assets.length) { 142 resourcesIndex -= this.assets.length; 143 } 144 this.ganeshPictureRenderer.setPicture(assets[resourcesIndex].ptr); 145 this.hwuiPictureView.setPicture(assets[resourcesIndex].picture); 146 this.currentView.invalidate(); 147 } 148 149 @Override onStop()150 protected void onStop() { 151 this.ganeshPictureRenderer.releaseResources(); 152 super.onStop(); 153 } 154 155 @Override onCreate(Bundle savedInstanceState)156 protected void onCreate(Bundle savedInstanceState) { 157 super.onCreate(savedInstanceState); 158 159 this.getAssetPaths(); 160 this.ganeshPictureRenderer = new GaneshPictureRenderer(); 161 this.hwuiPictureView = new HwuiPictureView(this); 162 163 this.ganeshPictureRenderer.setScale(2.0f); 164 this.hwuiPictureView.setScale(2.0f); 165 this.ganeshPictureView = ganeshPictureRenderer.makeView(this); 166 this.splitPaneView = new LinearLayout(this); 167 this.splitPaneView.setOrientation(LinearLayout.VERTICAL); 168 this.splitPaneView.setGravity(Gravity.FILL); 169 170 LayoutParams layoutParams = 171 new LayoutParams( 172 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 0.5f); 173 this.ganeshPictureView.setLayoutParams(layoutParams); 174 this.hwuiPictureView.setLayoutParams(layoutParams); 175 176 this.nextView(); 177 this.nextPicture(0); 178 } 179 180 // TODO: replace this funtion with onTouchEvent(). 181 // @Override public boolean onTouchEvent(MotionEvent event)... 182 @Override dispatchTouchEvent(MotionEvent event)183 public boolean dispatchTouchEvent (MotionEvent event) { 184 switch(event.getAction()) { 185 case MotionEvent.ACTION_DOWN: 186 this.x = event.getX(); 187 this.y = event.getY(); 188 break; 189 case MotionEvent.ACTION_UP: 190 float dx = event.getX() - this.x; 191 float dy = event.getY() - this.y; 192 float dx2 = dx * dx; 193 float dy2 = dy * dy; 194 if (dx2 + dy2 > 22500.0) { 195 if (dy2 < dx2) { 196 this.nextPicture(dx > 0 ? 1 : -1); 197 } else if (dy > 0) { 198 this.nextView(); 199 } 200 } 201 break; 202 } 203 return super.onTouchEvent(event); 204 } 205 } 206