117427eef8eb7b22f03937c8ac1dd60882968c6a
[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.XWalkRuntimeView;
20 import org.xwalk.core.SharedXWalkExceptionHandler;
21 import org.xwalk.core.SharedXWalkView;
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 boolean mUseAnimatableView = false;
37
38     private AlertDialog mLibraryNotFoundDialog = null;
39
40     private XWalkRuntimeExtensionManager mExtensionManager;
41
42     @Override
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() {
48             @Override
49             public void onReceive(Context context, Intent intent) {
50                 Bundle bundle = intent.getExtras();
51                 if (bundle == null)
52                     return;
53
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);
60                     }
61                 }
62             }
63         };
64         registerReceiver(mReceiver, intentFilter);
65         super.onCreate(savedInstanceState);
66         tryLoadRuntimeView();
67         if (mRuntimeView != null) mRuntimeView.onCreate();
68     }
69
70     @Override
71     public void onStart() {
72         super.onStart();
73         if (mExtensionManager != null) mExtensionManager.onStart();
74     }
75
76     @Override
77     public void onPause() {
78         super.onPause();
79         if (mRuntimeView != null) mRuntimeView.onPause();
80         if (mExtensionManager != null) mExtensionManager.onPause();
81     }
82
83     @Override
84     public void onResume() {
85         super.onResume();
86         if (mRuntimeView != null) mRuntimeView.onResume();
87         if (mExtensionManager != null) mExtensionManager.onResume();
88     }
89
90     @Override
91     public void onStop() {
92         super.onStop();
93         if (mExtensionManager != null) mExtensionManager.onStop();
94     }
95
96     @Override
97     public void onDestroy() {
98         unregisterReceiver(mReceiver);
99         if (mExtensionManager != null) mExtensionManager.onDestroy();
100         super.onDestroy();
101     }
102
103     @Override
104     public void onNewIntent(Intent intent) {
105         if (mRuntimeView == null || !mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
106         if (mExtensionManager != null) mExtensionManager.onNewIntent(intent);
107     }
108
109     @Override
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);
114     }
115
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);
120     }
121
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);
126     }
127
128     private void tryLoadRuntimeView() {
129         try {
130             SharedXWalkView.initialize(this, new SharedXWalkExceptionHandler() {
131                 @Override
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);
136                 }
137             });
138             if (mUseAnimatableView) {
139                 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true);
140             } else {
141                 XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, false);
142             }
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);
148             } else {
149                 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
150             }
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();
157             }
158         } catch (Exception e) {
159             handleException(e);
160         }
161         didTryLoadRuntimeView(mRuntimeView);
162     }
163
164     public XWalkRuntimeView getRuntimeView() {
165         return mRuntimeView;
166     }
167
168     public void handleException(Throwable e) {
169         if (e == null) return;
170         if (e instanceof RuntimeException && e.getCause() != null) {
171             handleException(e.getCause());
172             return;
173         }
174         throw new RuntimeException(e);
175     }
176
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) {
184                                 finish();
185                             }
186                         });
187             } else {
188                 builder.setNegativeButton(android.R.string.cancel,
189                         new DialogInterface.OnClickListener() {
190                             public void onClick(DialogInterface dialog, int id) {
191                                 // User cancelled the dialog
192                             }
193                         });
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);
202                                 }
203                             });
204                 }
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);
212                             }
213                         });
214             }
215             builder.setTitle(title).setMessage(message);
216
217             mLibraryNotFoundDialog = builder.create();
218             mLibraryNotFoundDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
219                 @Override
220                 public void onCancel(DialogInterface dialog) {
221                     mLibraryNotFoundDialog = null;
222                 }
223             });
224             mLibraryNotFoundDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
225                 @Override
226                 public void onDismiss(DialogInterface dialog) {
227                     mLibraryNotFoundDialog = null;
228                 }
229             });
230             mLibraryNotFoundDialog.show();
231             mShownNotFoundDialog = true;
232         }
233     }
234
235     /*
236      * Called each time trying to load runtime view from library apk.
237      * Descendant should handle both succeeded and failed to load
238      * library apk.
239      *
240      * @param, The RuntimeView loaded, it can be null for failed to load RuntimeView.
241      */
242     abstract protected void didTryLoadRuntimeView(View runtimeView);
243
244     public void setRemoteDebugging(boolean value) {
245         mRemoteDebugging = value;
246     }
247
248     public void setUseAnimatableView(boolean value) {
249         mUseAnimatableView = value;
250     }
251
252 }