Upstream version 9.38.204.0
[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 AlertDialog mLibraryNotFoundDialog = null;
37
38     private XWalkRuntimeExtensionManager mExtensionManager;
39
40     @Override
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() {
46             @Override
47             public void onReceive(Context context, Intent intent) {
48                 Bundle bundle = intent.getExtras();
49                 if (bundle == null)
50                     return;
51
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);
58                     }
59                 }
60             }
61         };
62         registerReceiver(mReceiver, intentFilter);
63         super.onCreate(savedInstanceState);
64         tryLoadRuntimeView();
65         if (mRuntimeView != null) mRuntimeView.onCreate();
66     }
67
68     @Override
69     public void onStart() {
70         super.onStart();
71         if (mExtensionManager != null) mExtensionManager.onStart();
72     }
73
74     @Override
75     public void onPause() {
76         super.onPause();
77         if (mRuntimeView != null) mRuntimeView.onPause();
78         if (mExtensionManager != null) mExtensionManager.onPause();
79     }
80
81     @Override
82     public void onResume() {
83         super.onResume();
84         if (mRuntimeView != null) mRuntimeView.onResume();
85         if (mExtensionManager != null) mExtensionManager.onResume();
86     }
87
88     @Override
89     public void onStop() {
90         super.onStop();
91         if (mExtensionManager != null) mExtensionManager.onStop();
92     }
93
94     @Override
95     public void onDestroy() {
96         unregisterReceiver(mReceiver);
97         if (mExtensionManager != null) mExtensionManager.onDestroy();
98         super.onDestroy();
99     }
100
101     @Override
102     public void onNewIntent(Intent intent) {
103         if (mRuntimeView == null || !mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
104     }
105
106     @Override
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);
111     }
112
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);
117     }
118
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);
123     }
124
125     private void tryLoadRuntimeView() {
126         try {
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);
132             } else {
133                 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
134             }
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();
141             }
142         } catch (Exception e) {
143             handleException(e);
144         }
145         didTryLoadRuntimeView(mRuntimeView);
146     }
147
148     public XWalkRuntimeView getRuntimeView() {
149         return mRuntimeView;
150     }
151
152     public void handleException(Throwable e) {
153         if (e instanceof RuntimeException) {
154             handleException(e.getCause());
155             return;
156         }
157
158         if (e instanceof XWalkRuntimeLibraryException) {
159             String title = "";
160             String message = "";
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");
166                 break;
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");
170                 break;
171             case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_INSTALLED:
172                 title = getString("dialog_title_install_runtime_lib");
173                 message = getString("dialog_message_install_runtime_lib");
174                 break;
175             case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_INVOKE_FAILED:
176             default:
177                 Exception originException = runtimeException.getOriginException();
178                 if (originException != null) handleException(originException);
179                 return;
180             }
181             showRuntimeLibraryExceptionDialog(title, message);
182         } else {
183             e.printStackTrace();
184             throw new RuntimeException(e);
185         }
186     }
187
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) {
195                                 finish();
196                             }
197                         });
198             } else {
199                 builder.setNegativeButton(android.R.string.cancel,
200                         new DialogInterface.OnClickListener() {
201                             public void onClick(DialogInterface dialog, int id) {
202                                 // User cancelled the dialog
203                             }
204                         });
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);
213                                 }
214                             });
215                 }
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);
223                             }
224                         });
225             }
226             builder.setTitle(title).setMessage(message);
227
228             mLibraryNotFoundDialog = builder.create();
229             mLibraryNotFoundDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
230                 @Override
231                 public void onCancel(DialogInterface dialog) {
232                     mLibraryNotFoundDialog = null;
233                 }
234             });
235             mLibraryNotFoundDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
236                 @Override
237                 public void onDismiss(DialogInterface dialog) {
238                     mLibraryNotFoundDialog = null;
239                 }
240             });
241             mLibraryNotFoundDialog.show();
242             mShownNotFoundDialog = true;
243         }
244     }
245
246     /*
247      * Called each time trying to load runtime view from library apk.
248      * Descendant should handle both succeeded and failed to load
249      * library apk.
250      *
251      * @param, The RuntimeView loaded, it can be null for failed to load RuntimeView.
252      */
253     abstract protected void didTryLoadRuntimeView(View runtimeView);
254
255     public void setRemoteDebugging(boolean value) {
256         mRemoteDebugging = value;
257     }
258
259 }