Home | History | Annotate | Download | only in webkit
      1 /*
      2  * Copyright (C) 2010 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 android.webkit;
     18 
     19 import android.app.ActivityManager;
     20 import android.content.Context;
     21 import android.net.Uri;
     22 import android.provider.Settings;
     23 import android.util.Log;
     24 
     25 import java.io.File;
     26 import java.io.InputStream;
     27 
     28 class JniUtil {
     29 
     30     static {
     31         System.loadLibrary("webcore");
     32         System.loadLibrary("chromium_net");
     33     }
     34     private static final String LOGTAG = "webkit";
     35     private JniUtil() {} // Utility class, do not instantiate.
     36 
     37     // Used by the Chromium HTTP stack.
     38     private static String sDatabaseDirectory;
     39     private static String sCacheDirectory;
     40     private static Context sContext;
     41 
     42     private static void checkInitialized() {
     43         if (sContext == null) {
     44             throw new IllegalStateException("Call CookieSyncManager::createInstance() or create a webview before using this class");
     45         }
     46     }
     47 
     48     protected static synchronized void setContext(Context context) {
     49         if (sContext != null) {
     50             return;
     51         }
     52 
     53         sContext = context.getApplicationContext();
     54     }
     55 
     56     protected static synchronized Context getContext() {
     57         return sContext;
     58     }
     59 
     60     /**
     61      * Called by JNI. Gets the application's database directory, excluding the trailing slash.
     62      * @return String The application's database directory
     63      */
     64     private static synchronized String getDatabaseDirectory() {
     65         checkInitialized();
     66 
     67         if (sDatabaseDirectory == null) {
     68             sDatabaseDirectory = sContext.getDatabasePath("dummy").getParent();
     69         }
     70 
     71         return sDatabaseDirectory;
     72     }
     73 
     74     /**
     75      * Called by JNI. Gets the application's cache directory, excluding the trailing slash.
     76      * @return String The application's cache directory
     77      */
     78     private static synchronized String getCacheDirectory() {
     79         checkInitialized();
     80 
     81         if (sCacheDirectory == null) {
     82             File cacheDir = sContext.getCacheDir();
     83             if (cacheDir == null) {
     84                 sCacheDirectory = "";
     85             } else {
     86                 sCacheDirectory = cacheDir.getAbsolutePath();
     87             }
     88         }
     89 
     90         return sCacheDirectory;
     91     }
     92 
     93     /**
     94      * Called by JNI. Gets the application's package name.
     95      * @return String The application's package name
     96      */
     97     private static synchronized String getPackageName() {
     98         checkInitialized();
     99 
    100         return sContext.getPackageName();
    101     }
    102 
    103     private static final String ANDROID_CONTENT = URLUtil.CONTENT_BASE;
    104 
    105     /**
    106      * Called by JNI. Calculates the size of an input stream by reading it.
    107      * @return long The size of the stream
    108      */
    109     private static synchronized long contentUrlSize(String url) {
    110         // content://
    111         if (url.startsWith(ANDROID_CONTENT)) {
    112             try {
    113                 // Strip off MIME type. If we don't do this, we can fail to
    114                 // load Gmail attachments, because the URL being loaded doesn't
    115                 // exactly match the URL we have permission to read.
    116                 int mimeIndex = url.lastIndexOf('?');
    117                 if (mimeIndex != -1) {
    118                     url = url.substring(0, mimeIndex);
    119                 }
    120                 Uri uri = Uri.parse(url);
    121                 InputStream is = sContext.getContentResolver().openInputStream(uri);
    122                 byte[] buffer = new byte[1024];
    123                 int n;
    124                 long size = 0;
    125                 try {
    126                     while ((n = is.read(buffer)) != -1) {
    127                         size += n;
    128                     }
    129                 } finally {
    130                     is.close();
    131                 }
    132                 return size;
    133             } catch (Exception e) {
    134                 Log.e(LOGTAG, "Exception: " + url);
    135                 return 0;
    136             }
    137         } else {
    138             return 0;
    139         }
    140     }
    141 
    142     /**
    143      * Called by JNI.
    144      *
    145      * @return  Opened input stream to content
    146      * TODO: Make all content loading use this instead of BrowserFrame.java
    147      */
    148     private static synchronized InputStream contentUrlStream(String url) {
    149         // content://
    150         if (url.startsWith(ANDROID_CONTENT)) {
    151             try {
    152                 // Strip off mimetype, for compatibility with ContentLoader.java
    153                 // (used with Android HTTP stack, now removed).
    154                 // If we don't do this, we can fail to load Gmail attachments,
    155                 // because the URL being loaded doesn't exactly match the URL we
    156                 // have permission to read.
    157                 int mimeIndex = url.lastIndexOf('?');
    158                 if (mimeIndex != -1) {
    159                     url = url.substring(0, mimeIndex);
    160                 }
    161                 Uri uri = Uri.parse(url);
    162                 return sContext.getContentResolver().openInputStream(uri);
    163             } catch (Exception e) {
    164                 Log.e(LOGTAG, "Exception: " + url);
    165                 return null;
    166             }
    167         } else {
    168             return null;
    169         }
    170     }
    171 
    172     private static synchronized String getAutofillQueryUrl() {
    173         checkInitialized();
    174         // If the device has not checked in it won't have pulled down the system setting for the
    175         // Autofill Url. In that case we will not make autofill server requests.
    176         return Settings.Global.getString(sContext.getContentResolver(),
    177                 Settings.Global.WEB_AUTOFILL_QUERY_URL);
    178     }
    179 
    180     private static boolean canSatisfyMemoryAllocation(long bytesRequested) {
    181         checkInitialized();
    182         ActivityManager manager = (ActivityManager) sContext.getSystemService(
    183                 Context.ACTIVITY_SERVICE);
    184         ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
    185         manager.getMemoryInfo(memInfo);
    186         long leftToAllocate = memInfo.availMem - memInfo.threshold;
    187         return !memInfo.lowMemory && bytesRequested < leftToAllocate;
    188     }
    189 }
    190