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.XWalkRuntimeView;
20 import org.xwalk.core.SharedXWalkExceptionHandler;
21 import org.xwalk.core.SharedXWalkView;
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 SharedXWalkView.initialize(this, new SharedXWalkExceptionHandler() {
132 public void onSharedLibraryNotFound() {
133 String title = getString("dialog_title_install_runtime_lib");
134 String message = getString("dialog_message_install_runtime_lib");
135 showRuntimeLibraryExceptionDialog(title, message);
138 if (mUseAnimatableView) {
139 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true);
141 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, false);
143 mRuntimeView = new XWalkRuntimeView(this, this, null);
144 mShownNotFoundDialog = false;
145 if (mLibraryNotFoundDialog != null) mLibraryNotFoundDialog.cancel();
146 if (mRemoteDebugging) {
147 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
149 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
151 // XWalkPreferences.ENABLE_EXTENSIONS
152 if (XWalkPreferences.getValue("enable-extensions")) {
153 // Enable xwalk extension mechanism and start load extensions here.
154 // Note that it has to be after above initialization.
155 mExtensionManager = new XWalkRuntimeExtensionManager(getApplicationContext(), this);
156 mExtensionManager.loadExtensions();
158 } catch (Exception e) {
161 didTryLoadRuntimeView(mRuntimeView);
164 public XWalkRuntimeView getRuntimeView() {
168 public void handleException(Throwable e) {
169 if (e == null) return;
170 if (e instanceof RuntimeException && e.getCause() != null) {
171 handleException(e.getCause());
174 throw new RuntimeException(e);
177 private void showRuntimeLibraryExceptionDialog(String title, String message) {
178 if (!mShownNotFoundDialog) {
179 AlertDialog.Builder builder = new AlertDialog.Builder(this);
180 if (!SharedXWalkView.usesLibraryOutOfPackage()) {
181 builder.setPositiveButton(android.R.string.ok,
182 new DialogInterface.OnClickListener() {
183 public void onClick(DialogInterface dialog, int id) {
188 builder.setNegativeButton(android.R.string.cancel,
189 new DialogInterface.OnClickListener() {
190 public void onClick(DialogInterface dialog, int id) {
191 // User cancelled the dialog
194 final String downloadUrl = getLibraryApkDownloadUrl();
195 if (downloadUrl != null && downloadUrl.length() > 0) {
196 builder.setNeutralButton(getString("download_from_url"),
197 new DialogInterface.OnClickListener() {
198 public void onClick(DialogInterface dialog, int id) {
199 Intent goDownload = new Intent(Intent.ACTION_VIEW);
200 goDownload.setData(Uri.parse(downloadUrl));
201 startActivity(goDownload);
205 builder.setPositiveButton(getString("download_from_store"),
206 new DialogInterface.OnClickListener() {
207 public void onClick(DialogInterface dialog, int id) {
208 Intent goToMarket = new Intent(Intent.ACTION_VIEW);
209 goToMarket.setData(Uri.parse(
210 "market://details?id=org.xwalk.core"));
211 startActivity(goToMarket);
215 builder.setTitle(title).setMessage(message);
217 mLibraryNotFoundDialog = builder.create();
218 mLibraryNotFoundDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
220 public void onCancel(DialogInterface dialog) {
221 mLibraryNotFoundDialog = null;
224 mLibraryNotFoundDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
226 public void onDismiss(DialogInterface dialog) {
227 mLibraryNotFoundDialog = null;
230 mLibraryNotFoundDialog.show();
231 mShownNotFoundDialog = true;
236 * Called each time trying to load runtime view from library apk.
237 * Descendant should handle both succeeded and failed to load
240 * @param, The RuntimeView loaded, it can be null for failed to load RuntimeView.
242 abstract protected void didTryLoadRuntimeView(View runtimeView);
244 public void setRemoteDebugging(boolean value) {
245 mRemoteDebugging = value;
248 public void setUseAnimatableView(boolean value) {
249 mUseAnimatableView = value;