• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.viewer;
9 
10 import android.app.Application;
11 import android.content.Intent;
12 import android.content.res.AssetManager;
13 import java.nio.ByteBuffer;
14 import java.nio.charset.StandardCharsets;
15 
16 public class ViewerApplication extends Application {
17     private long mNativeHandle = 0;
18     private ViewerActivity mViewerActivity;
19     private String mStateJsonStr, mTitle;
20 
21     static {
22         System.loadLibrary("viewer");
23     }
24 
createNativeApp(AssetManager assetManager, ByteBuffer[] args)25     private native long createNativeApp(AssetManager assetManager, ByteBuffer[] args);
destroyNativeApp(long handle)26     private native void destroyNativeApp(long handle);
27 
28     @Override
onTerminate()29     public void onTerminate() {
30         if (mNativeHandle != 0) {
31             destroyNativeApp(mNativeHandle);
32             mNativeHandle = 0;
33         }
34         super.onTerminate();
35     }
36 
getNativeHandle()37     public long getNativeHandle() {
38         return mNativeHandle;
39     }
40 
setViewerActivity(ViewerActivity viewerActivity)41     public void setViewerActivity(ViewerActivity viewerActivity) {
42         mViewerActivity = viewerActivity;
43         // Note that viewerActivity might be null (called by onDestroy)
44         if (mViewerActivity != null) {
45             // A new ViewerActivity is created; initialize its state and title
46             if (mStateJsonStr != null) {
47                 mViewerActivity.setState(mStateJsonStr);
48             }
49             if (mTitle != null) {
50                 mViewerActivity.setTitle(mTitle);
51             }
52             if (mNativeHandle == 0) {
53                 final ByteBuffer[] byteBufferArgs;
54                 Intent intent = viewerActivity.getIntent();
55                 String args = intent.getStringExtra("args");
56                 if (args == null) {
57                     byteBufferArgs = new ByteBuffer[0];
58                 } else {
59                     //TODO: split args better?
60                     String[] splitArgs = args.split("\\s+");
61                     byteBufferArgs = new ByteBuffer[splitArgs.length];
62                     for (int i = 0; i < splitArgs.length; ++i) {
63                         ByteBuffer bbArg = StandardCharsets.UTF_8.encode(splitArgs[i]);
64                         ByteBuffer directBBArg = ByteBuffer.allocateDirect(bbArg.limit() + 1);
65                         for (int j = 0; j < bbArg.limit(); ++j) {
66                             directBBArg.put(j, bbArg.get(j));
67                         }
68                         // UTF-8 doens't allow a zero terminator, but args require it.
69                         directBBArg.put(bbArg.limit(), (byte)0);
70                         byteBufferArgs[i] = directBBArg;
71                     }
72                 }
73                 mNativeHandle = createNativeApp(this.getResources().getAssets(), byteBufferArgs);
74             }
75         }
76     }
77 
setTitle(String title)78     public void setTitle(String title) {
79         mTitle = title; // Similar to mStateJsonStr, we have to store this.
80         if (mTitle.startsWith("Viewer: ")) { // Quick hack to shorten the title
81             mTitle = mTitle.replaceFirst("Viewer: ", "");
82         }
83         if (mViewerActivity != null) {
84             mViewerActivity.runOnUiThread(new Runnable() {
85                 @Override
86                 public void run() {
87                     mViewerActivity.setTitle(mTitle);
88                 }
89             });
90         }
91     }
92 
setState(String stateJsonStr)93     public void setState(String stateJsonStr) {
94         // We have to store this state because ViewerActivity may be destroyed while the native app
95         // is still running. When a new ViewerActivity is created, we'll pass the state to it.
96         mStateJsonStr = stateJsonStr;
97         if (mViewerActivity != null) {
98             mViewerActivity.runOnUiThread(new Runnable() {
99                 @Override
100                 public void run() {
101                     mViewerActivity.setState(mStateJsonStr);
102                 }
103             });
104         }
105     }
106 }
107