Upstream version 10.38.208.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.util.Log;
17 import android.view.View;
18
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;
24
25 public abstract class XWalkRuntimeActivityBase extends Activity {
26
27     private static final String DEFAULT_LIBRARY_APK_URL = null;
28
29     private static final String TAG = "XWalkRuntimeActivityBase";
30
31     private XWalkRuntimeView mRuntimeView;
32
33     private boolean mShownNotFoundDialog = false;
34
35     private BroadcastReceiver mReceiver;
36
37     private boolean mRemoteDebugging = false;
38
39     private boolean mUseAnimatableView = false;
40
41     private AlertDialog mLibraryNotFoundDialog = null;
42
43     private XWalkRuntimeExtensionManager mExtensionManager;
44
45     @Override
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() {
51             @Override
52             public void onReceive(Context context, Intent intent) {
53                 Bundle bundle = intent.getExtras();
54                 if (bundle == null)
55                     return;
56
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);
63                     }
64                 }
65             }
66         };
67         registerReceiver(mReceiver, intentFilter);
68         super.onCreate(savedInstanceState);
69         tryLoadRuntimeView();
70         if (mRuntimeView != null) mRuntimeView.onCreate();
71     }
72
73     @Override
74     public void onStart() {
75         super.onStart();
76         if (mExtensionManager != null) mExtensionManager.onStart();
77     }
78
79     @Override
80     public void onPause() {
81         super.onPause();
82         if (mRuntimeView != null) mRuntimeView.onPause();
83         if (mExtensionManager != null) mExtensionManager.onPause();
84     }
85
86     @Override
87     public void onResume() {
88         super.onResume();
89         if (mRuntimeView != null) mRuntimeView.onResume();
90         if (mExtensionManager != null) mExtensionManager.onResume();
91     }
92
93     @Override
94     public void onStop() {
95         super.onStop();
96         if (mExtensionManager != null) mExtensionManager.onStop();
97     }
98
99     @Override
100     public void onDestroy() {
101         unregisterReceiver(mReceiver);
102         if (mExtensionManager != null) mExtensionManager.onDestroy();
103         super.onDestroy();
104     }
105
106     @Override
107     public void onNewIntent(Intent intent) {
108         if (mRuntimeView == null || !mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
109         if (mExtensionManager != null) mExtensionManager.onNewIntent(intent);
110     }
111
112     @Override
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);
117     }
118
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);
123     }
124
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);
129     }
130
131     private void tryLoadRuntimeView() {
132         try {
133             SharedXWalkView.initialize(this, new SharedXWalkExceptionHandler() {
134                 @Override
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);
139                 }
140             });
141             if (mUseAnimatableView) {
142                 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true);
143             } else {
144                 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, false);
145             }
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);
151             } else {
152                 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
153             }
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();
160             }
161         } catch (Exception e) {
162             handleException(e);
163         }
164         didTryLoadRuntimeView(mRuntimeView);
165     }
166
167     public XWalkRuntimeView getRuntimeView() {
168         return mRuntimeView;
169     }
170
171     public void handleException(Throwable e) {
172         if (e == null) return;
173         if (e instanceof RuntimeException && e.getCause() != null) {
174             handleException(e.getCause());
175             return;
176         }
177         Log.e(TAG, Log.getStackTraceString(e));
178     }
179
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) {
187                                 finish();
188                             }
189                         });
190             } else {
191                 builder.setNegativeButton(android.R.string.cancel,
192                         new DialogInterface.OnClickListener() {
193                             public void onClick(DialogInterface dialog, int id) {
194                                 // User cancelled the dialog
195                             }
196                         });
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);
205                                 }
206                             });
207                 }
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);
215                             }
216                         });
217             }
218             builder.setTitle(title).setMessage(message);
219
220             mLibraryNotFoundDialog = builder.create();
221             mLibraryNotFoundDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
222                 @Override
223                 public void onCancel(DialogInterface dialog) {
224                     mLibraryNotFoundDialog = null;
225                 }
226             });
227             mLibraryNotFoundDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
228                 @Override
229                 public void onDismiss(DialogInterface dialog) {
230                     mLibraryNotFoundDialog = null;
231                 }
232             });
233             mLibraryNotFoundDialog.show();
234             mShownNotFoundDialog = true;
235         }
236     }
237
238     /*
239      * Called each time trying to load runtime view from library apk.
240      * Descendant should handle both succeeded and failed to load
241      * library apk.
242      *
243      * @param, The RuntimeView loaded, it can be null for failed to load RuntimeView.
244      */
245     abstract protected void didTryLoadRuntimeView(View runtimeView);
246
247     public void setRemoteDebugging(boolean value) {
248         mRemoteDebugging = value;
249     }
250
251     public void setUseAnimatableView(boolean value) {
252         mUseAnimatableView = value;
253     }
254
255 }