Merge "Porting Unsubmitted Cupcake CookieSyncManagerTest" into eclair
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 4bf8239..6eb1302 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -903,6 +903,9 @@
android:resource="@xml/authenticator" />
</service>
+ <activity android:name="android.opengl.cts.GLSurfaceViewStubActivity"
+ android:label="GLSurfaceViewStub"/>
+
</application>
<!--Test for PackageManager, please put this at the very beginning-->
diff --git a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
index 4ca1cc2..5ac7251 100644
--- a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
+++ b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
@@ -16,30 +16,26 @@
package android.test;
-import com.android.internal.util.Predicate;
-import com.android.internal.util.Predicates;
-
-import dalvik.annotation.BrokenTest;
-import dalvik.annotation.SideEffect;
-
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.test.suitebuilder.TestMethod;
-import android.test.suitebuilder.annotation.HasAnnotation;
-import android.util.Log;
-
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.TimeZone;
+import com.android.internal.util.Predicate;
+import com.android.internal.util.Predicates;
+
+import dalvik.annotation.BrokenTest;
+import dalvik.annotation.SideEffect;
+
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestListener;
+import android.os.Bundle;
+import android.test.suitebuilder.TestMethod;
+import android.test.suitebuilder.annotation.HasAnnotation;
+import android.util.Log;
/**
* This test runner extends the default InstrumentationTestRunner. It overrides
@@ -56,50 +52,37 @@
/**
* Convenience definition of our log tag.
- */
+ */
private static final String TAG = "InstrumentationCtsTestRunner";
-
+
/**
* True if (and only if) we are running in single-test mode (as opposed to
* batch mode).
*/
private boolean singleTest = false;
-
+
@Override
public void onCreate(Bundle arguments) {
// We might want to move this to /sdcard, if is is mounted/writable.
File cacheDir = getTargetContext().getCacheDir();
- // Set some properties that the core tests absolutely need.
+ // Set some properties that the core tests absolutely need.
System.setProperty("user.language", "en");
System.setProperty("user.region", "US");
-
+
System.setProperty("java.home", cacheDir.getAbsolutePath());
System.setProperty("user.home", cacheDir.getAbsolutePath());
System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
System.setProperty("javax.net.ssl.trustStore",
"/etc/security/cacerts.bks");
-
+
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
-
+
if (arguments != null) {
String classArg = arguments.getString(ARGUMENT_TEST_CLASS);
- singleTest = classArg != null && classArg.contains("#");
+ singleTest = classArg != null && classArg.contains("#");
}
-
- // attempt to disable keyguard, if current test has permission to do so
- // TODO: move this to a better place, such as InstrumentationTestRunner ?
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
- == PackageManager.PERMISSION_GRANTED) {
- Log.i(TAG, "Disabling keyguard");
- KeyguardManager keyguardManager =
- (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
- keyguardManager.newKeyguardLock("cts").disableKeyguard();
- } else {
- Log.i(TAG, "Test lacks permission to disable keyguard. " +
- "UI based tests may fail if keyguard is up");
- }
-
+
super.onCreate(arguments);
}
@@ -109,36 +92,36 @@
runner.addTestListener(new TestListener() {
/**
- * The last test class we executed code from.
+ * The last test class we executed code from.
*/
private Class<?> lastClass;
-
+
/**
* The minimum time we expect a test to take.
*/
private static final int MINIMUM_TIME = 100;
-
+
/**
* The start time of our current test in System.currentTimeMillis().
*/
private long startTime;
-
+
public void startTest(Test test) {
if (test.getClass() != lastClass) {
lastClass = test.getClass();
printMemory(test.getClass());
}
-
+
Thread.currentThread().setContextClassLoader(
test.getClass().getClassLoader());
-
+
startTime = System.currentTimeMillis();
}
-
+
public void endTest(Test test) {
if (test instanceof TestCase) {
cleanup((TestCase)test);
-
+
/*
* Make sure all tests take at least MINIMUM_TIME to
* complete. If they don't, we wait a bit. The Cupcake
@@ -146,7 +129,7 @@
* short time, which causes headache for the CTS.
*/
long timeTaken = System.currentTimeMillis() - startTime;
-
+
if (timeTaken < MINIMUM_TIME) {
try {
Thread.sleep(MINIMUM_TIME - timeTaken);
@@ -156,15 +139,15 @@
}
}
}
-
+
public void addError(Test test, Throwable t) {
// This space intentionally left blank.
}
-
+
public void addFailure(Test test, AssertionFailedError t) {
// This space intentionally left blank.
}
-
+
/**
* Dumps some memory info.
*/
@@ -174,7 +157,7 @@
long total = runtime.totalMemory();
long free = runtime.freeMemory();
long used = total - free;
-
+
Log.d(TAG, "Total memory : " + total);
Log.d(TAG, "Used memory : " + used);
Log.d(TAG, "Free memory : " + free);
@@ -190,7 +173,7 @@
*/
private void cleanup(TestCase test) {
Class<?> clazz = test.getClass();
-
+
while (clazz != TestCase.class) {
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
@@ -205,15 +188,15 @@
}
}
}
-
+
clazz = clazz.getSuperclass();
}
}
-
+
});
-
+
return runner;
- }
+ }
@Override
List<Predicate<TestMethod>> getBuilderRequirements() {
diff --git a/tests/src/android/opengl/cts/GLSurfaceViewStubActivity.java b/tests/src/android/opengl/cts/GLSurfaceViewStubActivity.java
new file mode 100644
index 0000000..5a8f310
--- /dev/null
+++ b/tests/src/android/opengl/cts/GLSurfaceViewStubActivity.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 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.opengl.cts;
+
+import android.app.Activity;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A minimal activity for testing {@link android.opengl.GLSurfaceView}.
+ */
+public class GLSurfaceViewStubActivity extends Activity {
+
+ private static class Renderer implements GLSurfaceView.Renderer {
+
+ public void onDrawFrame(GL10 gl) {
+ // Do nothing.
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ // Do nothing.
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ // Do nothing.
+ }
+ }
+
+ private GLSurfaceView mView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mView = new GLSurfaceView(this);
+ mView.setRenderer(new Renderer());
+ setContentView(mView);
+ }
+
+ public GLSurfaceView getView() {
+ return mView;
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+}
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
index 1d9affa5..5e06d36 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
@@ -1203,7 +1203,7 @@
assertNull(mContextWrapper.getSystemService("invalid"));
// Test valid service name
- assertNotNull(mContextWrapper.getSystemService("window"));
+ assertNotNull(mContextWrapper.getSystemService(Context.WINDOW_SERVICE));
}
@TestTargetNew(
diff --git a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
index bc404fe..14462a0 100644
--- a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
+++ b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
@@ -67,6 +67,15 @@
mTestAbstractCursor = new TestAbstractCursor(COLUMN_NAMES, list);
}
+ @Override
+ protected void tearDown() throws Exception {
+ mDatabase.close();
+ if (mDatabaseFile.exists()) {
+ mDatabaseFile.delete();
+ }
+ super.tearDown();
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "AbstractCursor",
diff --git a/tests/tests/database/src/android/database/cts/CursorWrapperTest.java b/tests/tests/database/src/android/database/cts/CursorWrapperTest.java
index c32cd89..507b2a3 100644
--- a/tests/tests/database/src/android/database/cts/CursorWrapperTest.java
+++ b/tests/tests/database/src/android/database/cts/CursorWrapperTest.java
@@ -19,6 +19,8 @@
import java.io.File;
import java.util.Arrays;
+import junit.framework.TestCase;
+
import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentProvider;
@@ -39,7 +41,7 @@
import dalvik.annotation.TestTargetClass;
@TestTargetClass(android.database.CursorWrapper.class)
-public class CursorWrapperTest extends DatabaseCursorTest {
+public class CursorWrapperTest extends TestCase {
private static final String FIRST_NUMBER = "123";
private static final String SECOND_NUMBER = "5555";
@@ -61,7 +63,6 @@
@Override
protected void setUp() throws Exception {
super.setUp();
- setupTestType(TYPE_CURSORWRAPPER);
setupDatabase();
}
diff --git a/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java b/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
index 0791bcd..bc351f5 100644
--- a/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
+++ b/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
@@ -454,17 +454,26 @@
})
@ToBeFixed(bug = "1676383", explanation = "setPageSize does not work as javadoc declares.")
public void testAccessPageSize() {
- mDatabaseFile = new File(mDatabaseDir, "database.db");
- if (mDatabaseFile.exists()) {
- mDatabaseFile.delete();
+ File databaseFile = new File(mDatabaseDir, "database.db");
+ if (databaseFile.exists()) {
+ databaseFile.delete();
}
- mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
+ SQLiteDatabase database = null;
+ try {
+ database = SQLiteDatabase.openOrCreateDatabase(databaseFile.getPath(), null);
- long initialValue = mDatabase.getPageSize();
- // check that this does not throw an exception
- // setting a different page size may not be supported after the DB has been created
- mDatabase.setPageSize(initialValue);
- assertEquals(initialValue, mDatabase.getPageSize());
+ long initialValue = database.getPageSize();
+ // check that this does not throw an exception
+ // setting a different page size may not be supported after the DB has been created
+ database.setPageSize(initialValue);
+ assertEquals(initialValue, database.getPageSize());
+
+ } finally {
+ if (database != null) {
+ database.close();
+ databaseFile.delete();
+ }
+ }
}
@TestTargetNew(
@@ -827,9 +836,16 @@
public void testIsReadOnly() {
assertFalse(mDatabase.isReadOnly());
- mDatabase = SQLiteDatabase.openDatabase(mDatabaseFilePath, null,
- SQLiteDatabase.OPEN_READONLY);
- assertTrue(mDatabase.isReadOnly());
+ SQLiteDatabase database = null;
+ try {
+ database = SQLiteDatabase.openDatabase(mDatabaseFilePath, null,
+ SQLiteDatabase.OPEN_READONLY);
+ assertTrue(database.isReadOnly());
+ } finally {
+ if (database != null) {
+ database.close();
+ }
+ }
}
@TestTargetNew(
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
index f62fea8..3b376fd 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
@@ -87,8 +87,7 @@
new NinePatchDrawable(bmp, chunk, r, name);
- // Omit for now - known failure, fixed in froyo. Bug 2219785
- //new NinePatchDrawable(new NinePatch(bmp, chunk, name));
+ new NinePatchDrawable(new NinePatch(bmp, chunk, name));
chunk = new byte[MIN_CHUNK_SIZE - 1];
chunk[MIN_CHUNK_SIZE - 2] = 1;
diff --git a/tests/tests/graphics/src/android/opengl/cts/GLSurfaceViewTest.java b/tests/tests/graphics/src/android/opengl/cts/GLSurfaceViewTest.java
new file mode 100644
index 0000000..4f55f96
--- /dev/null
+++ b/tests/tests/graphics/src/android/opengl/cts/GLSurfaceViewTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 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.opengl.cts;
+
+import android.opengl.GLSurfaceView;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.util.Log;
+
+import dalvik.annotation.TestTargetClass;
+
+/**
+ * Tests for the GLSurfaceView class.
+ */
+@TestTargetClass(GLSurfaceView.class)
+public class GLSurfaceViewTest extends
+ ActivityInstrumentationTestCase2<GLSurfaceViewStubActivity> {
+
+ private static final int NUM_PAUSE_RESUME_ITERATIONS_WITHOUT_DELAY = 1000;
+
+ private static final int NUM_PAUSE_RESUME_ITERATIONS_WITH_DELAY = 100;
+
+ private static final int PAUSE_RESUME_DELAY = 10;
+
+ private static final boolean LOG_PAUSE_RESUME = false;
+
+ private static final String TAG = "GLSurfaceViewTest";
+
+ private GLSurfaceViewStubActivity mActivity;
+
+ public GLSurfaceViewTest() {
+ super("com.android.cts.stub", GLSurfaceViewStubActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ /**
+ * Test repeated pausing and resuming of a GLSurfaceView with a delay
+ * between iterations.
+ * <p>
+ * This test simply verifies that the system is able to perform multiple
+ * pause/resume sequences without crashing. The delay is used to allow
+ * asynchronous events to occur in between the pause and resume operations.
+ * </p>
+ *
+ * @throws InterruptedException
+ */
+ @UiThreadTest
+ public void testPauseResumeWithDelay() throws InterruptedException {
+ GLSurfaceView view = mActivity.getView();
+ for (int i = 0; i < NUM_PAUSE_RESUME_ITERATIONS_WITH_DELAY; i++) {
+ Thread.sleep(PAUSE_RESUME_DELAY);
+ if (LOG_PAUSE_RESUME) {
+ Log.w(TAG, "Pause/Resume (w/ delay) step " + i + " - pause");
+ }
+ view.onPause();
+ Thread.sleep(PAUSE_RESUME_DELAY);
+ if (LOG_PAUSE_RESUME) {
+ Log.w(TAG, "Pause/Resume (w/ delay) step " + i + " - resume");
+ }
+ view.onResume();
+ }
+ }
+
+ /**
+ * Test repeated pausing and resuming of a GLSurfaceView.
+ * <p>
+ * This test simply verifies that the system is able to perform multiple
+ * pause/resume sequences without crashing. No delay is used so that a
+ * larger number of iterations can be done in a short amount of time.
+ * </p>
+ */
+ @UiThreadTest
+ public void testPauseResumeWithoutDelay() {
+ GLSurfaceView view = mActivity.getView();
+ for (int i = 0; i < NUM_PAUSE_RESUME_ITERATIONS_WITHOUT_DELAY; i++) {
+ if (LOG_PAUSE_RESUME) {
+ Log.w(TAG, "Pause/Resume (no delay) step " + i + " - pause");
+ }
+ view.onPause();
+ if (LOG_PAUSE_RESUME) {
+ Log.w(TAG, "Pause/Resume (no delay) step " + i + " - resume");
+ }
+ view.onResume();
+ }
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 90b2bf9..9ecbf20 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -22,6 +22,8 @@
import dalvik.annotation.TestTargets;
import android.content.Context;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
import android.os.Looper;
import android.os.cts.TestThread;
import android.telephony.CellLocation;
@@ -29,6 +31,8 @@
import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
+import java.util.regex.Pattern;
+
@TestTargetClass(TelephonyManager.class)
public class TelephonyManagerTest extends AndroidTestCase {
private TelephonyManager mTelephonyManager;
@@ -266,4 +270,137 @@
mTelephonyManager.getDeviceId();
mTelephonyManager.getDeviceSoftwareVersion();
}
+
+ /**
+ * Tests that the device properly reports either a valid IMEI if GSM,
+ * a valid MEID if CDMA, or a valid MAC address if only a WiFi device.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getDeviceId",
+ args = {}
+ )
+ public void testGetDeviceId() {
+ String deviceId = mTelephonyManager.getDeviceId();
+ int phoneType = mTelephonyManager.getPhoneType();
+ switch (phoneType) {
+ case TelephonyManager.PHONE_TYPE_GSM:
+ assertImeiDeviceId(deviceId);
+ break;
+
+ case TelephonyManager.PHONE_TYPE_CDMA:
+ assertMeidDeviceId(deviceId);
+ break;
+
+ case TelephonyManager.PHONE_TYPE_NONE:
+ assertMacAddressReported();
+ break;
+
+ default:
+ throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
+ }
+ }
+
+ private static void assertImeiDeviceId(String deviceId) {
+ assertImeiFormat(deviceId);
+ assertImeiCheckDigit(deviceId);
+ assertReportingBodyIdentifier(deviceId, true); // Must be decimal identifier
+ }
+
+ private static void assertImeiFormat(String deviceId) {
+ // IMEI must include the check digit
+ String imeiPattern = "[0-9]{15}";
+ assertTrue("IMEI device id " + deviceId + " does not match pattern " + imeiPattern,
+ Pattern.matches(imeiPattern, deviceId));
+ }
+
+ private static void assertImeiCheckDigit(String deviceId) {
+ int expectedCheckDigit = getLuhnCheckDigit(deviceId.substring(0, 14));
+ int actualCheckDigit = Character.digit(deviceId.charAt(14), 10);
+ assertEquals("Incorrect check digit for " + deviceId, expectedCheckDigit, actualCheckDigit);
+ }
+
+ /**
+ * Use decimal value (0-9) to index into array to get sum of its digits
+ * needed by Lunh check.
+ *
+ * Example: DOUBLE_DIGIT_SUM[6] = 3 because 6 * 2 = 12 => 1 + 2 = 3
+ */
+ private static final int[] DOUBLE_DIGIT_SUM = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
+
+ /**
+ * Calculate the check digit by starting from the right, doubling every
+ * each digit, summing all the digits including the doubled ones, and
+ * finding a number to make the sum divisible by 10.
+ *
+ * @param deviceId not including the check digit
+ * @return the check digit
+ */
+ private static int getLuhnCheckDigit(String deviceId) {
+ int sum = 0;
+ int dontDoubleModulus = deviceId.length() % 2;
+ for (int i = deviceId.length() - 1; i >= 0; --i) {
+ int digit = Character.digit(deviceId.charAt(i), 10);
+ if (i % 2 == dontDoubleModulus) {
+ sum += digit;
+ } else {
+ sum += DOUBLE_DIGIT_SUM[digit];
+ }
+ }
+ sum %= 10;
+ return sum == 0 ? 0 : 10 - sum;
+ }
+
+ private static void assertReportingBodyIdentifier(String deviceId, boolean decimalIdentifier) {
+ // Check the reporting body identifier
+ int reportingBodyIdentifier = Integer.parseInt(deviceId.substring(0, 2), 16);
+ int decimalBound = 0xA0;
+ String message = String.format("%s RR %x not %s than %x",
+ decimalIdentifier ? "IMEI" : "MEID",
+ reportingBodyIdentifier,
+ decimalIdentifier ? "<" : ">=",
+ decimalBound);
+ assertEquals(message, decimalIdentifier, reportingBodyIdentifier < decimalBound);
+ }
+
+ private static void assertMeidDeviceId(String deviceId) {
+ assertHexadecimalMeidFormat(deviceId);
+ assertReportingBodyIdentifier(deviceId, false); // Must be hexadecimal identifier
+ }
+
+ private static void assertHexadecimalMeidFormat(String deviceId) {
+ // MEID must NOT include the check digit.
+ String meidPattern = "[0-9a-fA-F]{14}";
+ assertTrue("MEID hex device id " + deviceId + " does not match pattern " + meidPattern,
+ Pattern.matches(meidPattern, deviceId));
+ }
+
+ private void assertMacAddressReported() {
+ String macAddress = getMacAddress();
+ String macPattern = "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}";
+ assertTrue("MAC Address " + macAddress + " does not match pattern " + macPattern,
+ Pattern.matches(macPattern, macAddress));
+ }
+
+ /** @return mac address which requires the WiFi system to be enabled */
+ private String getMacAddress() {
+ WifiManager wifiManager = (WifiManager) getContext()
+ .getSystemService(Context.WIFI_SERVICE);
+
+ boolean enabled = wifiManager.isWifiEnabled();
+
+ try {
+ if (!enabled) {
+ wifiManager.setWifiEnabled(true);
+ }
+
+ WifiInfo wifiInfo = wifiManager.getConnectionInfo();
+ return wifiInfo.getMacAddress();
+
+ } finally {
+ if (!enabled) {
+ wifiManager.setWifiEnabled(false);
+ }
+ }
+ }
}
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
index 64abfcf..283605d 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
@@ -20,6 +20,7 @@
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.telephony.TelephonyManager;
@@ -28,6 +29,22 @@
import android.view.WindowManager;
public class DeviceInfoInstrument extends Instrumentation {
+
+ // Should use XML files in frameworks/base/data/etc to generate dynamically.
+ private static final String[] FEATURES_TO_CHECK = {
+ PackageManager.FEATURE_CAMERA,
+ PackageManager.FEATURE_CAMERA_AUTOFOCUS,
+ PackageManager.FEATURE_CAMERA_FLASH,
+ PackageManager.FEATURE_SENSOR_LIGHT,
+ PackageManager.FEATURE_SENSOR_PROXIMITY,
+ PackageManager.FEATURE_TELEPHONY,
+ PackageManager.FEATURE_TELEPHONY_CDMA,
+ PackageManager.FEATURE_TELEPHONY_GSM,
+ PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH,
+ PackageManager.FEATURE_LIVE_WALLPAPER,
+ };
+
+ private static final String FEATURES = "features";
private static final String PHONE_NUMBER = "phoneNumber";
public static final String LOCALES = "locales";
private static final String IMSI = "imsi";
@@ -118,6 +135,10 @@
String phoneNumber = tm.getLine1Number();
addResult(PHONE_NUMBER, phoneNumber);
+ // features
+ String features = getFeatures();
+ addResult(FEATURES, features);
+
finish(Activity.RESULT_OK, mResults);
}
@@ -150,4 +171,20 @@
private void addResult(final String key, final float value){
mResults.putFloat(key, value);
}
+
+ /**
+ * Return a summary of the device's feature as a semi-colon-delimited list of colon separated
+ * name and availability pairs like "feature1:true;feature2:false;feature3;true".
+ */
+ private String getFeatures() {
+ StringBuilder builder = new StringBuilder();
+
+ PackageManager packageManager = getContext().getPackageManager();
+ for (String feature : FEATURES_TO_CHECK) {
+ boolean hasFeature = packageManager.hasSystemFeature(feature);
+ builder.append(feature).append(':').append(hasFeature).append(';');
+ }
+
+ return builder.toString();
+ }
}
diff --git a/tools/host/src/com/android/cts/TestDevice.java b/tools/host/src/com/android/cts/TestDevice.java
index 2146b1e..a53968c 100644
--- a/tools/host/src/com/android/cts/TestDevice.java
+++ b/tools/host/src/com/android/cts/TestDevice.java
@@ -416,6 +416,7 @@
public static final String IMEI = "imei";
public static final String IMSI = "imsi";
public static final String PHONE_NUMBER = "phoneNumber";
+ public static final String FEATURES = "features";
private HashMap<String, String> mInfoMap;
@@ -747,6 +748,15 @@
public String getPhoneNumber() {
return mInfoMap.get(PHONE_NUMBER);
}
+
+ /**
+ * Get features.
+ *
+ * @return Features.
+ */
+ public String getFeatures() {
+ return mInfoMap.get(FEATURES);
+ }
}
/**
diff --git a/tools/host/src/com/android/cts/TestSessionLog.java b/tools/host/src/com/android/cts/TestSessionLog.java
index efe5cc9..f89150d 100644
--- a/tools/host/src/com/android/cts/TestSessionLog.java
+++ b/tools/host/src/com/android/cts/TestSessionLog.java
@@ -69,6 +69,7 @@
static final String ATTRIBUTE_BUILD_NAME = "buildName";
static final String ATTRIBUTE_ARCH = "arch";
static final String ATTRIBUTE_VALUE = "value";
+ static final String ATTRIBUTE_AVAILABLE = "available";
static final String ATTRIBUTE_PASS = "pass";
static final String ATTRIBUTE_FAILED = "failed";
@@ -84,6 +85,8 @@
static final String TAG_SUMMARY = "Summary";
static final String TAG_SCREEN = "Screen";
static final String TAG_BUILD_INFO = "BuildInfo";
+ static final String TAG_FEATURE_INFO = "FeatureInfo";
+ static final String TAG_FEATURE = "Feature";
static final String TAG_PHONE_SUB_INFO = "PhoneSubInfo";
static final String TAG_TEST_RESULT = "TestResult";
static final String TAG_TESTPACKAGE = "TestPackage";
@@ -323,8 +326,10 @@
DeviceParameterCollector.BUILD_DEVICE, bldInfo.getBuildDevice());
deviceSettingNode.appendChild(devInfoNode);
+
+ addFeatureInfo(doc, deviceSettingNode, bldInfo);
}
-
+
Node hostInfo = doc.createElement(TAG_HOSTINFO);
root.appendChild(hostInfo);
String hostName = "";
@@ -389,6 +394,39 @@
}
/**
+ * Creates a {@link #TAG_FEATURE_INFO} tag with {@link #TAG_FEATURE} elements indicating
+ * what features are supported by the device. It parses a string from the deviceInfo argument
+ * that is in the form of "feature1:true;feature2:false;featuer3;true;" with a trailing
+ * semi-colon.
+ *
+ * <pre>
+ * <FeatureInfo>
+ * <Feature name="android.name.of.feature" available="true" />
+ * ...
+ * </FeatureInfo>
+ * </pre>
+ * @param document used to create elements
+ * @param parentNode to attach the FeatureInfo element to
+ * @param deviceInfo to get the feature data from
+ */
+ private void addFeatureInfo(Document document, Node parentNode,
+ DeviceParameterCollector deviceInfo) {
+ Node featureInfo = document.createElement(TAG_FEATURE_INFO);
+ parentNode.appendChild(featureInfo);
+
+ String features = deviceInfo.getFeatures();
+ String[] featurePairs = features.split(";");
+ for (String featurePair : featurePairs) {
+ Node feature = document.createElement(TAG_FEATURE);
+ featureInfo.appendChild(feature);
+
+ String[] nameAndAvailability = featurePair.split(":");
+ setAttribute(document, feature, ATTRIBUTE_NAME, nameAndAvailability[0]);
+ setAttribute(document, feature, ATTRIBUTE_AVAILABLE, nameAndAvailability[1]);
+ }
+ }
+
+ /**
* Output TestSuite and result to XML DOM Document.
*
* @param doc The document.
diff --git a/tools/host/src/com/android/cts/Version.java b/tools/host/src/com/android/cts/Version.java
index b3f6766..6477b1d 100644
--- a/tools/host/src/com/android/cts/Version.java
+++ b/tools/host/src/com/android/cts/Version.java
@@ -18,7 +18,7 @@
public class Version {
// The CTS version string
- private static final String version = "2.1_r1";
+ private static final String version = "2.1_r2";
private Version() {
// no instances allowed
diff --git a/tools/host/src/res/cts_result.css b/tools/host/src/res/cts_result.css
index 869c4dd..735fd8b 100644
--- a/tools/host/src/res/cts_result.css
+++ b/tools/host/src/res/cts_result.css
@@ -79,6 +79,7 @@
#summaryinfo td {
padding:1px;
border-width: 0px 0px 0px 0px;
+ vertical-align: top;
}
/* The test summary */
diff --git a/tools/host/src/res/cts_result.xsl b/tools/host/src/res/cts_result.xsl
index 0ff7e93..0846d91 100644
--- a/tools/host/src/res/cts_result.xsl
+++ b/tools/host/src/res/cts_result.xsl
@@ -102,7 +102,9 @@
<TR>
<TD class="rowtitle">Supported Locales</TD>
<TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@locales"/>
+ <xsl:call-template name="formatDelimitedString">
+ <xsl:with-param name="string" select="TestResult/DeviceInfo/BuildInfo/@locales"/>
+ </xsl:call-template>
</TD>
</TR>
<TR>
@@ -165,6 +167,26 @@
<xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@imsi"/>
</TD>
</TR>
+ <TR>
+ <TD class="rowtitle">Features</TD>
+ <TD>
+ <xsl:for-each select="TestResult/DeviceInfo/FeatureInfo/Feature">
+ <xsl:text>[</xsl:text>
+ <xsl:choose>
+ <xsl:when test="@available = 'true'">
+ <xsl:text>X</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>_</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>] </xsl:text>
+
+ <xsl:value-of select="@name" />
+ <br />
+ </xsl:for-each>
+ </TD>
+ </TR>
</TABLE>
</div>
</TD>
@@ -403,10 +425,31 @@
</TABLE>
</xsl:for-each> <!-- end test package -->
</DIV>
+ </body>
+ </html>
+ </xsl:template>
- </body>
- </html>
-</xsl:template>
+ <!-- Take a delimited string and insert line breaks after a some number of elements. -->
+ <xsl:template name="formatDelimitedString">
+ <xsl:param name="string" />
+ <xsl:param name="numTokensPerRow" select="10" />
+ <xsl:param name="tokenIndex" select="1" />
+ <xsl:if test="$string">
+ <!-- Requires the last element to also have a delimiter after it. -->
+ <xsl:variable name="token" select="substring-before($string, ';')" />
+ <xsl:value-of select="$token" />
+ <xsl:text> </xsl:text>
+
+ <xsl:if test="$tokenIndex mod $numTokensPerRow = 0">
+ <br />
+ </xsl:if>
+ <xsl:call-template name="formatDelimitedString">
+ <xsl:with-param name="string" select="substring-after($string, ';')" />
+ <xsl:with-param name="numTokensPerRow" select="$numTokensPerRow" />
+ <xsl:with-param name="tokenIndex" select="$tokenIndex + 1" />
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
</xsl:stylesheet>