80823b23918b195a415a29c6653794478e0e7ff8
[platform/framework/web/crosswalk.git] / src / xwalk / app / android / runtime_activity / src / org / xwalk / app / XWalkRuntimeActivityBase.java
1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.xwalk.app;
6
7 import android.app.Activity;
8 import android.app.AlertDialog;
9 import android.content.BroadcastReceiver;
10 import android.content.Context;
11 import android.content.DialogInterface;
12 import android.content.Intent;
13 import android.content.IntentFilter;
14 import android.net.Uri;
15 import android.os.Bundle;
16 import android.view.View;
17
18 import org.xwalk.app.runtime.extension.XWalkRuntimeExtensionManager;
19 import org.xwalk.app.runtime.XWalkRuntimeLibraryException;
20 import org.xwalk.app.runtime.XWalkRuntimeView;
21 import org.xwalk.core.ReflectionHelper;
22 import org.xwalk.core.XWalkPreferences;
23
24 public abstract class XWalkRuntimeActivityBase extends Activity {
25
26     private static final String DEFAULT_LIBRARY_APK_URL = null;
27
28     private XWalkRuntimeView mRuntimeView;
29
30     private boolean mShownNotFoundDialog = false;
31
32     private BroadcastReceiver mReceiver;
33
34     private boolean mRemoteDebugging = false;
35
36     private boolean mUseAnimatableView = false;
37
38     private AlertDialog mLibraryNotFoundDialog = null;
39
40     private XWalkRuntimeExtensionManager mExtensionManager;
41
42     @Override
43     public void onCreate(Bundle savedInstanceState) {
44         IntentFilter intentFilter = new IntentFilter("org.xwalk.intent");
45         intentFilter.addAction("android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE");
46         intentFilter.addAction("android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE");
47         mReceiver = new BroadcastReceiver() {
48             @Override
49             public void onReceive(Context context, Intent intent) {
50                 Bundle bundle = intent.getExtras();
51                 if (bundle == null)
52                     return;
53
54                 if (bundle.containsKey("remotedebugging")) {
55                     String extra = bundle.getString("remotedebugging");
56                     if (extra.equals("true")) {
57                         XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
58                     } else if (extra.equals("false")) {
59                         XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
60                     }
61                 }
62             }
63         };
64         registerReceiver(mReceiver, intentFilter);
65         super.onCreate(savedInstanceState);
66         tryLoadRuntimeView();
67         if (mRuntimeView != null) mRuntimeView.onCreate();
68     }
69
70     @Override
71     public void onStart() {
72         super.onStart();
73         if (mExtensionManager != null) mExtensionManager.onStart();
74     }
75
76     @Override
77     public void onPause() {
78         super.onPause();
79         if (mRuntimeView != null) mRuntimeView.onPause();
80         if (mExtensionManager != null) mExtensionManager.onPause();
81     }
82
83     @Override
84     public void onResume() {
85         super.onResume();
86         if (mRuntimeView != null) mRuntimeView.onResume();
87         if (mExtensionManager != null) mExtensionManager.onResume();
88     }
89
90     @Override
91     public void onStop() {
92         super.onStop();
93         if (mExtensionManager != null) mExtensionManager.onStop();
94     }
95
96     @Override
97     public void onDestroy() {
98         unregisterReceiver(mReceiver);
99         if (mExtensionManager != null) mExtensionManager.onDestroy();
100         super.onDestroy();
101     }
102
103     @Override
104     public void onNewIntent(Intent intent) {
105         if (mRuntimeView == null || !mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
106         if (mExtensionManager != null) mExtensionManager.onNewIntent(intent);
107     }
108
109     @Override
110     public void onActivityResult(int requestCode, int resultCode, Intent data) {
111         super.onActivityResult(requestCode, resultCode, data);
112         if (mRuntimeView != null) mRuntimeView.onActivityResult(requestCode, resultCode, data);
113         if (mExtensionManager != null) mExtensionManager.onActivityResult(requestCode, resultCode, data);
114     }
115
116     private String getLibraryApkDownloadUrl() {
117         int resId = getResources().getIdentifier("xwalk_library_apk_download_url", "string", getPackageName());
118         if (resId == 0) return DEFAULT_LIBRARY_APK_URL;
119         return getString(resId);
120     }
121
122     public String getString(String label) {
123         int resId = getResources().getIdentifier(label, "string", getPackageName());
124         if (resId == 0) return label.replace('_', ' ');
125         return getString(resId);
126     }
127
128     private void tryLoadRuntimeView() {
129         try {
130             if (mUseAnimatableView) {
131                 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true);
132             } else {
133                 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, false);
134             }
135             mRuntimeView = new XWalkRuntimeView(this, this, null);
136             mShownNotFoundDialog = false;
137             if (mLibraryNotFoundDialog != null) mLibraryNotFoundDialog.cancel();
138             if (mRemoteDebugging) {
139                 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
140             } else {
141                 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
142             }
143             // XWalkPreferences.ENABLE_EXTENSIONS
144             if (XWalkPreferences.getValue("enable-extensions")) {
145                 // Enable xwalk extension mechanism and start load extensions here.
146                 // Note that it has to be after above initialization.
147                 mExtensionManager = new XWalkRuntimeExtensionManager(getApplicationContext(), this);
148                 mExtensionManager.loadExtensions();
149             }
150         } catch (Exception e) {
151             handleException(e);
152         }
153         didTryLoadRuntimeView(mRuntimeView);
154     }
155
156     public XWalkRuntimeView getRuntimeView() {
157         return mRuntimeView;
158     }
159
160     public void handleException(Throwable e) {
161         if (e instanceof RuntimeException) {
162             handleException(e.getCause());
163             return;
164         }
165
166         if (e instanceof XWalkRuntimeLibraryException) {
167             String title = "";
168             String message = "";
169             XWalkRuntimeLibraryException runtimeException = (XWalkRuntimeLibraryException) e;
170             switch (runtimeException.getType()) {
171             case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_UP_TO_DATE_CRITICAL:
172                 title = getString("dialog_title_update_runtime_lib");
173                 message = getString("dialog_message_update_runtime_lib");
174                 break;
175             case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_UP_TO_DATE_WARNING:
176                 title = getString("dialog_title_update_runtime_lib_warning");
177                 message = getString("dialog_message_update_runtime_lib_warning");
178                 break;
179             case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_INSTALLED:
180                 title = getString("dialog_title_install_runtime_lib");
181                 message = getString("dialog_message_install_runtime_lib");
182                 break;
183             case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_INVOKE_FAILED:
184             default:
185                 Exception originException = runtimeException.getOriginException();
186                 if (originException != null) handleException(originException);
187                 return;
188             }
189             showRuntimeLibraryExceptionDialog(title, message);
190         } else {
191             e.printStackTrace();
192             throw new RuntimeException(e);
193         }
194     }
195
196     private void showRuntimeLibraryExceptionDialog(String title, String message) {
197         if (!mShownNotFoundDialog) {
198             AlertDialog.Builder builder = new AlertDialog.Builder(this);
199             if (!ReflectionHelper.shouldUseLibrary()) {
200                 builder.setPositiveButton(android.R.string.ok,
201                         new DialogInterface.OnClickListener() {
202                             public void onClick(DialogInterface dialog, int id) {
203                                 finish();
204                             }
205                         });
206             } else {
207                 builder.setNegativeButton(android.R.string.cancel,
208                         new DialogInterface.OnClickListener() {
209                             public void onClick(DialogInterface dialog, int id) {
210                                 // User cancelled the dialog
211                             }
212                         });
213                 final String downloadUrl = getLibraryApkDownloadUrl();
214                 if (downloadUrl != null && downloadUrl.length() > 0) {
215                     builder.setNeutralButton(getString("download_from_url"),
216                             new DialogInterface.OnClickListener() {
217                                 public void onClick(DialogInterface dialog, int id) {
218                                     Intent goDownload = new Intent(Intent.ACTION_VIEW);
219                                     goDownload.setData(Uri.parse(downloadUrl));
220                                     startActivity(goDownload);
221                                 }
222                             });
223                 }
224                 builder.setPositiveButton(getString("download_from_store"),
225                         new DialogInterface.OnClickListener() {
226                             public void onClick(DialogInterface dialog, int id) {
227                                 Intent goToMarket = new Intent(Intent.ACTION_VIEW);
228                                 goToMarket.setData(Uri.parse(
229                                         "market://details?id=org.xwalk.core"));
230                                 startActivity(goToMarket);
231                             }
232                         });
233             }
234             builder.setTitle(title).setMessage(message);
235
236             mLibraryNotFoundDialog = builder.create();
237             mLibraryNotFoundDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
238                 @Override
239                 public void onCancel(DialogInterface dialog) {
240                     mLibraryNotFoundDialog = null;
241                 }
242             });
243             mLibraryNotFoundDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
244                 @Override
245                 public void onDismiss(DialogInterface dialog) {
246                     mLibraryNotFoundDialog = null;
247                 }
248             });
249             mLibraryNotFoundDialog.show();
250             mShownNotFoundDialog = true;
251         }
252     }
253
254     /*
255      * Called each time trying to load runtime view from library apk.
256      * Descendant should handle both succeeded and failed to load
257      * library apk.
258      *
259      * @param, The RuntimeView loaded, it can be null for failed to load RuntimeView.
260      */
261     abstract protected void didTryLoadRuntimeView(View runtimeView);
262
263     public void setRemoteDebugging(boolean value) {
264         mRemoteDebugging = value;
265     }
266
267     public void setUseAnimatableView(boolean value) {
268         mUseAnimatableView = value;
269     }
270
271 }