merge in gingerbread-release history after reset to gingerbread
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 93b5078..08bd98b 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -75,6 +75,8 @@
<string name="bt_sent_messages">Sent Messages</string>
<string name="bt_no_messages">No messages</string>
<string name="bt_make_discoverable">Make Discoverable</string>
+ <string name="bt_insecure_pairing_error_title">Pairing dialog shown?</string>
+ <string name="bt_insecure_pairing_error_message">Insecure connections should not show the pairing dialog!</string>
<string name="bt_secure_client">Secure Client</string>
<string name="bt_insecure_client">Insecure Client</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BluetoothTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BluetoothTestActivity.java
index a6f9919..b617fc2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BluetoothTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BluetoothTestActivity.java
@@ -254,6 +254,7 @@
if (data != null) {
TestResult result = TestResult.fromActivityResult(resultCode, data);
TestListItem test = secure ? mSecureClientTest : mInsecureClientTest;
+ test.setResult(result.getResult());
updateTest(test);
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/MessageTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/MessageTestActivity.java
index aabe00c..1d6706d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/MessageTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/MessageTestActivity.java
@@ -18,11 +18,16 @@
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestResult;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -43,12 +48,17 @@
static final String EXTRA_DEVICE_ADDRESS = "deviceAddress";
static final String EXTRA_SECURE = "secure";
+ /** Broadcast action that should only be fired when pairing for a secure connection. */
+ private static final String ACTION_PAIRING_REQUEST =
+ "android.bluetooth.device.action.PAIRING_REQUEST";
+
private static final int ENABLE_BLUETOOTH_REQUEST = 1;
private static final String MESSAGE_DELIMITER = "\n";
private static final Pattern MESSAGE_PATTERN = Pattern.compile("Message (\\d+) to .*");
private BluetoothAdapter mBluetoothAdapter;
+ private PairingActionReceiver mPairingActionReceiver;
private BluetoothChatService mChatService;
private ArrayAdapter<String> mReceivedMessagesAdapter;
@@ -112,6 +122,10 @@
getPassButton().setEnabled(false);
+ mPairingActionReceiver = new PairingActionReceiver();
+ IntentFilter intentFilter = new IntentFilter(ACTION_PAIRING_REQUEST);
+ registerReceiver(mPairingActionReceiver, intentFilter);
+
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter.isEnabled()) {
startChatService();
@@ -284,9 +298,41 @@
Toast.makeText(this, toast, Toast.LENGTH_LONG).show();
}
+ class PairingActionReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!mSecure && ACTION_PAIRING_REQUEST.equals(intent.getAction())) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ showPairingErrorDialog();
+ }
+ });
+ }
+ }
+ }
+
+ private void showPairingErrorDialog() {
+ new AlertDialog.Builder(MessageTestActivity.this)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setTitle(R.string.bt_insecure_pairing_error_title)
+ .setMessage(R.string.bt_insecure_pairing_error_message)
+ .setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ TestResult.setFailedResult(MessageTestActivity.this);
+ finish();
+ }
+ })
+ .setCancelable(false)
+ .show();
+ }
+
@Override
protected void onDestroy() {
super.onDestroy();
mChatService.stop();
+ unregisterReceiver(mPairingActionReceiver);
}
}
diff --git a/tests/res/raw/sig_media.bin b/tests/res/raw/sig_media.bin
new file mode 100644
index 0000000..a43bc68
--- /dev/null
+++ b/tests/res/raw/sig_media.bin
Binary files differ
diff --git a/tests/res/raw/sig_platform.bin b/tests/res/raw/sig_platform.bin
new file mode 100644
index 0000000..33a683e
--- /dev/null
+++ b/tests/res/raw/sig_platform.bin
Binary files differ
diff --git a/tests/res/raw/sig_shared.bin b/tests/res/raw/sig_shared.bin
new file mode 100644
index 0000000..094b1b9
--- /dev/null
+++ b/tests/res/raw/sig_shared.bin
Binary files differ
diff --git a/tests/res/raw/sig_testkey.bin b/tests/res/raw/sig_testkey.bin
new file mode 100644
index 0000000..e2bef19
--- /dev/null
+++ b/tests/res/raw/sig_testkey.bin
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
new file mode 100644
index 0000000..cff19af
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2011 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.security.cts;
+
+import com.android.cts.stub.R;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.Signature;
+import android.content.res.Resources.NotFoundException;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class PackageSignatureTest extends AndroidTestCase {
+
+ private static final String TAG = PackageSignatureTest.class.getSimpleName();
+
+ public void testPackageSignatures() throws Exception {
+ Set<String> badPackages = new HashSet<String>();
+ Set<Signature> wellKnownSignatures = getWellKnownSignatures();
+
+ PackageManager packageManager = mContext.getPackageManager();
+ List<PackageInfo> allPackageInfos = packageManager.getInstalledPackages(
+ PackageManager.GET_UNINSTALLED_PACKAGES |
+ PackageManager.GET_SIGNATURES);
+ for (PackageInfo packageInfo : allPackageInfos) {
+ String packageName = packageInfo.packageName;
+ if (packageName != null && !isWhitelistedPackage(packageName)) {
+ for (Signature signature : packageInfo.signatures) {
+ if (wellKnownSignatures.contains(signature)) {
+ badPackages.add(packageInfo.packageName);
+ }
+ }
+ }
+ }
+
+ assertTrue("These packages should not be signed with a well known key: " + badPackages,
+ badPackages.isEmpty());
+ }
+
+ private Set<Signature> getWellKnownSignatures() throws NotFoundException, IOException {
+ Set<Signature> wellKnownSignatures = new HashSet<Signature>();
+ wellKnownSignatures.add(getSignature(R.raw.sig_media));
+ wellKnownSignatures.add(getSignature(R.raw.sig_platform));
+ wellKnownSignatures.add(getSignature(R.raw.sig_shared));
+ wellKnownSignatures.add(getSignature(R.raw.sig_testkey));
+ return wellKnownSignatures;
+ }
+
+ private boolean isWhitelistedPackage(String packageName) {
+ // Don't check the signatures of CTS test packages on the device.
+ // devicesetup is the APK CTS loads to collect information needed in the final report
+ return packageName.startsWith("com.android.cts")
+ || packageName.equalsIgnoreCase("android.tests.devicesetup");
+ }
+
+ private static final int DEFAULT_BUFFER_BYTES = 1024 * 4;
+
+ private Signature getSignature(int resId) throws NotFoundException, IOException {
+ InputStream input = mContext.getResources().openRawResource(resId);
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+ try {
+ byte[] buffer = new byte[DEFAULT_BUFFER_BYTES];
+ int numBytes = 0;
+ while ((numBytes = input.read(buffer)) != -1) {
+ output.write(buffer, 0, numBytes);
+ }
+ return new Signature(output.toByteArray());
+ } finally {
+ input.close();
+ output.close();
+ }
+ }
+
+ /**
+ * Writes a package's signature to a file on the device's external storage.
+ * This method was used to generate the well known signatures used by this test.
+ */
+ @SuppressWarnings("unused")
+ private void writeSignature(String packageName, String fileName)
+ throws NameNotFoundException, IOException {
+ PackageManager packageManager = mContext.getPackageManager();
+ PackageInfo packageInfo = packageManager.getPackageInfo(packageName,
+ PackageManager.GET_SIGNATURES);
+ File directory = mContext.getExternalFilesDir(null);
+ int numSignatures = packageInfo.signatures.length;
+ Log.i(TAG, "Will dump " + numSignatures + " signatures to " + directory);
+ for (int i = 0; i < numSignatures; i++) {
+ Signature signature = packageInfo.signatures[i];
+ byte[] signatureBytes = signature.toByteArray();
+ File signatureFile = new File(directory, fileName + "." + i);
+ FileOutputStream output = null;
+ try {
+ output = new FileOutputStream(signatureFile);
+ output.write(signatureBytes);
+ } finally {
+ if (output != null) {
+ output.close();
+ }
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/VoldExploitTest.java b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
index df5e58a..38eece7 100644
--- a/tests/tests/security/src/android/security/cts/VoldExploitTest.java
+++ b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
@@ -51,8 +51,8 @@
devices.addAll(getSysFsPath("/etc/vold.fstab"));
devices.addAll(getSysFsPath("/system/etc/vold.fstab"));
if (devices.isEmpty()) {
- // FIXME: We should be able to detect this security hole
- // even if there's no vold.fstab entry
+ // This vulnerability is not exploitable if there's
+ // no entry in vold.fstab
return;
}
diff --git a/tests/tests/text/src/android/text/method/cts/TouchTest.java b/tests/tests/text/src/android/text/method/cts/TouchTest.java
index 6b53f1d..7217db7 100755
--- a/tests/tests/text/src/android/text/method/cts/TouchTest.java
+++ b/tests/tests/text/src/android/text/method/cts/TouchTest.java
@@ -39,7 +39,9 @@
private Activity mActivity;
private static final String LONG_TEXT = "Scrolls the specified widget to the specified " +
"coordinates, except constrains the X scrolling position to the horizontal regions " +
- "of the text that will be visible after scrolling to the specified Y position.";
+ "of the text that will be visible after scrolling to the specified Y position." +
+ "This is the description of the test.";
+
private boolean mReturnFromTouchEvent;
public TouchTest() {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 05ff747..6e0be6c 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -908,14 +908,21 @@
args = {String.class},
notes = "Cannot check highlighting"
)
- @UiThreadTest
- public void testFindAll() throws InterruptedException {
- String p = "<p>Find all instances of find on the page and highlight them.</p>";
+ public void testFindAll() throws Throwable {
+ getActivity().runOnUiThread(new Runnable() {
+ public void run() {
+ String p = "<p>Find all instances of find on the page and highlight them.</p>";
- mWebView.loadData("<html><body>" + p + "</body></html>", "text/html", "UTF-8");
+ mWebView.loadData("<html><body>" + p +"</body></html>", "text/html", "UTF-8");
+ }
+ });
waitForLoadComplete(mWebView, TEST_TIMEOUT);
- assertEquals(2, mWebView.findAll("find"));
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ assertEquals(2, mWebView.findAll("find"));
+ }
+ });
}
@TestTargets({