diff options
Diffstat (limited to 'core')
5 files changed, 3 insertions, 674 deletions
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 2ab5357..bf15871 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1314,7 +1314,7 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a - * {@blink android.appwidget.AppWidgetManager} for accessing AppWidgets. + * {@link android.appwidget.AppWidgetManager} for accessing AppWidgets. * * @hide * @see #getSystemService @@ -1323,7 +1323,7 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve an - * {@blink android.backup.IBackupManager IBackupManager} for communicating + * {@link android.backup.IBackupManager IBackupManager} for communicating * with the backup mechanism. * @hide * @@ -1333,7 +1333,7 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a - * {@blink android.os.DropBox DropBox} instance for recording + * {@link android.os.DropBox DropBox} instance for recording * diagnostic logs. * @see #getSystemService */ diff --git a/core/java/com/android/internal/net/DbSSLSessionCache.java b/core/java/com/android/internal/net/DbSSLSessionCache.java deleted file mode 100644 index 842d40b..0000000 --- a/core/java/com/android/internal/net/DbSSLSessionCache.java +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright 2009 The Android Open Source Project - -package com.android.internal.net; - -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.SQLException; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.util.Log; - -import org.apache.commons.codec.binary.Base64; -import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache; - -import java.util.HashMap; -import java.util.Map; - -import javax.net.ssl.SSLSession; - -/** - * Hook into harmony SSL cache to persist the SSL sessions. - * - * Current implementation is suitable for saving a small number of hosts - - * like google services. It can be extended with expiration and more features - * to support more hosts. - * - * {@hide} - */ -public class DbSSLSessionCache implements SSLClientSessionCache { - private static final String TAG = "DbSSLSessionCache"; - - /** - * Table where sessions are stored. - */ - public static final String SSL_CACHE_TABLE = "ssl_sessions"; - - private static final String SSL_CACHE_ID = "_id"; - - /** - * Key is host:port - port is not optional. - */ - private static final String SSL_CACHE_HOSTPORT = "hostport"; - - /** - * Base64-encoded DER value of the session. - */ - private static final String SSL_CACHE_SESSION = "session"; - - /** - * Time when the record was added - should be close to the time - * of the initial session negotiation. - */ - private static final String SSL_CACHE_TIME_SEC = "time_sec"; - - public static final String DATABASE_NAME = "ssl_sessions.db"; - - public static final int DATABASE_VERSION = 2; - - /** public for testing - */ - public static final int SSL_CACHE_ID_COL = 0; - public static final int SSL_CACHE_HOSTPORT_COL = 1; - public static final int SSL_CACHE_SESSION_COL = 2; - public static final int SSL_CACHE_TIME_SEC_COL = 3; - - public static final int MAX_CACHE_SIZE = 256; - - private final Map<String, byte[]> mExternalCache = - new HashMap<String, byte[]>(); - - - private DatabaseHelper mDatabaseHelper; - - private boolean mNeedsCacheLoad = true; - - public static final String[] PROJECTION = new String[] { - SSL_CACHE_ID, - SSL_CACHE_HOSTPORT, - SSL_CACHE_SESSION, - SSL_CACHE_TIME_SEC - }; - - private static final Map<String,DbSSLSessionCache> sInstances = - new HashMap<String,DbSSLSessionCache>(); - - /** - * Returns a singleton instance of the DbSSLSessionCache that should be used for this - * context's package. - * - * @param context The context that should be used for getting/creating the singleton instance. - * @return The singleton instance for the context's package. - */ - public static synchronized DbSSLSessionCache getInstanceForPackage(Context context) { - String packageName = context.getPackageName(); - if (sInstances.containsKey(packageName)) { - return sInstances.get(packageName); - } - DbSSLSessionCache cache = new DbSSLSessionCache(context); - sInstances.put(packageName, cache); - return cache; - } - - /** - * Create a SslSessionCache instance, using the specified context to - * initialize the database. - * - * This constructor will use the default database - created for the application - * context. - * - * @param activityContext - */ - private DbSSLSessionCache(Context activityContext) { - Context appContext = activityContext.getApplicationContext(); - mDatabaseHelper = new DatabaseHelper(appContext); - } - - /** - * Create a SslSessionCache that uses a specific database. - * - * - * @param database - */ - public DbSSLSessionCache(DatabaseHelper database) { - this.mDatabaseHelper = database; - } - - public void putSessionData(SSLSession session, byte[] der) { - if (mDatabaseHelper == null) { - return; - } - synchronized (this.getClass()) { - SQLiteDatabase db = mDatabaseHelper.getWritableDatabase(); - if (mExternalCache.size() == MAX_CACHE_SIZE) { - // remove oldest. - // TODO: check if the new one is in cached already ( i.e. update ). - Cursor byTime = mDatabaseHelper.getReadableDatabase().query(SSL_CACHE_TABLE, - PROJECTION, null, null, null, null, SSL_CACHE_TIME_SEC); - if (byTime.moveToFirst()) { - // TODO: can I do byTime.deleteRow() ? - String hostPort = byTime.getString(SSL_CACHE_HOSTPORT_COL); - db.delete(SSL_CACHE_TABLE, - SSL_CACHE_HOSTPORT + "= ?" , new String[] { hostPort }); - mExternalCache.remove(hostPort); - } else { - Log.w(TAG, "No rows found"); - // something is wrong, clear it - clear(); - } - } - // Serialize native session to standard DER encoding - long t0 = System.currentTimeMillis(); - - String b64 = new String(Base64.encodeBase64(der)); - String key = session.getPeerHost() + ":" + session.getPeerPort(); - - ContentValues values = new ContentValues(); - values.put(SSL_CACHE_HOSTPORT, key); - values.put(SSL_CACHE_SESSION, b64); - values.put(SSL_CACHE_TIME_SEC, System.currentTimeMillis() / 1000); - - mExternalCache.put(key, der); - - try { - db.insert(SSL_CACHE_TABLE, null /*nullColumnHack */ , values); - } catch(SQLException ex) { - // Ignore - nothing we can do to recover, and caller shouldn't - // be affected. - Log.w(TAG, "Ignoring SQL exception when caching session", ex); - } - if (Log.isLoggable(TAG, Log.DEBUG)) { - long t1 = System.currentTimeMillis(); - Log.d(TAG, "New SSL session " + session.getPeerHost() + - " DER len: " + der.length + " " + (t1 - t0)); - } - } - - } - - public byte[] getSessionData(String host, int port) { - // Current (simple) implementation does a single lookup to DB, then saves - // all entries to the cache. - - // This works for google services - i.e. small number of certs. - // If we extend this to all processes - we should hold a separate cache - // or do lookups to DB each time. - if (mDatabaseHelper == null) { - return null; - } - synchronized(this.getClass()) { - if (mNeedsCacheLoad) { - // Don't try to load again, if something is wrong on the first - // request it'll likely be wrong each time. - mNeedsCacheLoad = false; - long t0 = System.currentTimeMillis(); - - Cursor cur = null; - try { - cur = mDatabaseHelper.getReadableDatabase().query(SSL_CACHE_TABLE, - PROJECTION, null, null, null, null, null); - if (cur.moveToFirst()) { - do { - String hostPort = cur.getString(SSL_CACHE_HOSTPORT_COL); - String value = cur.getString(SSL_CACHE_SESSION_COL); - - if (hostPort == null || value == null) { - continue; - } - // TODO: blob support ? - byte[] der = Base64.decodeBase64(value.getBytes()); - mExternalCache.put(hostPort, der); - } while (cur.moveToNext()); - - } - } catch (SQLException ex) { - Log.d(TAG, "Error loading SSL cached entries ", ex); - } finally { - if (cur != null) { - cur.close(); - } - if (Log.isLoggable(TAG, Log.DEBUG)) { - long t1 = System.currentTimeMillis(); - Log.d(TAG, "LOADED CACHED SSL " + (t1 - t0) + " ms"); - } - } - } - - String key = host + ":" + port; - - return mExternalCache.get(key); - } - } - - /** - * Reset the database and internal state. - * Used for testing or to free space. - */ - public void clear() { - synchronized(this) { - try { - mExternalCache.clear(); - mNeedsCacheLoad = true; - mDatabaseHelper.getWritableDatabase().delete(SSL_CACHE_TABLE, - null, null); - } catch (SQLException ex) { - Log.d(TAG, "Error removing SSL cached entries ", ex); - // ignore - nothing we can do about it - } - } - } - - public byte[] getSessionData(byte[] id) { - // We support client side only - the cache will do nothing for - // server-side sessions. - return null; - } - - /** Visible for testing. - */ - public static class DatabaseHelper extends SQLiteOpenHelper { - - public DatabaseHelper(Context context) { - super(context, DATABASE_NAME, null /* factory */, DATABASE_VERSION); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL("CREATE TABLE " + SSL_CACHE_TABLE + " (" + - SSL_CACHE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + - SSL_CACHE_HOSTPORT + " TEXT UNIQUE ON CONFLICT REPLACE," + - SSL_CACHE_SESSION + " TEXT," + - SSL_CACHE_TIME_SEC + " INTEGER" + - ");"); - - // No index - we load on startup, index would slow down inserts. - // If we want to scale this to lots of rows - we could use - // index, but then we'll hit DB a bit too often ( including - // negative hits ) - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - db.execSQL("DROP TABLE IF EXISTS " + SSL_CACHE_TABLE ); - onCreate(db); - } - - } - -} diff --git a/core/java/com/google/android/net/NetworkStatsEntity.java b/core/java/com/google/android/net/NetworkStatsEntity.java deleted file mode 100644 index a22fa1e..0000000 --- a/core/java/com/google/android/net/NetworkStatsEntity.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.net; - -import android.net.TrafficStats; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.util.EventLog; -import org.apache.http.HttpEntity; -import org.apache.http.entity.HttpEntityWrapper; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - - -public class NetworkStatsEntity extends HttpEntityWrapper { - - private static final int HTTP_STATS_EVENT = 52001; - - private class NetworkStatsInputStream extends FilterInputStream { - - public NetworkStatsInputStream(InputStream wrapped) { - super(wrapped); - } - - @Override - public void close() throws IOException { - try { - super.close(); - } finally { - long processingTime = SystemClock.elapsedRealtime() - mProcessingStartTime; - long tx = TrafficStats.getUidTxBytes(mUid); - long rx = TrafficStats.getUidRxBytes(mUid); - - EventLog.writeEvent(HTTP_STATS_EVENT, mUa, mResponseLatency, processingTime, - tx - mStartTx, rx - mStartRx); - } - } - } - - private final String mUa; - private final int mUid; - private final long mStartTx; - private final long mStartRx; - private final long mResponseLatency; - private final long mProcessingStartTime; - - public NetworkStatsEntity(HttpEntity orig, String ua, - int uid, long startTx, long startRx, long responseLatency, - long processingStartTime) { - super(orig); - this.mUa = ua; - this.mUid = uid; - this.mStartTx = startTx; - this.mStartRx = startRx; - this.mResponseLatency = responseLatency; - this.mProcessingStartTime = processingStartTime; - } - - public static boolean shouldLogNetworkStats() { - return "1".equals(SystemProperties.get("googlehttpclient.logstats")); - } - - @Override - public InputStream getContent() throws IOException { - InputStream orig = super.getContent(); - return new NetworkStatsInputStream(orig); - } -} diff --git a/core/java/com/google/android/net/SSLClientSessionCacheFactory.java b/core/java/com/google/android/net/SSLClientSessionCacheFactory.java deleted file mode 100644 index 6570a9bd..0000000 --- a/core/java/com/google/android/net/SSLClientSessionCacheFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.google.android.net; - -import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache; -import org.apache.harmony.xnet.provider.jsse.FileClientSessionCache; -import android.content.Context; -import android.provider.Settings; -import android.util.Log; - -import java.io.File; -import java.io.IOException; - -import com.android.internal.net.DbSSLSessionCache; - -/** - * Factory that returns the appropriate implementation of a {@link SSLClientSessionCache} based - * on gservices. - * - * @hide - */ -// TODO: return a proxied implementation that is updated as the gservices value changes. -public final class SSLClientSessionCacheFactory { - - private static final String TAG = "SSLClientSessionCacheFactory"; - - public static final String DB = "db"; - public static final String FILE = "file"; - - // utility class - private SSLClientSessionCacheFactory() {} - - /** - * Returns a new {@link SSLClientSessionCache} based on the persistent cache that's specified, - * if any, in gservices. If no cache is specified, returns null. - * @param context The application context used for the per-process persistent cache. - * @return A new {@link SSLClientSessionCache}, or null if no persistent cache is configured. - */ - public static SSLClientSessionCache getCache(Context context) { - String type = Settings.Gservices.getString(context.getContentResolver(), - Settings.Gservices.SSL_SESSION_CACHE); - - if (type != null) { - if (DB.equals(type)) { - return DbSSLSessionCache.getInstanceForPackage(context); - } else if (FILE.equals(type)) { - File dir = context.getFilesDir(); - File cacheDir = new File(dir, "sslcache"); - if (!cacheDir.exists()) { - cacheDir.mkdir(); - } - try { - return FileClientSessionCache.usingDirectory(cacheDir); - } catch (IOException ioe) { - Log.w(TAG, "Unable to create FileClientSessionCache in " + cacheDir.getName(), ioe); - return null; - } - } else { - Log.w(TAG, "Ignoring unrecognized type: '" + type + "'"); - } - } - return null; - } -} diff --git a/core/java/com/google/android/net/UrlRules.java b/core/java/com/google/android/net/UrlRules.java deleted file mode 100644 index 54d139d..0000000 --- a/core/java/com/google/android/net/UrlRules.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.net; - -import android.content.ContentResolver; -import android.database.Cursor; -import android.provider.Checkin; -import android.provider.Settings; -import android.util.Config; -import android.util.Log; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A set of rules rewriting and blocking URLs. Used to offer a point of - * control for redirecting HTTP requests, often to the Android proxy server. - * - * <p>Each rule has the following format: - * - * <pre><em>url-prefix</em> [REWRITE <em>new-prefix</em>] [BLOCK]</pre> - * - * <p>Any URL which starts with <em>url-prefix</em> will trigger the rule. - * If BLOCK is specified, requests to that URL will be blocked and fail. - * If REWRITE is specified, the matching prefix will be removed and replaced - * with <em>new-prefix</em>. (If both are specified, BLOCK wins.) Case is - * insensitive for the REWRITE and BLOCK keywords, but sensitive for URLs. - * - * <p>In Gservices, the value of any key that starts with "url:" will be - * interpreted as a rule. The full name of the key is unimportant (but can - * be used to document the intent of the rule, and must be unique). - * Example gservices keys: - * - * <pre> - * url:use_proxy_for_calendar = "http://www.google.com/calendar/ REWRITE http://android.clients.google.com/proxy/calendar/" - * url:stop_crash_reports = "http://android.clients.google.com/crash/ BLOCK" - * url:use_ssl_for_contacts = "http://www.google.com/m8/ REWRITE https://www.google.com/m8/" - * </pre> - */ -public class UrlRules { - public static final String TAG = "UrlRules"; - public static final boolean LOCAL_LOGV = Config.LOGV || false; - - /** Thrown when the rewrite rules can't be parsed. */ - public static class RuleFormatException extends Exception { - public RuleFormatException(String msg) { super(msg); } - } - - /** A single rule specifying actions for URLs matching a certain prefix. */ - public static class Rule implements Comparable { - /** Name assigned to the rule (for logging and debugging). */ - public final String mName; - - /** Prefix required to match this rule. */ - public final String mPrefix; - - /** Text to replace mPrefix with (null to leave alone). */ - public final String mRewrite; - - /** True if matching URLs should be blocked. */ - public final boolean mBlock; - - /** Default rule that does nothing. */ - public static final Rule DEFAULT = new Rule(); - - /** Parse a rewrite rule as given in a Gservices value. */ - public Rule(String name, String rule) throws RuleFormatException { - mName = name; - String[] words = PATTERN_SPACE_PLUS.split(rule); - if (words.length == 0) throw new RuleFormatException("Empty rule"); - - mPrefix = words[0]; - String rewrite = null; - boolean block = false; - for (int pos = 1; pos < words.length; ) { - String word = words[pos].toLowerCase(); - if (word.equals("rewrite") && pos + 1 < words.length) { - rewrite = words[pos + 1]; - pos += 2; - } else if (word.equals("block")) { - block = true; - pos += 1; - } else { - throw new RuleFormatException("Illegal rule: " + rule); - } - // TODO: Parse timeout specifications, etc. - } - - mRewrite = rewrite; - mBlock = block; - } - - /** Create the default Rule. */ - private Rule() { - mName = "DEFAULT"; - mPrefix = ""; - mRewrite = null; - mBlock = false; - } - - /** - * Apply the rule to a particular URL (assumed to match the rule). - * @param url to rewrite or modify. - * @return modified URL, or null if the URL is blocked. - */ - public String apply(String url) { - if (mBlock) { - return null; - } else if (mRewrite != null) { - return mRewrite + url.substring(mPrefix.length()); - } else { - return url; - } - } - - /** More generic rules are greater than more specific rules. */ - public int compareTo(Object o) { - return ((Rule) o).mPrefix.compareTo(mPrefix); - } - } - - /** Cached rule set from Gservices. */ - private static UrlRules sCachedRules = new UrlRules(new Rule[] {}); - - private static final Pattern PATTERN_SPACE_PLUS = Pattern.compile(" +"); - private static final Pattern RULE_PATTERN = Pattern.compile("\\W"); - - /** Gservices digest when sCachedRules was cached. */ - private static String sCachedDigest = null; - - /** Currently active set of Rules. */ - private final Rule[] mRules; - - /** Regular expression with one capturing group for each Rule. */ - private final Pattern mPattern; - - /** - * Create a rewriter from an array of Rules. Normally used only for - * testing. Instead, use {@link #getRules} to get rules from Gservices. - * @param rules to use. - */ - public UrlRules(Rule[] rules) { - // Sort the rules to put the most specific rules first. - Arrays.sort(rules); - - // Construct a regular expression, escaping all the prefix strings. - StringBuilder pattern = new StringBuilder("("); - for (int i = 0; i < rules.length; ++i) { - if (i > 0) pattern.append(")|("); - pattern.append(RULE_PATTERN.matcher(rules[i].mPrefix).replaceAll("\\\\$0")); - } - mPattern = Pattern.compile(pattern.append(")").toString()); - mRules = rules; - } - - /** - * Match a string against every Rule and find one that matches. - * @param uri to match against the Rules in the rewriter. - * @return the most specific matching Rule, or Rule.DEFAULT if none match. - */ - public Rule matchRule(String url) { - Matcher matcher = mPattern.matcher(url); - if (matcher.lookingAt()) { - for (int i = 0; i < mRules.length; ++i) { - if (matcher.group(i + 1) != null) { - return mRules[i]; // Rules are sorted most specific first. - } - } - } - return Rule.DEFAULT; - } - - /** - * Get the (possibly cached) UrlRules based on the rules in Gservices. - * @param resolver to use for accessing the Gservices database. - * @return an updated UrlRules instance - */ - public static synchronized UrlRules getRules(ContentResolver resolver) { - String digest = Settings.Gservices.getString(resolver, - Settings.Gservices.PROVISIONING_DIGEST); - if (sCachedDigest != null && sCachedDigest.equals(digest)) { - // The digest is the same, so the rules are the same. - if (LOCAL_LOGV) Log.v(TAG, "Using cached rules for digest: " + digest); - return sCachedRules; - } - - if (LOCAL_LOGV) Log.v(TAG, "Scanning for Gservices \"url:*\" rules"); - Cursor cursor = resolver.query(Settings.Gservices.CONTENT_URI, - new String[] { - Settings.Gservices.NAME, - Settings.Gservices.VALUE - }, - Settings.Gservices.NAME + " like \"url:%\"", null, - Settings.Gservices.NAME); - try { - ArrayList<Rule> rules = new ArrayList<Rule>(); - while (cursor.moveToNext()) { - try { - String name = cursor.getString(0).substring(4); // "url:X" - String value = cursor.getString(1); - if (value == null || value.length() == 0) continue; - if (LOCAL_LOGV) Log.v(TAG, " Rule " + name + ": " + value); - rules.add(new Rule(name, value)); - } catch (RuleFormatException e) { - // Oops, Gservices has an invalid rule! Skip it. - Log.e(TAG, "Invalid rule from Gservices", e); - Checkin.logEvent(resolver, - Checkin.Events.Tag.GSERVICES_ERROR, e.toString()); - } - } - sCachedRules = new UrlRules(rules.toArray(new Rule[rules.size()])); - sCachedDigest = digest; - if (LOCAL_LOGV) Log.v(TAG, "New rules stored for digest: " + digest); - } finally { - cursor.close(); - } - - return sCachedRules; - } -} |