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.util.Log;
17 import android.view.View;
19 import org.xwalk.app.runtime.extension.XWalkRuntimeExtensionManager;
20 import org.xwalk.app.runtime.XWalkRuntimeView;
21 import org.xwalk.core.SharedXWalkExceptionHandler;
22 import org.xwalk.core.SharedXWalkView;
23 import org.xwalk.core.XWalkPreferences;
25 public abstract class XWalkRuntimeActivityBase extends Activity {
27 private static final String DEFAULT_LIBRARY_APK_URL = null;
29 private static final String TAG = "XWalkRuntimeActivityBase";
31 private XWalkRuntimeView mRuntimeView;
33 private boolean mShownNotFoundDialog = false;
35 private BroadcastReceiver mReceiver;
37 private boolean mRemoteDebugging = false;
39 private boolean mUseAnimatableView = false;
41 private AlertDialog mLibraryNotFoundDialog = null;
43 private XWalkRuntimeExtensionManager mExtensionManager;
46 public void onCreate(Bundle savedInstanceState) {
47 IntentFilter intentFilter = new IntentFilter("org.xwalk.intent");
48 intentFilter.addAction("android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE");
49 intentFilter.addAction("android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE");
50 mReceiver = new BroadcastReceiver() {
52 public void onReceive(Context context, Intent intent) {
53 Bundle bundle = intent.getExtras();
57 if (bundle.containsKey("remotedebugging")) {
58 String extra = bundle.getString("remotedebugging");
59 if (extra.equals("true")) {
60 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
61 } else if (extra.equals("false")) {
62 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
67 registerReceiver(mReceiver, intentFilter);
68 super.onCreate(savedInstanceState);
70 if (mRuntimeView != null) mRuntimeView.onCreate();
74 public void onStart() {
76 if (mExtensionManager != null) mExtensionManager.onStart();
80 public void onPause() {
82 if (mRuntimeView != null) mRuntimeView.onPause();
83 if (mExtensionManager != null) mExtensionManager.onPause();
87 public void onResume() {
89 if (mRuntimeView != null) mRuntimeView.onResume();
90 if (mExtensionManager != null) mExtensionManager.onResume();
94 public void onStop() {
96 if (mExtensionManager != null) mExtensionManager.onStop();
100 public void onDestroy() {
101 unregisterReceiver(mReceiver);
102 if (mExtensionManager != null) mExtensionManager.onDestroy();
107 public void onNewIntent(Intent intent) {
108 if (mRuntimeView == null || !mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
109 if (mExtensionManager != null) mExtensionManager.onNewIntent(intent);
113 public void onActivityResult(int requestCode, int resultCode, Intent data) {
114 super.onActivityResult(requestCode, resultCode, data);
115 if (mRuntimeView != null) mRuntimeView.onActivityResult(requestCode, resultCode, data);
116 if (mExtensionManager != null) mExtensionManager.onActivityResult(requestCode, resultCode, data);
119 private String getLibraryApkDownloadUrl() {
120 int resId = getResources().getIdentifier("xwalk_library_apk_download_url", "string", getPackageName());
121 if (resId == 0) return DEFAULT_LIBRARY_APK_URL;
122 return getString(resId);
125 public String getString(String label) {
126 int resId = getResources().getIdentifier(label, "string", getPackageName());
127 if (resId == 0) return label.replace('_', ' ');
128 return getString(resId);
131 private void tryLoadRuntimeView() {
133 SharedXWalkView.initialize(this, new SharedXWalkExceptionHandler() {
135 public void onSharedLibraryNotFound() {
136 String title = getString("dialog_title_install_runtime_lib");
137 String message = getString("dialog_message_install_runtime_lib");
138 showRuntimeLibraryExceptionDialog(title, message);
141 if (mUseAnimatableView) {
142 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true);
144 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, false);
146 mShownNotFoundDialog = false;
147 if (mLibraryNotFoundDialog != null) mLibraryNotFoundDialog.cancel();
148 mRuntimeView = new XWalkRuntimeView(this, this, null);
149 if (mRemoteDebugging) {
150 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
152 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
154 // XWalkPreferences.ENABLE_EXTENSIONS
155 if (XWalkPreferences.getValue("enable-extensions")) {
156 // Enable xwalk extension mechanism and start load extensions here.
157 // Note that it has to be after above initialization.
158 mExtensionManager = new XWalkRuntimeExtensionManager(getApplicationContext(), this);
159 mExtensionManager.loadExtensions();
161 } catch (Exception e) {
164 didTryLoadRuntimeView(mRuntimeView);
167 public XWalkRuntimeView getRuntimeView() {
171 public void handleException(Throwable e) {
172 if (e == null) return;
173 if (e instanceof RuntimeException && e.getCause() != null) {
174 handleException(e.getCause());
177 Log.e(TAG, Log.getStackTraceString(e));
180 private void showRuntimeLibraryExceptionDialog(String title, String message) {
181 if (!mShownNotFoundDialog) {
182 AlertDialog.Builder builder = new AlertDialog.Builder(this);
183 if (!SharedXWalkView.usesLibraryOutOfPackage()) {
184 builder.setPositiveButton(android.R.string.ok,
185 new DialogInterface.OnClickListener() {
186 public void onClick(DialogInterface dialog, int id) {
191 builder.setNegativeButton(android.R.string.cancel,
192 new DialogInterface.OnClickListener() {
193 public void onClick(DialogInterface dialog, int id) {
194 // User cancelled the dialog
197 final String downloadUrl = getLibraryApkDownloadUrl();
198 if (downloadUrl != null && downloadUrl.length() > 0) {
199 builder.setNeutralButton(getString("download_from_url"),
200 new DialogInterface.OnClickListener() {
201 public void onClick(DialogInterface dialog, int id) {
202 Intent goDownload = new Intent(Intent.ACTION_VIEW);
203 goDownload.setData(Uri.parse(downloadUrl));
204 startActivity(goDownload);
208 builder.setPositiveButton(getString("download_from_store"),
209 new DialogInterface.OnClickListener() {
210 public void onClick(DialogInterface dialog, int id) {
211 Intent goToMarket = new Intent(Intent.ACTION_VIEW);
212 goToMarket.setData(Uri.parse(
213 "market://details?id=org.xwalk.core"));
214 startActivity(goToMarket);
218 builder.setTitle(title).setMessage(message);
220 mLibraryNotFoundDialog = builder.create();
221 mLibraryNotFoundDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
223 public void onCancel(DialogInterface dialog) {
224 mLibraryNotFoundDialog = null;
227 mLibraryNotFoundDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
229 public void onDismiss(DialogInterface dialog) {
230 mLibraryNotFoundDialog = null;
233 mLibraryNotFoundDialog.show();
234 mShownNotFoundDialog = true;
239 * Called each time trying to load runtime view from library apk.
240 * Descendant should handle both succeeded and failed to load
243 * @param, The RuntimeView loaded, it can be null for failed to load RuntimeView.
245 abstract protected void didTryLoadRuntimeView(View runtimeView);
247 public void setRemoteDebugging(boolean value) {
248 mRemoteDebugging = value;
251 public void setUseAnimatableView(boolean value) {
252 mUseAnimatableView = value;