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 boolean mUseAnimatableView = false;
38 private AlertDialog mLibraryNotFoundDialog = null;
40 private XWalkRuntimeExtensionManager mExtensionManager;
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() {
49 public void onReceive(Context context, Intent intent) {
50 Bundle bundle = intent.getExtras();
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);
64 registerReceiver(mReceiver, intentFilter);
65 super.onCreate(savedInstanceState);
67 if (mRuntimeView != null) mRuntimeView.onCreate();
71 public void onStart() {
73 if (mExtensionManager != null) mExtensionManager.onStart();
77 public void onPause() {
79 if (mRuntimeView != null) mRuntimeView.onPause();
80 if (mExtensionManager != null) mExtensionManager.onPause();
84 public void onResume() {
86 if (mRuntimeView != null) mRuntimeView.onResume();
87 if (mExtensionManager != null) mExtensionManager.onResume();
91 public void onStop() {
93 if (mExtensionManager != null) mExtensionManager.onStop();
97 public void onDestroy() {
98 unregisterReceiver(mReceiver);
99 if (mExtensionManager != null) mExtensionManager.onDestroy();
104 public void onNewIntent(Intent intent) {
105 if (mRuntimeView == null || !mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
106 if (mExtensionManager != null) mExtensionManager.onNewIntent(intent);
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);
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);
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);
128 private void tryLoadRuntimeView() {
130 if (mUseAnimatableView) {
131 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true);
133 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, false);
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);
141 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
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();
150 } catch (Exception e) {
153 didTryLoadRuntimeView(mRuntimeView);
156 public XWalkRuntimeView getRuntimeView() {
160 public void handleException(Throwable e) {
161 if (e instanceof RuntimeException) {
162 handleException(e.getCause());
166 if (e instanceof XWalkRuntimeLibraryException) {
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");
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");
179 case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_INSTALLED:
180 title = getString("dialog_title_install_runtime_lib");
181 message = getString("dialog_message_install_runtime_lib");
183 case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_INVOKE_FAILED:
185 Exception originException = runtimeException.getOriginException();
186 if (originException != null) handleException(originException);
189 showRuntimeLibraryExceptionDialog(title, message);
192 throw new RuntimeException(e);
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) {
207 builder.setNegativeButton(android.R.string.cancel,
208 new DialogInterface.OnClickListener() {
209 public void onClick(DialogInterface dialog, int id) {
210 // User cancelled the dialog
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);
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);
234 builder.setTitle(title).setMessage(message);
236 mLibraryNotFoundDialog = builder.create();
237 mLibraryNotFoundDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
239 public void onCancel(DialogInterface dialog) {
240 mLibraryNotFoundDialog = null;
243 mLibraryNotFoundDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
245 public void onDismiss(DialogInterface dialog) {
246 mLibraryNotFoundDialog = null;
249 mLibraryNotFoundDialog.show();
250 mShownNotFoundDialog = true;
255 * Called each time trying to load runtime view from library apk.
256 * Descendant should handle both succeeded and failed to load
259 * @param, The RuntimeView loaded, it can be null for failed to load RuntimeView.
261 abstract protected void didTryLoadRuntimeView(View runtimeView);
263 public void setRemoteDebugging(boolean value) {
264 mRemoteDebugging = value;
267 public void setUseAnimatableView(boolean value) {
268 mUseAnimatableView = value;