Home | History | Annotate | Download | only in android_webview
      1 // Copyright (c) 2013 The Chromium Authors. 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.chromium.android_webview;
      6 
      7 import org.chromium.base.CalledByNative;
      8 import org.chromium.base.JNINamespace;
      9 import org.chromium.base.ThreadUtils;
     10 
     11 import android.webkit.ValueCallback;
     12 
     13 import java.util.Map;
     14 import java.util.HashMap;
     15 
     16 /**
     17  * Bridge between android.webview.WebStorage and native QuotaManager. This object is owned by Java
     18  * AwBrowserContext and the native side is owned by the native AwBrowserContext.
     19  *
     20  * TODO(boliu): Actually make this true after Java AwBrowserContext is added.
     21  */
     22 @JNINamespace("android_webview")
     23 public class AwQuotaManagerBridge {
     24     // TODO(boliu): This should be obtained from Java AwBrowserContext that owns this.
     25     private static native int nativeGetDefaultNativeAwQuotaManagerBridge();
     26 
     27     // TODO(boliu): This should be owned by Java AwBrowserContext, not a singleton.
     28     private static AwQuotaManagerBridge sInstance;
     29     public static AwQuotaManagerBridge getInstance() {
     30         ThreadUtils.assertOnUiThread();
     31         if (sInstance == null) {
     32             sInstance = new AwQuotaManagerBridge(nativeGetDefaultNativeAwQuotaManagerBridge());
     33         }
     34         return sInstance;
     35     }
     36 
     37     /**
     38      * This class represent the callback value of android.webview.WebStorage.getOrigins. The values
     39      * are optimized for JNI convenience and need to be converted.
     40      */
     41     public static class Origins {
     42         // Origin, usage, and quota data in parallel arrays of same length.
     43         public final String[] mOrigins;
     44         public final long[] mUsages;
     45         public final long[] mQuotas;
     46 
     47         Origins(String[] origins, long[] usages, long[] quotas) {
     48             mOrigins = origins;
     49             mUsages = usages;
     50             mQuotas = quotas;
     51         }
     52     }
     53 
     54     // This is not owning. The native object is owned by the native AwBrowserContext.
     55     private int mNativeAwQuotaManagerBridgeImpl;
     56 
     57     // The Java callbacks are saved here. An incrementing callback id is generated for each saved
     58     // callback and is passed to the native side to identify callback.
     59     private int mNextId;
     60     private Map<Integer, ValueCallback<Origins>> mPendingGetOriginCallbacks;
     61     private Map<Integer, ValueCallback<Long>> mPendingGetQuotaForOriginCallbacks;
     62     private Map<Integer, ValueCallback<Long>> mPendingGetUsageForOriginCallbacks;
     63 
     64     private AwQuotaManagerBridge(int nativeAwQuotaManagerBridgeImpl) {
     65         mNativeAwQuotaManagerBridgeImpl = nativeAwQuotaManagerBridgeImpl;
     66         mPendingGetOriginCallbacks =
     67                 new HashMap<Integer, ValueCallback<Origins>>();
     68         mPendingGetQuotaForOriginCallbacks = new HashMap<Integer, ValueCallback<Long>>();
     69         mPendingGetUsageForOriginCallbacks = new HashMap<Integer, ValueCallback<Long>>();
     70         nativeInit(mNativeAwQuotaManagerBridgeImpl);
     71     }
     72 
     73     private int getNextId() {
     74         ThreadUtils.assertOnUiThread();
     75         return ++mNextId;
     76     }
     77 
     78     /*
     79      * There are five HTML5 offline storage APIs.
     80      * 1) Web Storage (ie the localStorage and sessionStorage variables)
     81      * 2) Web SQL database
     82      * 3) Application cache
     83      * 4) Indexed Database
     84      * 5) Filesystem API
     85      */
     86 
     87     /**
     88      * Implements WebStorage.deleteAllData(). Clear the storage of all five offline APIs.
     89      *
     90      * TODO(boliu): Actually clear Web Storage.
     91      */
     92     public void deleteAllData() {
     93         nativeDeleteAllData(mNativeAwQuotaManagerBridgeImpl);
     94     }
     95 
     96     /**
     97      * Implements WebStorage.deleteOrigin(). Clear the storage of APIs 2-5 for the given origin.
     98      */
     99     public void deleteOrigin(String origin) {
    100         nativeDeleteOrigin(mNativeAwQuotaManagerBridgeImpl, origin);
    101     }
    102 
    103     /**
    104      * Implements WebStorage.getOrigins. Get the per origin usage and quota of APIs 2-5 in
    105      * aggregate.
    106      */
    107     public void getOrigins(ValueCallback<Origins> callback) {
    108         int callbackId = getNextId();
    109         assert !mPendingGetOriginCallbacks.containsKey(callbackId);
    110         mPendingGetOriginCallbacks.put(callbackId, callback);
    111         nativeGetOrigins(mNativeAwQuotaManagerBridgeImpl, callbackId);
    112     }
    113 
    114     /**
    115      * Implements WebStorage.getQuotaForOrigin. Get the quota of APIs 2-5 in aggregate for given
    116      * origin.
    117      */
    118     public void getQuotaForOrigin(String origin, ValueCallback<Long> callback) {
    119         int callbackId = getNextId();
    120         assert !mPendingGetQuotaForOriginCallbacks.containsKey(callbackId);
    121         mPendingGetQuotaForOriginCallbacks.put(callbackId, callback);
    122         nativeGetUsageAndQuotaForOrigin(mNativeAwQuotaManagerBridgeImpl, origin, callbackId, true);
    123     }
    124 
    125     /**
    126      * Implements WebStorage.getUsageForOrigin. Get the usage of APIs 2-5 in aggregate for given
    127      * origin.
    128      */
    129     public void getUsageForOrigin(String origin, ValueCallback<Long> callback) {
    130         int callbackId = getNextId();
    131         assert !mPendingGetUsageForOriginCallbacks.containsKey(callbackId);
    132         mPendingGetUsageForOriginCallbacks.put(callbackId, callback);
    133         nativeGetUsageAndQuotaForOrigin(mNativeAwQuotaManagerBridgeImpl, origin, callbackId, false);
    134     }
    135 
    136     @CalledByNative
    137     private void onGetOriginsCallback(int callbackId, String[] origin, long[] usages,
    138             long[] quotas) {
    139         assert mPendingGetOriginCallbacks.containsKey(callbackId);
    140         mPendingGetOriginCallbacks.remove(callbackId).onReceiveValue(
    141             new Origins(origin, usages, quotas));
    142     }
    143 
    144     @CalledByNative
    145     private void onGetUsageAndQuotaForOriginCallback(
    146             int callbackId, boolean isQuota, long usage, long quota) {
    147         if (isQuota) {
    148           assert mPendingGetQuotaForOriginCallbacks.containsKey(callbackId);
    149           mPendingGetQuotaForOriginCallbacks.remove(callbackId).onReceiveValue(quota);
    150         } else {
    151           assert mPendingGetUsageForOriginCallbacks.containsKey(callbackId);
    152           mPendingGetUsageForOriginCallbacks.remove(callbackId).onReceiveValue(usage);
    153         }
    154     }
    155 
    156     private native void nativeInit(int nativeAwQuotaManagerBridgeImpl);
    157     private native void nativeDeleteAllData(int nativeAwQuotaManagerBridgeImpl);
    158     private native void nativeDeleteOrigin(int nativeAwQuotaManagerBridgeImpl, String origin);
    159     private native void nativeGetOrigins(int nativeAwQuotaManagerBridgeImpl, int callbackId);
    160     private native void nativeGetUsageAndQuotaForOrigin(int nativeAwQuotaManagerBridgeImpl,
    161             String origin, int callbackId, boolean isQuota);
    162 }
    163