summaryrefslogtreecommitdiffstats
path: root/core/java/android/webkit/gears
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:43 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:43 -0800
commitf013e1afd1e68af5e3b868c26a653bbfb39538f8 (patch)
tree7ad6c8fd9c7b55f4b4017171dec1cb760bbd26bf /core/java/android/webkit/gears
parente70cfafe580c6f2994c4827cd8a534aabf3eb05c (diff)
downloadframeworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.zip
frameworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.tar.gz
frameworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'core/java/android/webkit/gears')
-rw-r--r--core/java/android/webkit/gears/AndroidWifiDataProvider.java136
-rw-r--r--core/java/android/webkit/gears/DesktopAndroid.java6
-rw-r--r--core/java/android/webkit/gears/HttpRequestAndroid.java29
-rw-r--r--core/java/android/webkit/gears/NativeDialog.java142
-rw-r--r--core/java/android/webkit/gears/PluginSettings.java79
-rw-r--r--core/java/android/webkit/gears/UrlInterceptHandlerGears.java10
6 files changed, 387 insertions, 15 deletions
diff --git a/core/java/android/webkit/gears/AndroidWifiDataProvider.java b/core/java/android/webkit/gears/AndroidWifiDataProvider.java
new file mode 100644
index 0000000..7379f59
--- /dev/null
+++ b/core/java/android/webkit/gears/AndroidWifiDataProvider.java
@@ -0,0 +1,136 @@
+// Copyright 2008, Google Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// 3. Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package android.webkit.gears;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Config;
+import android.util.Log;
+import android.webkit.WebView;
+import java.util.List;
+
+/**
+ * WiFi data provider implementation for Android.
+ * {@hide}
+ */
+public final class AndroidWifiDataProvider extends BroadcastReceiver {
+ /**
+ * Logging tag
+ */
+ private static final String TAG = "Gears-J-WifiProvider";
+ /**
+ * Our Wifi manager instance.
+ */
+ private WifiManager mWifiManager;
+ /**
+ * The native object ID.
+ */
+ private long mNativeObject;
+ /**
+ * The Context instance.
+ */
+ private Context mContext;
+
+ /**
+ * Constructs a instance of this class and registers for wifi scan
+ * updates. Note that this constructor must be called on a Looper
+ * thread. Suitable threads can be created on the native side using
+ * the AndroidLooperThread C++ class.
+ */
+ public AndroidWifiDataProvider(WebView webview, long object) {
+ mNativeObject = object;
+ mContext = webview.getContext();
+ mWifiManager =
+ (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ if (mWifiManager == null) {
+ Log.e(TAG,
+ "AndroidWifiDataProvider: could not get location manager.");
+ throw new NullPointerException(
+ "AndroidWifiDataProvider: locationManager is null.");
+ }
+
+ // Create a Handler that identifies the message loop associated
+ // with the current thread. Note that it is not necessary to
+ // override handleMessage() at all since the Intent
+ // ReceiverDispatcher (see the ActivityThread class) only uses
+ // this handler to post a Runnable to this thread's loop.
+ Handler handler = new Handler(Looper.myLooper());
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(mWifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+ mContext.registerReceiver(this, filter, null, handler);
+
+ // Get the last scan results and pass them to the native side.
+ // We can't just invoke the callback here, so we queue a message
+ // to this thread's loop.
+ handler.post(new Runnable() {
+ public void run() {
+ onUpdateAvailable(mWifiManager.getScanResults(), mNativeObject);
+ }
+ });
+ }
+
+ /**
+ * Called when the provider is no longer needed.
+ */
+ public void shutdown() {
+ mContext.unregisterReceiver(this);
+ if (Config.LOGV) {
+ Log.v(TAG, "Wifi provider closed.");
+ }
+ }
+
+ /**
+ * This method is called when the AndroidWifiDataProvider is receiving an
+ * Intent broadcast.
+ * @param context The Context in which the receiver is running.
+ * @param intent The Intent being received.
+ */
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(
+ mWifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+ if (Config.LOGV) {
+ Log.v(TAG, "Wifi scan resulst available");
+ }
+ onUpdateAvailable(mWifiManager.getScanResults(), mNativeObject);
+ }
+ }
+
+ /**
+ * The native method called when new wifi data is available.
+ * @param scanResults is a list of ScanResults to pass to the native side.
+ * @param nativeObject is a pointer to the corresponding
+ * AndroidWifiDataProvider C++ instance.
+ */
+ private static native void onUpdateAvailable(
+ List<ScanResult> scanResults, long nativeObject);
+}
diff --git a/core/java/android/webkit/gears/DesktopAndroid.java b/core/java/android/webkit/gears/DesktopAndroid.java
index 00a9a47..ee8ca49 100644
--- a/core/java/android/webkit/gears/DesktopAndroid.java
+++ b/core/java/android/webkit/gears/DesktopAndroid.java
@@ -40,8 +40,6 @@ import android.webkit.WebView;
public class DesktopAndroid {
private static final String TAG = "Gears-J-Desktop";
- private static final String BROWSER = "com.android.browser";
- private static final String BROWSER_ACTIVITY = BROWSER + ".BrowserActivity";
private static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
private static final String ACTION_INSTALL_SHORTCUT =
"com.android.launcher.action.INSTALL_SHORTCUT";
@@ -78,11 +76,9 @@ public class DesktopAndroid {
String url, String imagePath) {
Context context = webview.getContext();
- ComponentName browser = new ComponentName(BROWSER, BROWSER_ACTIVITY);
-
Intent viewWebPage = new Intent(Intent.ACTION_VIEW);
- viewWebPage.setComponent(browser);
viewWebPage.setData(Uri.parse(url));
+ viewWebPage.addCategory(Intent.CATEGORY_BROWSABLE);
Intent intent = new Intent(ACTION_INSTALL_SHORTCUT);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, viewWebPage);
diff --git a/core/java/android/webkit/gears/HttpRequestAndroid.java b/core/java/android/webkit/gears/HttpRequestAndroid.java
index 8668c54..30f855f 100644
--- a/core/java/android/webkit/gears/HttpRequestAndroid.java
+++ b/core/java/android/webkit/gears/HttpRequestAndroid.java
@@ -163,7 +163,20 @@ public final class HttpRequestAndroid {
// Setup the connection. This doesn't go to the wire yet - it
// doesn't block.
try {
- connection = (HttpURLConnection) new URL(url).openConnection();
+ URL url_object = new URL(url);
+ // Check that the protocol is indeed HTTP(S).
+ String protocol = url_object.getProtocol();
+ if (protocol == null) {
+ log("null protocol for URL " + url);
+ return false;
+ }
+ protocol = protocol.toLowerCase();
+ if (!"http".equals(protocol) && !"https".equals(protocol)) {
+ log("Url has wrong protocol: " + url);
+ return false;
+ }
+
+ connection = (HttpURLConnection) url_object.openConnection();
connection.setRequestMethod(method);
// Manually follow redirects.
connection.setInstanceFollowRedirects(false);
@@ -197,11 +210,13 @@ public final class HttpRequestAndroid {
log("interrupt() called but no child thread");
return;
}
- if (inBlockingOperation) {
- log("Interrupting blocking operation");
- childThread.interrupt();
- } else {
- log("Nothing to interrupt");
+ synchronized (this) {
+ if (inBlockingOperation) {
+ log("Interrupting blocking operation");
+ childThread.interrupt();
+ } else {
+ log("Nothing to interrupt");
+ }
}
}
@@ -472,7 +487,7 @@ public final class HttpRequestAndroid {
String encoding = cacheResult.getEncoding();
// Encoding may not be specified. No default.
String contentType = mimeType;
- if (encoding != null) {
+ if (encoding != null && encoding.length() > 0) {
contentType += "; charset=" + encoding;
}
setResponseHeader(KEY_CONTENT_TYPE, contentType);
diff --git a/core/java/android/webkit/gears/NativeDialog.java b/core/java/android/webkit/gears/NativeDialog.java
new file mode 100644
index 0000000..9e2b375
--- /dev/null
+++ b/core/java/android/webkit/gears/NativeDialog.java
@@ -0,0 +1,142 @@
+// Copyright 2008 The Android Open Source Project
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// 3. Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package android.webkit.gears;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import java.io.File;
+import java.lang.InterruptedException;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Utility class to call a modal native dialog on Android
+ * The dialog itself is an Activity defined in the Browser.
+ * @hide
+ */
+public class NativeDialog {
+
+ private static final String TAG = "Gears-J-NativeDialog";
+
+ private final String DIALOG_PACKAGE = "com.android.browser";
+ private final String DIALOG_CLASS = DIALOG_PACKAGE + ".GearsNativeDialog";
+
+ private static Lock mLock = new ReentrantLock();
+ private static Condition mDialogFinished = mLock.newCondition();
+ private static String mResults = null;
+
+ private static boolean mAsynchronousDialog;
+
+ /**
+ * Utility function to build the intent calling the
+ * dialog activity
+ */
+ private Intent createIntent(String type, String arguments) {
+ Intent intent = new Intent();
+ intent.setClassName(DIALOG_PACKAGE, DIALOG_CLASS);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra("dialogArguments", arguments);
+ intent.putExtra("dialogType", type);
+ return intent;
+ }
+
+ /**
+ * Opens a native dialog synchronously and waits for its completion.
+ *
+ * The dialog is an activity (GearsNativeDialog) provided by the Browser
+ * that we call via startActivity(). Contrary to a normal activity though,
+ * we need to block until it returns. To do so, we define a static lock
+ * object in this class, which GearsNativeDialog can unlock once done
+ */
+ public String showDialog(Context context, String file,
+ String arguments) {
+
+ try {
+ mAsynchronousDialog = false;
+ mLock.lock();
+ File path = new File(file);
+ String fileName = path.getName();
+ String type = fileName.substring(0, fileName.indexOf(".html"));
+ Intent intent = createIntent(type, arguments);
+
+ mResults = null;
+ context.startActivity(intent);
+ mDialogFinished.await();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "exception e: " + e);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "exception e: " + e);
+ } finally {
+ mLock.unlock();
+ }
+
+ return mResults;
+ }
+
+ /**
+ * Opens a native dialog asynchronously
+ *
+ * The dialog is an activity (GearsNativeDialog) provided by the
+ * Browser.
+ */
+ public void showAsyncDialog(Context context, String type,
+ String arguments) {
+ mAsynchronousDialog = true;
+ Intent intent = createIntent(type, arguments);
+ context.startActivity(intent);
+ }
+
+ /**
+ * Static method that GearsNativeDialog calls to unlock us
+ */
+ public static void signalFinishedDialog() {
+ if (!mAsynchronousDialog) {
+ mLock.lock();
+ mDialogFinished.signal();
+ mLock.unlock();
+ } else {
+ // we call the native callback
+ closeAsynchronousDialog(mResults);
+ }
+ }
+
+ /**
+ * Static method that GearsNativeDialog calls to set the
+ * dialog's result
+ */
+ public static void closeDialog(String res) {
+ mResults = res;
+ }
+
+ /**
+ * Native callback method
+ */
+ private native static void closeAsynchronousDialog(String res);
+}
diff --git a/core/java/android/webkit/gears/PluginSettings.java b/core/java/android/webkit/gears/PluginSettings.java
new file mode 100644
index 0000000..2d0cc13
--- /dev/null
+++ b/core/java/android/webkit/gears/PluginSettings.java
@@ -0,0 +1,79 @@
+// Copyright 2008 The Android Open Source Project
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// 3. Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package android.webkit.gears;
+
+import android.content.Context;
+import android.util.Log;
+import android.webkit.Plugin;
+import android.webkit.Plugin.PreferencesClickHandler;
+
+/**
+ * Simple bridge class intercepting the click in the
+ * browser plugin list and calling the Gears settings
+ * dialog.
+ */
+public class PluginSettings {
+
+ private static final String TAG = "Gears-J-PluginSettings";
+ private Context mContext;
+
+ public PluginSettings(Plugin plugin) {
+ plugin.setClickHandler(new ClickHandler());
+ }
+
+ /**
+ * We do not call the dialog synchronously here as the main
+ * message loop would be blocked, so we call it via a secondary thread.
+ */
+ private class ClickHandler implements PreferencesClickHandler {
+ public void handleClickEvent(Context context) {
+ mContext = context.getApplicationContext();
+ Thread startDialog = new Thread(new StartDialog(context));
+ startDialog.start();
+ }
+ }
+
+ /**
+ * Simple wrapper class to call the gears native method in
+ * a separate thread (the native code will then instanciate a NativeDialog
+ * object which will start the GearsNativeDialog activity defined in
+ * the Browser).
+ */
+ private class StartDialog implements Runnable {
+ Context mContext;
+
+ public StartDialog(Context context) {
+ mContext = context;
+ }
+
+ public void run() {
+ runSettingsDialog(mContext);
+ }
+ }
+
+ private static native void runSettingsDialog(Context c);
+
+}
diff --git a/core/java/android/webkit/gears/UrlInterceptHandlerGears.java b/core/java/android/webkit/gears/UrlInterceptHandlerGears.java
index 95fc30f..288240e 100644
--- a/core/java/android/webkit/gears/UrlInterceptHandlerGears.java
+++ b/core/java/android/webkit/gears/UrlInterceptHandlerGears.java
@@ -407,6 +407,8 @@ public class UrlInterceptHandlerGears implements UrlInterceptHandler {
true); // forceCache
if (cacheResult == null) {
+ // With the no-cache policy we could end up
+ // with a null result
return null;
}
@@ -444,8 +446,7 @@ public class UrlInterceptHandlerGears implements UrlInterceptHandler {
// be used for input.
cacheResult = CacheManager.getCacheFile(gearsUrl, null);
if (cacheResult != null) {
- if (logEnabled)
- log("Returning surrogate result");
+ log("Returning surrogate result");
return cacheResult;
} else {
// Not an expected condition, but handle gracefully. Perhaps out
@@ -476,7 +477,10 @@ public class UrlInterceptHandlerGears implements UrlInterceptHandler {
}
/**
- * Convenience debug function. Calls Android logging mechanism.
+ * Convenience debug function. Calls the Android logging
+ * mechanism. logEnabled is not a constant, so if the string
+ * evaluation is potentially expensive, the caller also needs to
+ * check it.
* @param str String to log to the Android console.
*/
private void log(String str) {