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.
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;
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;
24 public abstract class XWalkRuntimeActivityBase extends Activity {
26 private static final String DEFAULT_LIBRARY_APK_URL = null;
28 private XWalkRuntimeView mRuntimeView;
30 private boolean mShownNotFoundDialog = false;
32 private BroadcastReceiver mReceiver;
34 private boolean mRemoteDebugging = false;
36 private AlertDialog mLibraryNotFoundDialog = null;
38 private XWalkRuntimeExtensionManager mExtensionManager;
41 public void onCreate(Bundle savedInstanceState) {
42 IntentFilter intentFilter = new IntentFilter("org.xwalk.intent");
43 intentFilter.addAction("android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE");
44 intentFilter.addAction("android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE");
45 mReceiver = new BroadcastReceiver() {
47 public void onReceive(Context context, Intent intent) {
48 Bundle bundle = intent.getExtras();
52 if (bundle.containsKey("remotedebugging")) {
53 String extra = bundle.getString("remotedebugging");
54 if (extra.equals("true")) {
55 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
56 } else if (extra.equals("false")) {
57 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
62 registerReceiver(mReceiver, intentFilter);
63 super.onCreate(savedInstanceState);
65 if (mRuntimeView != null) mRuntimeView.onCreate();
69 public void onStart() {
71 if (mExtensionManager != null) mExtensionManager.onStart();
75 public void onPause() {
77 if (mRuntimeView != null) mRuntimeView.onPause();
78 if (mExtensionManager != null) mExtensionManager.onPause();
82 public void onResume() {
84 if (mRuntimeView != null) mRuntimeView.onResume();
85 if (mExtensionManager != null) mExtensionManager.onResume();
89 public void onStop() {
91 if (mExtensionManager != null) mExtensionManager.onStop();
95 public void onDestroy() {
96 unregisterReceiver(mReceiver);
97 if (mExtensionManager != null) mExtensionManager.onDestroy();
102 public void onNewIntent(Intent intent) {
103 if (mRuntimeView == null || !mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
107 public void onActivityResult(int requestCode, int resultCode, Intent data) {
108 super.onActivityResult(requestCode, resultCode, data);
109 if (mRuntimeView != null) mRuntimeView.onActivityResult(requestCode, resultCode, data);
110 if (mExtensionManager != null) mExtensionManager.onActivityResult(requestCode, resultCode, data);
113 private String getLibraryApkDownloadUrl() {
114 int resId = getResources().getIdentifier("xwalk_library_apk_download_url", "string", getPackageName());
115 if (resId == 0) return DEFAULT_LIBRARY_APK_URL;
116 return getString(resId);
119 public String getString(String label) {
120 int resId = getResources().getIdentifier(label, "string", getPackageName());
121 if (resId == 0) return label.replace('_', ' ');
122 return getString(resId);
125 private void tryLoadRuntimeView() {
127 mRuntimeView = new XWalkRuntimeView(this, this, null);
128 mShownNotFoundDialog = false;
129 if (mLibraryNotFoundDialog != null) mLibraryNotFoundDialog.cancel();
130 if (mRemoteDebugging) {
131 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
133 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
135 // XWalkPreferences.ENABLE_EXTENSIONS
136 if (XWalkPreferences.getValue("enable-extensions")) {
137 // Enable xwalk extension mechanism and start load extensions here.
138 // Note that it has to be after above initialization.
139 mExtensionManager = new XWalkRuntimeExtensionManager(getApplicationContext(), this);
140 mExtensionManager.loadExtensions();
142 } catch (Exception e) {
145 didTryLoadRuntimeView(mRuntimeView);
148 public XWalkRuntimeView getRuntimeView() {
152 public void handleException(Throwable e) {
153 if (e instanceof RuntimeException) {
154 handleException(e.getCause());
158 if (e instanceof XWalkRuntimeLibraryException) {
161 XWalkRuntimeLibraryException runtimeException = (XWalkRuntimeLibraryException) e;
162 switch (runtimeException.getType()) {
163 case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_UP_TO_DATE_CRITICAL:
164 title = getString("dialog_title_update_runtime_lib");
165 message = getString("dialog_message_update_runtime_lib");
167 case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_UP_TO_DATE_WARNING:
168 title = getString("dialog_title_update_runtime_lib_warning");
169 message = getString("dialog_message_update_runtime_lib_warning");
171 case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_INSTALLED:
172 title = getString("dialog_title_install_runtime_lib");
173 message = getString("dialog_message_install_runtime_lib");
175 case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_INVOKE_FAILED:
177 Exception originException = runtimeException.getOriginException();
178 if (originException != null) handleException(originException);
181 showRuntimeLibraryExceptionDialog(title, message);
184 throw new RuntimeException(e);
188 private void showRuntimeLibraryExceptionDialog(String title, String message) {
189 if (!mShownNotFoundDialog) {
190 AlertDialog.Builder builder = new AlertDialog.Builder(this);
191 if (!ReflectionHelper.shouldUseLibrary()) {
192 builder.setPositiveButton(android.R.string.ok,
193 new DialogInterface.OnClickListener() {
194 public void onClick(DialogInterface dialog, int id) {
199 builder.setNegativeButton(android.R.string.cancel,
200 new DialogInterface.OnClickListener() {
201 public void onClick(DialogInterface dialog, int id) {
202 // User cancelled the dialog
205 final String downloadUrl = getLibraryApkDownloadUrl();
206 if (downloadUrl != null && downloadUrl.length() > 0) {
207 builder.setNeutralButton(getString("download_from_url"),
208 new DialogInterface.OnClickListener() {
209 public void onClick(DialogInterface dialog, int id) {
210 Intent goDownload = new Intent(Intent.ACTION_VIEW);
211 goDownload.setData(Uri.parse(downloadUrl));
212 startActivity(goDownload);
216 builder.setPositiveButton(getString("download_from_store"),
217 new DialogInterface.OnClickListener() {
218 public void onClick(DialogInterface dialog, int id) {
219 Intent goToMarket = new Intent(Intent.ACTION_VIEW);
220 goToMarket.setData(Uri.parse(
221 "market://details?id=org.xwalk.core"));
222 startActivity(goToMarket);
226 builder.setTitle(title).setMessage(message);
228 mLibraryNotFoundDialog = builder.create();
229 mLibraryNotFoundDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
231 public void onCancel(DialogInterface dialog) {
232 mLibraryNotFoundDialog = null;
235 mLibraryNotFoundDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
237 public void onDismiss(DialogInterface dialog) {
238 mLibraryNotFoundDialog = null;
241 mLibraryNotFoundDialog.show();
242 mShownNotFoundDialog = true;
247 * Called each time trying to load runtime view from library apk.
248 * Descendant should handle both succeeded and failed to load
251 * @param, The RuntimeView loaded, it can be null for failed to load RuntimeView.
253 abstract protected void didTryLoadRuntimeView(View runtimeView);
255 public void setRemoteDebugging(boolean value) {
256 mRemoteDebugging = value;