• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.browser;
18 
19 import android.app.Activity;
20 import android.app.Dialog;
21 import android.content.Intent;
22 import android.net.Uri;
23 import android.os.Bundle;
24 import android.os.Handler;
25 import android.os.Message;
26 import android.util.Log;
27 import android.view.Gravity;
28 import android.view.KeyEvent;
29 import android.view.Window;
30 import android.widget.BaseAdapter;
31 import android.widget.Toast;
32 
33 import android.webkit.gears.NativeDialog;
34 
35 import com.android.browser.GearsBaseDialog;
36 import com.android.browser.GearsPermissionsDialog;
37 import com.android.browser.GearsSettingsDialog;
38 
39 /**
40  * Native dialog Activity used by gears
41  * TODO: rename in GearsNativeDialogActivity
42  * @hide
43  */
44 public class GearsNativeDialog extends Activity {
45 
46   private static final String TAG = "GearsNativeDialog";
47 
48   private String mDialogArguments;
49 
50   private String mGearsVersion = null;
51 
52   private boolean mDebug = false;
53 
54   private int mDialogType;
55   private final int SETTINGS_DIALOG = 1;
56   private final int PERMISSION_DIALOG = 2;
57   private final int LOCATION_DIALOG = 3;
58 
59   private final String VERSION_STRING = "version";
60   private final String SETTINGS_DIALOG_STRING = "settings_dialog";
61   private final String PERMISSION_DIALOG_STRING = "permissions_dialog";
62   private final String LOCATION_DIALOG_STRING = "locations_dialog";
63 
64   private boolean mDialogDismissed = false;
65 
66   GearsBaseDialog dialog;
67 
68   // Handler for callbacks to the UI thread
69   final Handler mHandler = new Handler() {
70     public void handleMessage(Message msg) {
71       if (msg.what == GearsBaseDialog.NEW_ICON) {
72         BaseAdapter adapter = (BaseAdapter) msg.obj;
73         adapter.notifyDataSetChanged();
74       } else if (msg.what == GearsBaseDialog.UPDATE_ICON) {
75         dialog.updateIcon();
76       } else if (msg.what == GearsBaseDialog.ALWAYS_DENY) {
77         closeDialog(GearsBaseDialog.ALWAYS_DENY);
78       } else if (msg.what == GearsBaseDialog.ALLOW) {
79         closeDialog(GearsBaseDialog.ALLOW);
80       } else if (msg.what == GearsBaseDialog.DENY) {
81         closeDialog(GearsBaseDialog.DENY);
82       }
83       super.handleMessage(msg);
84     }
85   };
86 
87   @Override
onCreate(Bundle icicle)88   public void onCreate(Bundle icicle) {
89     getArguments();
90     if (mDialogType == SETTINGS_DIALOG) {
91       setTheme(android.R.style.Theme);
92     }
93     super.onCreate(icicle);
94     if (mDialogType != SETTINGS_DIALOG) {
95       requestWindowFeature(Window.FEATURE_NO_TITLE);
96       setContentView(R.layout.gears_dialog);
97     }
98 
99     switch (mDialogType) {
100       case SETTINGS_DIALOG:
101         dialog = new GearsSettingsDialog(this, mHandler, mDialogArguments);
102         dialog.setGearsVersion(mGearsVersion);
103         break;
104       case PERMISSION_DIALOG:
105         dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
106         break;
107       case LOCATION_DIALOG:
108         dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
109         break;
110       default:
111         dialog = new GearsBaseDialog(this, mHandler, mDialogArguments);
112     }
113     dialog.setDebug(mDebug);
114     dialog.setup();
115   }
116 
117   /**
118    * Get the arguments for the dialog
119    *
120    * The dialog needs a json string as an argument, as
121    * well as a dialogType. In debug mode the arguments
122    * are mocked.
123    */
getArguments()124   private void getArguments() {
125     if (mDebug) {
126       mDialogType = LOCATION_DIALOG +1;
127       mockArguments();
128 
129       return;
130     }
131 
132     Intent intent = getIntent();
133     mDialogArguments = intent.getStringExtra("dialogArguments");
134     String dialogTypeString = intent.getStringExtra("dialogType");
135     if (dialogTypeString == null) {
136       return;
137     }
138 
139     if (Browser.LOGV_ENABLED) {
140       Log.v(TAG, "dialogtype: " + dialogTypeString);
141     }
142 
143     if (dialogTypeString.equalsIgnoreCase(SETTINGS_DIALOG_STRING)) {
144       mDialogType = SETTINGS_DIALOG;
145       mGearsVersion = intent.getStringExtra(VERSION_STRING);
146     } else if (dialogTypeString.equalsIgnoreCase(PERMISSION_DIALOG_STRING)) {
147       mDialogType = PERMISSION_DIALOG;
148     } else if (dialogTypeString.equalsIgnoreCase(LOCATION_DIALOG_STRING)) {
149       mDialogType = LOCATION_DIALOG;
150     }
151   }
152 
153   /**
154    * Utility method for debugging the dialog.
155    *
156    * Set mock arguments.
157    */
mockArguments()158   private void mockArguments() {
159 
160     String argumentsPermissions = "{ locale: \"en-US\", "
161         + "origin: \"http://www.google.com\", dialogType: \"localData\","
162         + "customIcon: \"http://google-gears.googlecode.com/"
163         + "svn/trunk/gears/test/manual/shortcuts/32.png\","
164         + "customName: \"My Application\","
165         + "customMessage: \"Press the button to enable my "
166         + "application to run offline!\" };";
167 
168     String argumentsPermissions2 = "{ locale: \"en-US\", "
169         + "origin: \"http://www.google.com\", dialogType: \"localData\" };";
170 
171     String argumentsLocation = "{ locale: \"en-US\", "
172         + "origin: \"http://www.google.com\", dialogType: \"locationData\","
173         + "customIcon: \"http://google-gears.googlecode.com/"
174         + "svn/trunk/gears/test/manual/shortcuts/32.png\","
175         + "customName: \"My Application\","
176         + "customMessage: \"Press the button to enable my "
177         + "application to run offline!\" };";
178 
179     String argumentsSettings = "{ locale: \"en-US\", permissions: [ { "
180         + "name: \"http://www.google.com\", "
181         + "localStorage: { permissionState: 0 }, "
182         + "locationData: { permissionState: 1 } }, "
183         + "{ name: \"http://www.aaronboodman.com\", "
184         + "localStorage: { permissionState: 1 }, "
185         + "locationData: { permissionState: 2 } }, "
186         + "{ name: \"http://www.evil.org\", "
187         + "localStorage: { permissionState: 2 }, "
188         + "locationData: { permissionState: 2 } } ] }";
189 
190     switch (mDialogType) {
191       case PERMISSION_DIALOG:
192         mDialogArguments = argumentsPermissions;
193         break;
194       case LOCATION_DIALOG:
195         mDialogArguments = argumentsLocation;
196         break;
197       case SETTINGS_DIALOG:
198         mDialogArguments = argumentsSettings;
199         break;
200     }
201   }
202 
203   /**
204    * Close the dialog and set the return string value.
205    */
closeDialog(int closingType)206   private void closeDialog(int closingType) {
207     String ret = dialog.closeDialog(closingType);
208 
209     if (mDebug) {
210       Log.v(TAG, "closeDialog ret value: " + ret);
211     }
212 
213     NativeDialog.closeDialog(ret);
214     notifyEndOfDialog();
215     finish();
216 
217     // If the dialog sets a notification, we display it.
218     int notification = dialog.notification();
219     if (notification != 0) {
220       Toast toast = Toast.makeText(this, notification, Toast.LENGTH_LONG);
221       toast.setGravity(Gravity.BOTTOM, 0, 0);
222       toast.show();
223     }
224   }
225 
226   @Override
onDestroy()227   public void onDestroy() {
228     super.onDestroy();
229     // In case we reach this point without
230     // notifying NativeDialog, we do it now.
231     if (!mDialogDismissed) {
232       notifyEndOfDialog();
233     }
234   }
235 
236   @Override
onPause()237   public void onPause(){
238     super.onPause();
239     if (!mDialogDismissed) {
240       closeDialog(GearsBaseDialog.CANCEL);
241     }
242   }
243 
244   /**
245    * Signal to NativeDialog that we are done.
246    */
notifyEndOfDialog()247   private void notifyEndOfDialog() {
248     NativeDialog.signalFinishedDialog();
249     mDialogDismissed = true;
250   }
251 
252   /**
253    * Intercepts the back key to immediately notify
254    * NativeDialog that we are done.
255    */
dispatchKeyEvent(KeyEvent event)256   public boolean dispatchKeyEvent(KeyEvent event) {
257     if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK)
258       && (event.getAction() == KeyEvent.ACTION_DOWN)) {
259       if (!dialog.handleBackButton()) {
260         // if the dialog doesn't do anything with the back button
261         closeDialog(GearsBaseDialog.CANCEL);
262       }
263       return true; // event consumed
264     }
265     return super.dispatchKeyEvent(event);
266   }
267 
268   /**
269    * If the dialog call showDialog() on ourself, we let
270    * it handle the creation of this secondary dialog.
271    * It is used in GearsSettingsDialog, to create the confirmation
272    * dialog when the user click on "Remove this site from Gears"
273    */
274   @Override
onCreateDialog(int id)275   protected Dialog onCreateDialog(int id) {
276     return dialog.onCreateDialog(id);
277   }
278 
279 }
280