Add modifications to handle the WebStorage settings + the WebStorage bridge native functions
diff --git a/core/java/android/webkit/WebStorage.java b/core/java/android/webkit/WebStorage.java
index a0faf76..f27360d 100644
--- a/core/java/android/webkit/WebStorage.java
+++ b/core/java/android/webkit/WebStorage.java
@@ -16,6 +16,16 @@
package android.webkit;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.HashMap;
+import java.util.Vector;
+
/**
* Functionality for manipulating the webstorage databases.
*/
@@ -32,4 +42,242 @@
public interface QuotaUpdater {
public void updateQuota(long newQuota);
};
+
+ // Log tag
+ private static final String TAG = "webstorage";
+
+ // Global instance of a WebStorage
+ private static WebStorage sWebStorage;
+
+ // We keep a copy of the origins, quotas and usages
+ // that we protect via a lock and update in syncValues()
+ private static Lock mLock = new ReentrantLock();
+ private static Condition mCacheUpdated = mLock.newCondition();
+
+ // Message ids
+ static final int UPDATE = 0;
+ static final int SET_QUOTA_ORIGIN = 1;
+ static final int DELETE_ORIGIN = 2;
+ static final int DELETE_ALL = 3;
+
+ private Vector <String> mOrigins;
+ private HashMap <String, Long> mQuotas = new HashMap<String, Long>();
+ private HashMap <String, Long> mUsages = new HashMap<String, Long>();
+
+ private Handler mHandler = null;
+
+ private class Origin {
+ String mOrigin = null;
+ long mQuota = 0;
+
+ public Origin(String origin, long quota) {
+ mOrigin = origin;
+ mQuota = quota;
+ }
+
+ public Origin(String origin) {
+ mOrigin = origin;
+ }
+
+ public String getOrigin() {
+ return mOrigin;
+ }
+
+ public long getQuota() {
+ return mQuota;
+ }
+ }
+
+ /**
+ * @hide
+ * Message handler
+ */
+ public void createHandler() {
+ if (mHandler == null) {
+ mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SET_QUOTA_ORIGIN: {
+ Origin website = (Origin) msg.obj;
+ nativeSetQuotaForOrigin(website.getOrigin(),
+ website.getQuota());
+ syncValues();
+ } break;
+
+ case DELETE_ORIGIN: {
+ Origin website = (Origin) msg.obj;
+ nativeDeleteOrigin(website.getOrigin());
+ syncValues();
+ } break;
+
+ case DELETE_ALL:
+ nativeDeleteAllDatabases();
+ syncValues();
+ break;
+
+ case UPDATE:
+ syncValues();
+ break;
+ }
+ }
+ };
+ }
+ }
+
+ /**
+ * @hide
+ * Returns a list of origins having a database
+ */
+ public Vector getOrigins() {
+ Vector ret = null;
+ mLock.lock();
+ try {
+ update();
+ mCacheUpdated.await();
+ ret = mOrigins;
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Exception while waiting on the updated origins", e);
+ } finally {
+ mLock.unlock();
+ }
+ return ret;
+ }
+
+ /**
+ * @hide
+ * Returns the use for a given origin
+ */
+ public long getUsageForOrigin(String origin) {
+ long ret = 0;
+ if (origin == null) {
+ return ret;
+ }
+ mLock.lock();
+ try {
+ update();
+ mCacheUpdated.await();
+ Long usage = mUsages.get(origin);
+ if (usage != null) {
+ ret = usage.longValue();
+ }
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Exception while waiting on the updated origins", e);
+ } finally {
+ mLock.unlock();
+ }
+ return ret;
+ }
+
+ /**
+ * @hide
+ * Returns the quota for a given origin
+ */
+ public long getQuotaForOrigin(String origin) {
+ long ret = 0;
+ if (origin == null) {
+ return ret;
+ }
+ mLock.lock();
+ try {
+ update();
+ mCacheUpdated.await();
+ Long quota = mQuotas.get(origin);
+ if (quota != null) {
+ ret = quota.longValue();
+ }
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Exception while waiting on the updated origins", e);
+ } finally {
+ mLock.unlock();
+ }
+ return ret;
+ }
+
+ /**
+ * @hide
+ * Set the quota for a given origin
+ */
+ public void setQuotaForOrigin(String origin, long quota) {
+ if (origin != null) {
+ postMessage(Message.obtain(null, SET_QUOTA_ORIGIN,
+ new Origin(origin, quota)));
+ }
+ }
+
+ /**
+ * @hide
+ * Delete a given origin
+ */
+ public void deleteOrigin(String origin) {
+ if (origin != null) {
+ postMessage(Message.obtain(null, DELETE_ORIGIN,
+ new Origin(origin)));
+ }
+ }
+
+ /**
+ * @hide
+ * Delete all databases
+ */
+ public void deleteAllDatabases() {
+ postMessage(Message.obtain(null, DELETE_ALL));
+ }
+
+ /**
+ * Utility function to send a message to our handler
+ */
+ private void postMessage(Message msg) {
+ if (mHandler != null) {
+ mHandler.sendMessage(msg);
+ }
+ }
+
+ /**
+ * @hide
+ * Get the global instance of WebStorage.
+ * @return A single instance of WebStorage.
+ */
+ public static WebStorage getInstance() {
+ if (sWebStorage == null) {
+ sWebStorage = new WebStorage();
+ }
+ return sWebStorage;
+ }
+
+ /**
+ * @hide
+ * Post a Sync request
+ */
+ public void update() {
+ postMessage(Message.obtain(null, UPDATE));
+ }
+
+ /**
+ * Run on the webcore thread
+ * sync the local cached values with the real ones
+ */
+ private void syncValues() {
+ mLock.lock();
+ Vector tmp = nativeGetOrigins();
+ mOrigins = new Vector<String>();
+ mQuotas.clear();
+ mUsages.clear();
+ for (int i = 0; i < tmp.size(); i++) {
+ String origin = (String) tmp.get(i);
+ mOrigins.add(origin);
+ mQuotas.put(origin, new Long(nativeGetQuotaForOrigin(origin)));
+ mUsages.put(origin, new Long(nativeGetUsageForOrigin(origin)));
+ }
+ mCacheUpdated.signal();
+ mLock.unlock();
+ }
+
+ // Native functions
+ private static native Vector nativeGetOrigins();
+ private static native long nativeGetUsageForOrigin(String origin);
+ private static native long nativeGetQuotaForOrigin(String origin);
+ private static native void nativeSetQuotaForOrigin(String origin, long quota);
+ private static native void nativeDeleteOrigin(String origin);
+ private static native void nativeDeleteAllDatabases();
}