summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-02 22:54:33 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-02 22:54:33 -0800
commit3dec7d563a2f3e1eb967ce2054a00b6620e3558c (patch)
treeaa3b0365c47cb3c1607c0dc76c8d32b4046fc287 /tests
parent15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b (diff)
downloadframeworks_base-3dec7d563a2f3e1eb967ce2054a00b6620e3558c.zip
frameworks_base-3dec7d563a2f3e1eb967ce2054a00b6620e3558c.tar.gz
frameworks_base-3dec7d563a2f3e1eb967ce2054a00b6620e3558c.tar.bz2
auto import from //depot/cupcake/@137055
Diffstat (limited to 'tests')
-rwxr-xr-xtests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java12
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/DbSSLSessionCacheTest.java273
-rw-r--r--tests/CoreTests/android/core/DatabaseSessionCache.java312
-rw-r--r--tests/CoreTests/android/core/SSLPerformanceTest.java432
-rw-r--r--tests/CoreTests/android/core/SSLSocketTest.java243
-rw-r--r--tests/CoreTests/android/location/LocationManagerProximityTest.java49
-rwxr-xr-xtests/CoreTests/run_core_test.sh4
-rwxr-xr-xtests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java4
-rw-r--r--tests/gadgets/GadgetProviderTest/res/layout/test_gadget.xml7
-rw-r--r--tests/gadgets/GadgetProviderTest/res/xml/gadget_info.xml6
10 files changed, 1277 insertions, 65 deletions
diff --git a/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java b/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java
index f9af436..3daa8ab 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java
@@ -121,6 +121,7 @@ public class AppCacheTest extends AndroidTestCase {
}
@LargeTest
public void testFreeApplicationCacheAllFiles() throws Exception {
+ boolean TRACKING = true;
StatFs st = new StatFs("/data");
long blks1 = getFreeStorageBlks(st);
long availableMem = getFreeStorageSize(st);
@@ -128,11 +129,11 @@ public class AppCacheTest extends AndroidTestCase {
assertNotNull(cacheDir);
createTestFiles1(cacheDir, "testtmpdir", 5);
long blks2 = getFreeStorageBlks(st);
- if(localLOGV) Log.i(TAG, "blk1="+blks1+", blks2="+blks2);
+ if(localLOGV || TRACKING) Log.i(TAG, "blk1="+blks1+", blks2="+blks2);
//this should free up the test files that were created earlier
invokePMFreeApplicationCache(availableMem);
long blks3 = getFreeStorageBlks(st);
- if(localLOGV) Log.i(TAG, "blks3="+blks3);
+ if(localLOGV || TRACKING) Log.i(TAG, "blks3="+blks3);
verifyTestFiles1(cacheDir, "testtmpdir", 5);
}
@@ -629,15 +630,16 @@ public class AppCacheTest extends AndroidTestCase {
@SmallTest
public void testFreeStorage() throws Exception {
+ boolean TRACKING = true;
StatFs st = new StatFs("/data");
long blks1 = getFreeStorageBlks(st);
- if(localLOGV) Log.i(TAG, "Available free blocks="+blks1);
+ if(localLOGV || TRACKING) Log.i(TAG, "Available free blocks="+blks1);
long availableMem = getFreeStorageSize(st);
File cacheDir = mContext.getCacheDir();
assertNotNull(cacheDir);
createTestFiles1(cacheDir, "testtmpdir", 5);
long blks2 = getFreeStorageBlks(st);
- if(localLOGV) Log.i(TAG, "Available blocks after writing test files in application cache="+blks2);
+ if(localLOGV || TRACKING) Log.i(TAG, "Available blocks after writing test files in application cache="+blks2);
// Create receiver and register it
FreeStorageReceiver receiver = new FreeStorageReceiver();
mContext.registerReceiver(receiver, new IntentFilter(FreeStorageReceiver.ACTION_FREE));
@@ -646,7 +648,7 @@ public class AppCacheTest extends AndroidTestCase {
// Invoke PackageManager api
invokePMFreeStorage(availableMem, receiver, pi);
long blks3 = getFreeStorageBlks(st);
- if(localLOGV) Log.i(TAG, "Available blocks after freeing cache"+blks3);
+ if(localLOGV || TRACKING) Log.i(TAG, "Available blocks after freeing cache"+blks3);
assertEquals(receiver.getResultCode(), 1);
mContext.unregisterReceiver(receiver);
// Verify result
diff --git a/tests/AndroidTests/src/com/android/unit_tests/DbSSLSessionCacheTest.java b/tests/AndroidTests/src/com/android/unit_tests/DbSSLSessionCacheTest.java
new file mode 100644
index 0000000..77460be
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/DbSSLSessionCacheTest.java
@@ -0,0 +1,273 @@
+/*
+ * 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.android.unit_tests;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.provider.Settings;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
+
+import com.google.android.net.GoogleHttpClient;
+
+import com.android.internal.net.DbSSLSessionCache;
+import com.android.internal.net.SSLSessionCache;
+import com.android.internal.net.DbSSLSessionCache.DatabaseHelper;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.security.cert.Certificate;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+import javax.security.cert.X509Certificate;
+
+/** Unit test for SSL session caching with {@link GoogleHttpClient}.
+ * Uses network resources.
+ */
+@Suppress
+public class DbSSLSessionCacheTest extends AndroidTestCase {
+
+ protected void setUp() throws Exception {
+ }
+
+ protected void tearDown() throws Exception {
+ }
+
+ @LargeTest
+ public void testSslCacheSettings() throws Exception {
+ ContentResolver resolver = getContext().getContentResolver();
+ Settings.Gservices.putString(resolver, Settings.Gservices.SSL_SESSION_CACHE,
+ "0");
+ assertFalse(SSLSessionCache.isEnabled(getContext().getContentResolver()));
+
+ resolver = getContext().getContentResolver();
+ Settings.Gservices.putString(resolver, Settings.Gservices.SSL_SESSION_CACHE,
+ "db");
+ assertTrue(SSLSessionCache.isEnabled(getContext().getContentResolver()));
+ }
+
+ /**
+ * We want to test the actual database write - the actual hooking into
+ * low-level SSL is tested.
+ */
+ @LargeTest
+ public void testSslCacheAdd() throws Exception {
+ // Let's verify the database has the rows.
+ // Use internal details of the implementation - could make the field
+ // visible for testing, but it's same.
+
+ // Use default database
+ DbSSLSessionCache cache = new DbSSLSessionCache(getContext());
+ cache.clear();
+
+
+ makeRequestInNewContext("https://www.google.com");
+
+ // Verify the key was inserted
+ SQLiteOpenHelper helper = new DatabaseHelper(getContext());
+ Cursor query = null;
+ try {
+ query = helper.getReadableDatabase().query(DbSSLSessionCache.SSL_CACHE_TABLE,
+ new String[] {"hostport"}, null,
+ null, null, null, null);
+
+ assertTrue(query.moveToFirst()); // one row inserted
+ String hostPort = query.getString(0);
+ assertEquals(hostPort, "www.google.com:443");
+ } finally {
+ query.close();
+ }
+ }
+
+ @LargeTest
+ public void testExpire() throws Exception {
+ DatabaseHelper helper = new DatabaseHelper(getContext());
+ // clean up
+ DbSSLSessionCache cache = new DbSSLSessionCache(helper);
+ cache.clear();
+
+ long t0 = System.currentTimeMillis();
+ for (int i = 0; i < DbSSLSessionCache.MAX_CACHE_SIZE + 2; i++) {
+ final int port = i;
+ cache.putSessionData(new MockSession() {
+
+ public String getPeerHost() {
+ return "test.host.com";
+ }
+
+ public int getPeerPort() {
+ return port;
+ }
+ }, new byte[256]);
+ }
+ long t1 = System.currentTimeMillis();
+
+ System.err.println("Time to insert " +
+ (DbSSLSessionCache.MAX_CACHE_SIZE + 2) + " " + (t1 - t0));
+
+ // first entry should have port 1.
+ Cursor query = helper.getReadableDatabase().query(DbSSLSessionCache.SSL_CACHE_TABLE,
+ new String[] {"hostport", "session"}, null,
+ null, null, null, null);
+
+ int cnt = query.getCount();
+
+ assertTrue(query.moveToFirst()); // one row inserted
+ String hostPort = query.getString(0);
+ assertEquals("test.host.com:2", hostPort);
+ while (query.moveToNext()) {
+ hostPort = query.getString(0);
+ String session = query.getString(1);
+ }
+ long t2 = System.currentTimeMillis();
+ System.err.println("Time to load " + cnt + " " + (t2 - t1));
+
+ query.close();
+ }
+
+ private void makeRequestInNewContext(String url) throws IOException {
+ GoogleHttpClient client = new GoogleHttpClient(getContext(), "Test",
+ false /* no gzip */);
+
+ try {
+ // Note: we must test against a real server, because the connection
+ // gets established before the interceptor can crash the request.
+ HttpGet method = new HttpGet(url);
+ HttpResponse response = client.execute(method);
+ } finally {
+ client.close();
+ }
+ }
+
+ private static class MockSession implements SSLSession {
+
+ public String getPeerHost() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public int getPeerPort() {
+ throw new UnsupportedOperationException();
+ }
+
+
+
+ public int getApplicationBufferSize() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public String getCipherSuite() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public long getCreationTime() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public byte[] getId() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public long getLastAccessedTime() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public Certificate[] getLocalCertificates() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public Principal getLocalPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public int getPacketBufferSize() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public X509Certificate[] getPeerCertificateChain()
+ throws SSLPeerUnverifiedException {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public String getProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public SSLSessionContext getSessionContext() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public Object getValue(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public String[] getValueNames() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public void invalidate() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public boolean isValid() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public void putValue(String name, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public void removeValue(String name) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+
+}
diff --git a/tests/CoreTests/android/core/DatabaseSessionCache.java b/tests/CoreTests/android/core/DatabaseSessionCache.java
new file mode 100644
index 0000000..c344d9c
--- /dev/null
+++ b/tests/CoreTests/android/core/DatabaseSessionCache.java
@@ -0,0 +1,312 @@
+// Copyright 2009 The Android Open Source Project
+
+package android.core;
+
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+import android.content.ContentValues;
+import android.content.Context;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
+
+import java.util.LinkedHashMap;
+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 DatabaseSessionCache implements SSLClientSessionCache {
+ private static final String TAG = "SslSessionCache";
+ static DatabaseHelper sDefaultDatabaseHelper;
+
+ private DatabaseHelper mDatabaseHelper;
+
+ /**
+ * 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 = 1;
+
+ /** 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;
+
+ private static final String SAVE_ON_ADD = "save_on_add";
+
+ static boolean sHookInitializationDone = false;
+
+ public static final int MAX_CACHE_SIZE = 256;
+
+ private static final Map<String, byte[]> mExternalCache =
+ new LinkedHashMap<String, byte[]>(MAX_CACHE_SIZE, 0.75f, true) {
+ @Override
+ public boolean removeEldestEntry(
+ Map.Entry<String, byte[]> eldest) {
+ boolean shouldDelete = this.size() > MAX_CACHE_SIZE;
+
+ // TODO: delete from DB
+ return shouldDelete;
+ }
+ };
+ static boolean mNeedsCacheLoad = true;
+
+ public static final String[] PROJECTION = new String[] {
+ SSL_CACHE_ID,
+ SSL_CACHE_HOSTPORT,
+ SSL_CACHE_SESSION,
+ SSL_CACHE_TIME_SEC
+ };
+
+ /**
+ * This class needs to be installed as a hook, if the security property
+ * is set. Getting the right classloader may be fun since we don't use
+ * Provider to get its classloader, but in android this is in same
+ * loader with AndroidHttpClient.
+ *
+ * This constructor will use the default database. You must
+ * call init() before to specify the context used for the database and
+ * check settings.
+ */
+ public DatabaseSessionCache() {
+ Log.v(TAG, "Instance created.");
+ // May be null if caching is disabled - no sessions will be persisted.
+ this.mDatabaseHelper = sDefaultDatabaseHelper;
+ }
+
+ /**
+ * Create a SslSessionCache instance, using the specified context to
+ * initialize the database.
+ *
+ * This constructor will use the default database - created the first
+ * time.
+ *
+ * @param activityContext
+ */
+ public DatabaseSessionCache(Context activityContext) {
+ // Static init - only one initialization will happen.
+ // Each SslSessionCache is using the same DB.
+ init(activityContext);
+ // May be null if caching is disabled - no sessions will be persisted.
+ this.mDatabaseHelper = sDefaultDatabaseHelper;
+ }
+
+ /**
+ * Create a SslSessionCache that uses a specific database.
+ *
+ * @param database
+ */
+ public DatabaseSessionCache(DatabaseHelper database) {
+ this.mDatabaseHelper = database;
+ }
+
+// public static boolean enabled(Context androidContext) {
+// String sslCache = Settings.Gservices.getString(androidContext.getContentResolver(),
+// Settings.Gservices.SSL_SESSION_CACHE);
+//
+// if (Log.isLoggable(TAG, Log.DEBUG)) {
+// Log.d(TAG, "enabled " + sslCache + " " + androidContext.getPackageName());
+// }
+//
+// return SAVE_ON_ADD.equals(sslCache);
+// }
+
+ /**
+ * You must call this method to enable SSL session caching for an app.
+ */
+ public synchronized static void init(Context activityContext) {
+ // It is possible that multiple provider will try to install this hook.
+ // We want a single db per VM.
+ if (sHookInitializationDone) {
+ return;
+ }
+
+
+// // More values can be added in future to provide different
+// // behaviours, like 'batch save'.
+// if (enabled(activityContext)) {
+ Context appContext = activityContext.getApplicationContext();
+ sDefaultDatabaseHelper = new DatabaseHelper(appContext);
+
+ // Set default SSLSocketFactory
+ // The property is defined in the javadocs for javax.net.SSLSocketFactory
+ // (no constant defined there)
+ // This should cover all code using SSLSocketFactory.getDefault(),
+ // including native http client and apache httpclient.
+ // MCS is using its own custom factory - will need special code.
+// Security.setProperty("ssl.SocketFactory.provider",
+// SslSocketFactoryWithCache.class.getName());
+// }
+
+ // Won't try again.
+ sHookInitializationDone = true;
+ }
+
+ public void putSessionData(SSLSession session, byte[] der) {
+ if (mDatabaseHelper == null) {
+ return;
+ }
+ if (mExternalCache.size() > MAX_CACHE_SIZE) {
+ // remove oldest.
+ Cursor byTime = mDatabaseHelper.getWritableDatabase().query(SSL_CACHE_TABLE,
+ PROJECTION, null, null, null, null, SSL_CACHE_TIME_SEC);
+ byTime.moveToFirst();
+ // TODO: can I do byTime.deleteRow() ?
+ String hostPort = byTime.getString(SSL_CACHE_HOSTPORT_COL);
+
+ mDatabaseHelper.getWritableDatabase().delete(SSL_CACHE_TABLE,
+ SSL_CACHE_HOSTPORT + "= ?" , new String[] { hostPort });
+ }
+ // 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);
+
+ synchronized (this.getClass()) {
+ mExternalCache.put(key, der);
+
+ try {
+ mDatabaseHelper.getWritableDatabase().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);
+ }
+ }
+
+ public byte[] getSessionData(byte[] id) {
+ // We support client side only - the cache will do nothing on client.
+ 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" +
+ ");");
+ db.execSQL("CREATE INDEX ssl_sessions_idx1 ON ssl_sessions (" +
+ SSL_CACHE_HOSTPORT + ");");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ db.execSQL("DROP TABLE IF EXISTS " + SSL_CACHE_TABLE );
+ onCreate(db);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/tests/CoreTests/android/core/SSLPerformanceTest.java b/tests/CoreTests/android/core/SSLPerformanceTest.java
new file mode 100644
index 0000000..e2bd9c5
--- /dev/null
+++ b/tests/CoreTests/android/core/SSLPerformanceTest.java
@@ -0,0 +1,432 @@
+/*
+ * 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 android.core;
+
+import android.test.AndroidTestCase;
+import android.os.Debug;
+import org.apache.harmony.xnet.provider.jsse.FileClientSessionCache;
+import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
+import org.apache.harmony.xnet.provider.jsse.SSLContextImpl;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.conn.SingleClientConnManager;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.HttpResponse;
+
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.security.cert.Certificate;
+import java.security.Principal;
+import java.security.KeyManagementException;
+import java.util.Arrays;
+
+public class SSLPerformanceTest extends AndroidTestCase {
+
+ static final byte[] SESSION_DATA = new byte[6000];
+ static {
+ for (int i = 0; i < SESSION_DATA.length; i++) {
+ SESSION_DATA[i] = (byte) i;
+ }
+ }
+
+ static final File dataDir = new File("/data/data/android.core/");
+ static final File filesDir = new File(dataDir, "files");
+ static final File dbDir = new File(dataDir, "databases");
+
+ static final String CACHE_DIR
+ = SSLPerformanceTest.class.getName() + "/cache";
+
+ static final int ITERATIONS = 10;
+
+ public void testCreateNewEmptyDatabase() {
+ deleteDatabase();
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ DatabaseSessionCache cache = new DatabaseSessionCache(getContext());
+ cache.getSessionData("crazybob.org", 443);
+
+ stopwatch.stop();
+ }
+
+ public void testCreateNewEmptyDirectory() throws IOException {
+ deleteDirectory();
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ SSLClientSessionCache cache = FileClientSessionCache.usingDirectory(
+ getCacheDirectory());
+ cache.getSessionData("crazybob.org", 443);
+
+ stopwatch.stop();
+ }
+
+ public void testOpenDatabaseWith10Sessions() {
+ deleteDatabase();
+
+ DatabaseSessionCache cache = new DatabaseSessionCache(getContext());
+ putSessionsIn(cache);
+ closeDatabase();
+
+ System.err.println("Size of ssl_sessions.db w/ 10 sessions: "
+ + new File(dbDir, "ssl_sessions.db").length());
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ cache = new DatabaseSessionCache(getContext());
+ cache.getSessionData("crazybob.org", 443);
+
+ stopwatch.stop();
+ }
+
+ public void testOpenDirectoryWith10Sessions() throws IOException {
+ deleteDirectory();
+
+ SSLClientSessionCache cache = FileClientSessionCache.usingDirectory(
+ getCacheDirectory());
+ putSessionsIn(cache);
+ closeDirectoryCache();
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ cache = FileClientSessionCache.usingDirectory(
+ getCacheDirectory());
+ cache.getSessionData("crazybob.org", 443);
+
+ stopwatch.stop();
+ }
+
+ public void testGetSessionFromDatabase() {
+ deleteDatabase();
+
+ DatabaseSessionCache cache = new DatabaseSessionCache(getContext());
+ cache.putSessionData(new FakeSession("foo"), SESSION_DATA);
+ closeDatabase();
+
+ cache = new DatabaseSessionCache(getContext());
+ cache.getSessionData("crazybob.org", 443);
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ byte[] sessionData = cache.getSessionData("foo", 443);
+
+ stopwatch.stop();
+
+ assertTrue(Arrays.equals(SESSION_DATA, sessionData));
+ }
+
+ public void testGetSessionFromDirectory() throws IOException {
+ deleteDirectory();
+
+ SSLClientSessionCache cache = FileClientSessionCache.usingDirectory(
+ getCacheDirectory());
+ cache.putSessionData(new FakeSession("foo"), SESSION_DATA);
+ closeDirectoryCache();
+
+ cache = FileClientSessionCache.usingDirectory(
+ getCacheDirectory());
+ cache.getSessionData("crazybob.org", 443);
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ byte[] sessionData = cache.getSessionData("foo", 443);
+
+ stopwatch.stop();
+
+ assertTrue(Arrays.equals(SESSION_DATA, sessionData));
+ }
+
+ public void testPutSessionIntoDatabase() {
+ deleteDatabase();
+
+ DatabaseSessionCache cache = new DatabaseSessionCache(getContext());
+ cache.getSessionData("crazybob.org", 443);
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ cache.putSessionData(new FakeSession("foo"), SESSION_DATA);
+
+ stopwatch.stop();
+ }
+
+ public void testPutSessionIntoDirectory() throws IOException {
+ deleteDirectory();
+
+ SSLClientSessionCache cache = FileClientSessionCache.usingDirectory(
+ getCacheDirectory());
+ cache.getSessionData("crazybob.org", 443);
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ cache.putSessionData(new FakeSession("foo"), SESSION_DATA);
+
+ stopwatch.stop();
+ }
+
+ public void testEngineInit() throws IOException, KeyManagementException {
+ Stopwatch stopwatch = new Stopwatch();
+
+ new SSLContextImpl().engineInit(null, null, null);
+
+ stopwatch.stop();
+ }
+
+ public void testWebRequestWithoutCache() throws IOException,
+ KeyManagementException {
+ SSLContextImpl sslContext = new SSLContextImpl();
+ sslContext.engineInit(null, null, null);
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ getVerisignDotCom(sslContext);
+
+ stopwatch.stop();
+ }
+
+ public void testWebRequestWithFileCache() throws IOException,
+ KeyManagementException {
+ deleteDirectory();
+
+ SSLContextImpl sslContext = new SSLContextImpl();
+ sslContext.engineInit(null, null, null,
+ FileClientSessionCache.usingDirectory(getCacheDirectory()),
+ null);
+
+ // Make sure www.google.com is in the cache.
+ getVerisignDotCom(sslContext);
+
+ // Re-initialize so we hit the file cache.
+ sslContext.engineInit(null, null, null,
+ FileClientSessionCache.usingDirectory(getCacheDirectory()),
+ null);
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ getVerisignDotCom(sslContext);
+
+ stopwatch.stop();
+ }
+
+ public void testWebRequestWithInMemoryCache() throws IOException,
+ KeyManagementException {
+ deleteDirectory();
+
+ SSLContextImpl sslContext = new SSLContextImpl();
+ sslContext.engineInit(null, null, null);
+
+ // Make sure www.google.com is in the cache.
+ getVerisignDotCom(sslContext);
+
+ Stopwatch stopwatch = new Stopwatch();
+
+ getVerisignDotCom(sslContext);
+
+ stopwatch.stop();
+ }
+
+ private void getVerisignDotCom(SSLContextImpl sslContext)
+ throws IOException {
+ SchemeRegistry schemeRegistry = new SchemeRegistry();
+ schemeRegistry.register(new Scheme("https",
+ new SSLSocketFactory(sslContext.engineGetSocketFactory()),
+ 443));
+
+ ClientConnectionManager manager =
+ new SingleClientConnManager(null, schemeRegistry);
+
+ new DefaultHttpClient(manager, null).execute(
+ new HttpGet("https://www.verisign.com"),
+ new ResponseHandler<Object>() {
+ public Object handleResponse(HttpResponse response)
+ throws ClientProtocolException, IOException {
+ return null;
+ }
+ });
+ }
+
+ private void putSessionsIn(SSLClientSessionCache cache) {
+ for (int i = 0; i < 10; i++) {
+ cache.putSessionData(new FakeSession("host" + i), SESSION_DATA);
+ }
+ }
+
+ private void deleteDatabase() {
+ closeDatabase();
+ if (!new File(dbDir, "ssl_sessions.db").delete()) {
+ System.err.println("Failed to delete database.");
+ }
+ }
+
+ private void closeDatabase() {
+ if (DatabaseSessionCache.sDefaultDatabaseHelper != null) {
+ DatabaseSessionCache.sDefaultDatabaseHelper.close();
+ }
+ DatabaseSessionCache.sDefaultDatabaseHelper = null;
+ DatabaseSessionCache.sHookInitializationDone = false;
+ DatabaseSessionCache.mNeedsCacheLoad = true;
+ }
+
+ private void deleteDirectory() {
+ closeDirectoryCache();
+
+ File dir = getCacheDirectory();
+ if (!dir.exists()) {
+ return;
+ }
+ for (File file : dir.listFiles()) {
+ file.delete();
+ }
+ if (!dir.delete()) {
+ System.err.println("Failed to delete directory.");
+ }
+ }
+
+ private void closeDirectoryCache() {
+ try {
+ Method reset = FileClientSessionCache.class
+ .getDeclaredMethod("reset");
+ reset.setAccessible(true);
+ reset.invoke(null);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private File getCacheDirectory() {
+ return new File(getContext().getFilesDir(), CACHE_DIR);
+ }
+
+ class Stopwatch {
+ {
+ Debug.startAllocCounting();
+ }
+ long start = System.nanoTime();
+
+ void stop() {
+ long elapsed = (System.nanoTime() - start) / 1000;
+ Debug.stopAllocCounting();
+ System.err.println(getName() + ": " + elapsed + "us, "
+ + Debug.getThreadAllocCount() + " allocations, "
+ + Debug.getThreadAllocSize() + " bytes");
+ }
+ }
+}
+
+class FakeSession implements SSLSession {
+ final String host;
+
+ FakeSession(String host) {
+ this.host = host;
+ }
+
+ public int getApplicationBufferSize() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getCipherSuite() {
+ throw new UnsupportedOperationException();
+ }
+
+ public long getCreationTime() {
+ throw new UnsupportedOperationException();
+ }
+
+ public byte[] getId() {
+ return host.getBytes();
+ }
+
+ public long getLastAccessedTime() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Certificate[] getLocalCertificates() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Principal getLocalPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getPacketBufferSize() {
+ throw new UnsupportedOperationException();
+ }
+
+ public javax.security.cert.X509Certificate[] getPeerCertificateChain() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Certificate[] getPeerCertificates() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getPeerHost() {
+ return host;
+ }
+
+ public int getPeerPort() {
+ return 443;
+ }
+
+ public Principal getPeerPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+ public SSLSessionContext getSessionContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getValue(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String[] getValueNames() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void invalidate() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isValid() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void putValue(String name, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void removeValue(String name) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/tests/CoreTests/android/core/SSLSocketTest.java b/tests/CoreTests/android/core/SSLSocketTest.java
index 922090a..088fa8c 100644
--- a/tests/CoreTests/android/core/SSLSocketTest.java
+++ b/tests/CoreTests/android/core/SSLSocketTest.java
@@ -19,9 +19,13 @@ package android.core;
import junit.framework.TestCase;
import org.apache.commons.codec.binary.Base64;
+import org.apache.harmony.xnet.provider.jsse.SSLContextImpl;
+import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
+import org.apache.harmony.xnet.provider.jsse.FileClientSessionCache;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -29,18 +33,28 @@ import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.KeyStore;
+import java.security.KeyManagementException;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Random;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
+/**
+ * SSL integration tests that hit real servers.
+ */
public class SSLSocketTest extends TestCase {
private static SSLSocketFactory clientFactory =
@@ -61,13 +75,15 @@ public class SSLSocketTest extends TestCase {
* @param delay The delay after each request (in seconds).
* @throws IOException When a problem occurs.
*/
- private void fetch(String host, int port, boolean secure, String path,
- int outerLoop, int innerLoop, int delay, int timeout) throws IOException {
+ private void fetch(SSLSocketFactory socketFactory, String host, int port,
+ boolean secure, String path, int outerLoop, int innerLoop,
+ int delay, int timeout) throws IOException {
InetSocketAddress address = new InetSocketAddress(host, port);
for (int i = 0; i < outerLoop; i++) {
// Connect to the remote host
- Socket socket = secure ? clientFactory.createSocket() : new Socket();
+ Socket socket = secure ? socketFactory.createSocket()
+ : new Socket();
if (timeout >= 0) {
socket.setKeepAlive(true);
socket.setSoTimeout(timeout * 1000);
@@ -159,6 +175,16 @@ public class SSLSocketTest extends TestCase {
}
/**
+ * Invokes fetch() with the default socket factory.
+ */
+ private void fetch(String host, int port, boolean secure, String path,
+ int outerLoop, int innerLoop,
+ int delay, int timeout) throws IOException {
+ fetch(clientFactory, host, port, secure, path, outerLoop, innerLoop,
+ delay, timeout);
+ }
+
+ /**
* Does a single request for each of the hosts. Consumes the response.
*
* @throws IOException If a problem occurs.
@@ -619,13 +645,17 @@ public class SSLSocketTest extends TestCase {
public void run() {
try {
- KeyManager[] keyManagers = provideKeys ? getKeyManagers(SERVER_KEYS_BKS) : null;
- TrustManager[] trustManagers = new TrustManager[] { trustManager };
+ KeyManager[] keyManagers = provideKeys
+ ? getKeyManagers(SERVER_KEYS_BKS) : null;
+ TrustManager[] trustManagers = new TrustManager[] {
+ trustManager };
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
- SSLServerSocket serverSocket = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket();
+ SSLServerSocket serverSocket
+ = (SSLServerSocket) sslContext.getServerSocketFactory()
+ .createServerSocket();
if (clientAuth == CLIENT_AUTH_WANTED) {
serverSocket.setWantClientAuth(true);
@@ -637,14 +667,15 @@ public class SSLSocketTest extends TestCase {
serverSocket.bind(new InetSocketAddress(port));
- SSLSocket clientSocket = (SSLSocket)serverSocket.accept();
+ SSLSocket clientSocket = (SSLSocket) serverSocket.accept();
InputStream stream = clientSocket.getInputStream();
for (int i = 0; i < 256; i++) {
int j = stream.read();
if (i != j) {
- throw new RuntimeException("Error reading socket, expected " + i + ", got " + j);
+ throw new RuntimeException("Error reading socket,"
+ + " expected " + i + ", got " + j);
}
}
@@ -690,13 +721,16 @@ public class SSLSocketTest extends TestCase {
public void run() {
try {
- KeyManager[] keyManagers = provideKeys ? getKeyManagers(CLIENT_KEYS_BKS) : null;
- TrustManager[] trustManagers = new TrustManager[] { trustManager };
+ KeyManager[] keyManagers = provideKeys
+ ? getKeyManagers(CLIENT_KEYS_BKS) : null;
+ TrustManager[] trustManagers = new TrustManager[] {
+ trustManager };
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
- SSLSocket socket = (SSLSocket)sslContext.getSocketFactory().createSocket();
+ SSLSocket socket = (SSLSocket) sslContext.getSocketFactory()
+ .createSocket();
socket.connect(new InetSocketAddress(port));
socket.startHandshake();
@@ -867,6 +901,189 @@ public class SSLSocketTest extends TestCase {
fail("SSL handshake should have failed.");
}
}
-
-
+
+ /**
+ * Tests our in-memory and persistent caching support.
+ */
+ public void testClientSessionCaching() throws IOException,
+ KeyManagementException {
+ SSLContextImpl context = new SSLContextImpl();
+
+ // Cache size = 2.
+ FakeClientSessionCache fakeCache = new FakeClientSessionCache();
+ context.engineInit(null, null, null, fakeCache, null);
+ SSLSocketFactory socketFactory = context.engineGetSocketFactory();
+ context.engineGetClientSessionContext().setSessionCacheSize(2);
+ makeRequests(socketFactory);
+ List<String> smallCacheOps = Arrays.asList(
+ "get www.fortify.net",
+ "put www.fortify.net",
+ "get www.paypal.com",
+ "put www.paypal.com",
+ "get www.yellownet.ch",
+ "put www.yellownet.ch",
+
+ // At this point, all in-memory cache requests should miss,
+ // but the sessions will still be in the persistent cache.
+ "get www.fortify.net",
+ "get www.paypal.com",
+ "get www.yellownet.ch"
+ );
+ assertEquals(smallCacheOps, fakeCache.ops);
+
+ // Cache size = 3.
+ fakeCache = new FakeClientSessionCache();
+ context.engineInit(null, null, null, fakeCache, null);
+ socketFactory = context.engineGetSocketFactory();
+ context.engineGetClientSessionContext().setSessionCacheSize(3);
+ makeRequests(socketFactory);
+ List<String> bigCacheOps = Arrays.asList(
+ "get www.fortify.net",
+ "put www.fortify.net",
+ "get www.paypal.com",
+ "put www.paypal.com",
+ "get www.yellownet.ch",
+ "put www.yellownet.ch"
+
+ // At this point, all results should be in the in-memory
+ // cache, and the persistent cache shouldn't be hit anymore.
+ );
+ assertEquals(bigCacheOps, fakeCache.ops);
+
+ // Cache size = 4.
+ fakeCache = new FakeClientSessionCache();
+ context.engineInit(null, null, null, fakeCache, null);
+ socketFactory = context.engineGetSocketFactory();
+ context.engineGetClientSessionContext().setSessionCacheSize(4);
+ makeRequests(socketFactory);
+ assertEquals(bigCacheOps, fakeCache.ops);
+ }
+
+ /**
+ * Executes sequence of requests twice using given socket factory.
+ */
+ private void makeRequests(SSLSocketFactory socketFactory)
+ throws IOException {
+ for (int i = 0; i < 2; i++) {
+ fetch(socketFactory, "www.fortify.net", 443, true, "/sslcheck.html",
+ 1, 1, 0, 60);
+ fetch(socketFactory, "www.paypal.com", 443, true, "/",
+ 1, 1, 0, 60);
+ fetch(socketFactory, "www.yellownet.ch", 443, true, "/",
+ 1, 1, 0, 60);
+ }
+ }
+
+ /**
+ * Fake in the sense that it doesn't actually persist anything.
+ */
+ static class FakeClientSessionCache implements SSLClientSessionCache {
+
+ List<String> ops = new ArrayList<String>();
+ Map<String, byte[]> sessions = new HashMap<String, byte[]>();
+
+ public byte[] getSessionData(String host, int port) {
+ ops.add("get " + host);
+ return sessions.get(host);
+ }
+
+ public void putSessionData(SSLSession session, byte[] sessionData) {
+ String host = session.getPeerHost();
+ System.err.println("length: " + sessionData.length);
+ ops.add("put " + host);
+ sessions.put(host, sessionData);
+ }
+ }
+
+ public void testFileBasedClientSessionCache() throws IOException,
+ KeyManagementException {
+ SSLContextImpl context = new SSLContextImpl();
+ String tmpDir = System.getProperty("java.io.tmpdir");
+ if (tmpDir == null) {
+ fail("Please set 'java.io.tmpdir' system property.");
+ }
+ File cacheDir = new File(tmpDir
+ + "/" + SSLSocketTest.class.getName() + "/cache");
+ deleteDir(cacheDir);
+ SSLClientSessionCache fileCache
+ = FileClientSessionCache.usingDirectory(cacheDir);
+ try {
+ ClientSessionCacheProxy cacheProxy
+ = new ClientSessionCacheProxy(fileCache);
+ context.engineInit(null, null, null, cacheProxy, null);
+ SSLSocketFactory socketFactory = context.engineGetSocketFactory();
+ context.engineGetClientSessionContext().setSessionCacheSize(1);
+ makeRequests(socketFactory);
+ List<String> expected = Arrays.asList(
+ "unsuccessful get www.fortify.net",
+ "put www.fortify.net",
+ "unsuccessful get www.paypal.com",
+ "put www.paypal.com",
+ "unsuccessful get www.yellownet.ch",
+ "put www.yellownet.ch",
+
+ // At this point, all in-memory cache requests should miss,
+ // but the sessions will still be in the persistent cache.
+ "successful get www.fortify.net",
+ "successful get www.paypal.com",
+ "successful get www.yellownet.ch"
+ );
+ assertEquals(expected, cacheProxy.ops);
+
+ // Try again now that file-based cache is populated.
+ fileCache = FileClientSessionCache.usingDirectory(cacheDir);
+ cacheProxy = new ClientSessionCacheProxy(fileCache);
+ context.engineInit(null, null, null, cacheProxy, null);
+ socketFactory = context.engineGetSocketFactory();
+ context.engineGetClientSessionContext().setSessionCacheSize(1);
+ makeRequests(socketFactory);
+ expected = Arrays.asList(
+ "successful get www.fortify.net",
+ "successful get www.paypal.com",
+ "successful get www.yellownet.ch",
+ "successful get www.fortify.net",
+ "successful get www.paypal.com",
+ "successful get www.yellownet.ch"
+ );
+ assertEquals(expected, cacheProxy.ops);
+ } finally {
+ deleteDir(cacheDir);
+ }
+ }
+
+ private static void deleteDir(File directory) {
+ if (!directory.exists()) {
+ return;
+ }
+ for (File file : directory.listFiles()) {
+ file.delete();
+ }
+ directory.delete();
+ }
+
+ static class ClientSessionCacheProxy implements SSLClientSessionCache {
+
+ final SSLClientSessionCache delegate;
+ final List<String> ops = new ArrayList<String>();
+
+ ClientSessionCacheProxy(SSLClientSessionCache delegate) {
+ this.delegate = delegate;
+ }
+
+ public byte[] getSessionData(String host, int port) {
+ byte[] sessionData = delegate.getSessionData(host, port);
+ ops.add((sessionData == null ? "unsuccessful" : "successful")
+ + " get " + host);
+ return sessionData;
+ }
+
+ public void putSessionData(SSLSession session, byte[] sessionData) {
+ delegate.putSessionData(session, sessionData);
+ ops.add("put " + session.getPeerHost());
+ }
+ }
+
+ public static void main(String[] args) throws KeyManagementException, IOException {
+ new SSLSocketTest().testFileBasedClientSessionCache();
+ }
}
diff --git a/tests/CoreTests/android/location/LocationManagerProximityTest.java b/tests/CoreTests/android/location/LocationManagerProximityTest.java
index 5f62983..e1501e3 100644
--- a/tests/CoreTests/android/location/LocationManagerProximityTest.java
+++ b/tests/CoreTests/android/location/LocationManagerProximityTest.java
@@ -23,6 +23,7 @@ import android.content.IntentFilter;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
+import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
@@ -33,8 +34,10 @@ import android.util.Log;
* TODO: add tests for more scenarios
*
* To run:
- * adb shell am instrument -e class com.google.android.mapstests.api.LocationProximityTest \
- * -w com.google.android.mapstests/.MapInstrumentationTestRunner
+ * adb shell am instrument -e class android.location.LocationManagerProximityTest \
+ * -w android.core/android.test.InstrumentationTestRunner
+ *
+ * This test requires that the "Allow mock locations" setting be enabled
*
*/
@MediumTest
@@ -46,8 +49,6 @@ public class LocationManagerProximityTest extends AndroidTestCase {
private LocationManager mLocationManager;
private PendingIntent mPendingIntent;
private TestIntentReceiver mIntentReceiver;
- private String mOriginalAllowedProviders;
- private int mOriginalMocksAllowed;
private static final String LOG_TAG = "LocationProximityTest";
@@ -60,27 +61,13 @@ public class LocationManagerProximityTest extends AndroidTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
-
- // allow mock locations
- mOriginalMocksAllowed =
- android.provider.Settings.Secure.getInt(getContext().getContentResolver(),
- android.provider.Settings.Secure.ALLOW_MOCK_LOCATION, 0);
-
- android.provider.Settings.Secure.putInt(getContext().getContentResolver(),
- android.provider.Settings.Secure.ALLOW_MOCK_LOCATION, 1);
-
- mOriginalAllowedProviders =
- android.provider.Settings.Secure.getString(
- getContext().getContentResolver(),
- android.provider.Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
-
- // ensure 'only' the mock provider is enabled
- // need to do this so the proximity listener does not ignore the mock
- // updates in favor of gps updates
- android.provider.Settings.Secure.putString(
- getContext().getContentResolver(),
- android.provider.Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- PROVIDER_NAME);
+
+ // test that mock locations are allowed so a more descriptive error message can be logged
+ if (Settings.Secure.getInt(getContext().getContentResolver(),
+ Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 0) {
+ fail("Mock locations are currently disabled in Settings - this test requires " +
+ "mock locations");
+ }
mLocationManager = (LocationManager) getContext().
getSystemService(Context.LOCATION_SERVICE);
@@ -109,18 +96,6 @@ public class LocationManagerProximityTest extends AndroidTestCase {
if (mIntentReceiver != null) {
getContext().unregisterReceiver(mIntentReceiver);
}
-
- android.provider.Settings.Secure.putInt(getContext().getContentResolver(),
- android.provider.Settings.Secure.ALLOW_MOCK_LOCATION, mOriginalMocksAllowed);
-
- if (mOriginalAllowedProviders != null) {
- // restore original settings
- android.provider.Settings.Secure.putString(
- getContext().getContentResolver(),
- android.provider.Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- mOriginalAllowedProviders);
- mLocationManager.updateProviders();
- }
}
/**
diff --git a/tests/CoreTests/run_core_test.sh b/tests/CoreTests/run_core_test.sh
index 1fc3348..ffa31ed 100755
--- a/tests/CoreTests/run_core_test.sh
+++ b/tests/CoreTests/run_core_test.sh
@@ -1,4 +1,6 @@
framework=/system/framework
bpath=$framework/core.jar:$framework/ext.jar:$framework/framework.jar:$framework/android.test.runner.jar
-adb shell exec dalvikvm -Xbootclasspath:$bpath -cp system/app/CoreTests.apk \
+adb shell exec dalvikvm -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=3001 \
+ -Xbootclasspath:$bpath -cp /data/app/android.core.apk \
+ -Djava.io.tmpdir=/sdcard/tmp \
com.android.internal.util.WithFramework junit.textui.TestRunner $*
diff --git a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
index 6c71e86..17f6bdc 100755
--- a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
+++ b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
@@ -83,10 +83,6 @@ public class InputTypeActivity extends Activity {
mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_NORMAL|EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT,
R.string.auto_correct_edit_text_label));
- /* Normal Edit Text w/Search Flag*/
- mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_NORMAL|EditorInfo.TYPE_TEXT_FLAG_SEARCH,
- R.string.search_edit_text_label));
-
/* Uri Edit Text */
mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_URI,
R.string.uri_edit_text_label));
diff --git a/tests/gadgets/GadgetProviderTest/res/layout/test_gadget.xml b/tests/gadgets/GadgetProviderTest/res/layout/test_gadget.xml
index 4d483c7..e0a416e 100644
--- a/tests/gadgets/GadgetProviderTest/res/layout/test_gadget.xml
+++ b/tests/gadgets/GadgetProviderTest/res/layout/test_gadget.xml
@@ -16,8 +16,11 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/oh_hai_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="150dp"
+ android:layout_height="150dp"
android:text="@string/oh_hai"
+ android:background="#8fff"
+ android:textColor="#000"
+ android:textStyle="bold"
/>
diff --git a/tests/gadgets/GadgetProviderTest/res/xml/gadget_info.xml b/tests/gadgets/GadgetProviderTest/res/xml/gadget_info.xml
index 0fc7812..33cc2e3 100644
--- a/tests/gadgets/GadgetProviderTest/res/xml/gadget_info.xml
+++ b/tests/gadgets/GadgetProviderTest/res/xml/gadget_info.xml
@@ -1,7 +1,7 @@
<gadget-provider xmlns:android="http://schemas.android.com/apk/res/android"
- android:minWidth="40dp"
- android:minHeight="30dp"
- android:updatePeriodMillis="60000"
+ android:minWidth="150dp"
+ android:minHeight="150dp"
+ android:updatePeriodMillis="2000"
android:initialLayout="@layout/test_gadget"
>
</gadget-provider>