1// Copyright 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 5package org.chromium.android_webview; 6 7import android.webkit.ValueCallback; 8 9import org.chromium.base.CalledByNative; 10import org.chromium.base.JNINamespace; 11import org.chromium.base.ThreadUtils; 12 13import java.util.HashMap; 14import java.util.Map; 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") 23public class AwQuotaManagerBridge { 24 // TODO(boliu): This should be obtained from Java AwBrowserContext that owns this. 25 private static native long 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 long 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(long 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(long nativeAwQuotaManagerBridgeImpl); 157 private native void nativeDeleteAllData(long nativeAwQuotaManagerBridgeImpl); 158 private native void nativeDeleteOrigin(long nativeAwQuotaManagerBridgeImpl, String origin); 159 private native void nativeGetOrigins(long nativeAwQuotaManagerBridgeImpl, int callbackId); 160 private native void nativeGetUsageAndQuotaForOrigin(long nativeAwQuotaManagerBridgeImpl, 161 String origin, int callbackId, boolean isQuota); 162} 163