am a0351d44: (-s ours) merge in lmp-mr1-cts-release history after reset to lmp-mr1-dev
* commit 'a0351d441b8867451a38e2023281b6d5b68fec63':
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index b525cc4..17ddbac 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1434,8 +1434,6 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_other" />
- <meta-data android:name="test_excluded_features"
- android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
</activity>
<activity android:name=".tv.MockTvInputSettingsActivity">
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 07f7654..1444723 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1164,6 +1164,7 @@
<string name="provisioning_byod_no_video_capture_resolver">No video capture app present. Skip test.</string>
<string name="provisioning_byod_no_audio_capture_resolver">No audio capture app present. Skip test.</string>
<string name="provisioning_byod_capture_media_error">Error while capturing media from managed profile.</string>
+ <string name="provisioning_byod_capture_image_error">Error while capturing image from managed profile.</string>
<!-- Strings for DeskClock -->
<string name="deskclock_tests">Alarms and Timers Tests</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodPresentMediaDialog.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodPresentMediaDialog.java
index b3f126b..15f5bc8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodPresentMediaDialog.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodPresentMediaDialog.java
@@ -31,10 +31,14 @@
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.VideoView;
-
+import android.view.Display;
+import android.graphics.BitmapFactory;
+import android.graphics.Point;
+import android.content.ContentResolver;
import com.android.cts.verifier.R;
import java.io.IOException;
+import java.io.InputStream;
/**
* This dialog shows/plays an image, video or audio uri.
@@ -46,6 +50,7 @@
private static final String KEY_IMAGE_URI = "image";
private static final String KEY_AUDIO_URI = "audio";
+ private Bitmap scaled = null;
/**
* Get a dialogFragment showing an image.
*/
@@ -79,6 +84,16 @@
return dialog;
}
+ private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){
+ // Raw height and width of image
+ final int height = options.outHeight;
+ final int width = options.outWidth;
+ if(reqWidth <= 0 || reqHeight <= 0) {
+ return 1;
+ }
+ return Math.max(height/reqHeight, width/reqWidth) + 1;
+ }
+
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dialog = new Dialog(getActivity());
@@ -114,11 +129,36 @@
} else if (arguments.containsKey(KEY_IMAGE_URI)) {
// Show image UI.
dialog.setTitle(getString(R.string.provisioning_byod_verify_image_title));
-
- Uri uri = (Uri) getArguments().getParcelable(KEY_IMAGE_URI);
+ Uri uri = (Uri)getArguments().getParcelable(KEY_IMAGE_URI);
ImageView imageView = (ImageView) dialog.findViewById(R.id.imageView);
imageView.setVisibility(View.VISIBLE);
- imageView.setImageURI(uri);
+
+ try{
+ InputStream input = getActivity().getContentResolver().openInputStream(uri);
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeStream(input, null, options);
+ //scale the picture
+ Display display = getActivity().getWindowManager().getDefaultDisplay();
+ Point size = new Point();
+ display.getSize(size);
+ int reqWidth = size.x;
+ int reqHeight = size.y;
+ options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+
+ options.inJustDecodeBounds = false;
+ input.close();
+ input = getActivity().getContentResolver().openInputStream(uri);
+ scaled = BitmapFactory.decodeStream(input, null, options);
+ input.close();
+ imageView.setImageBitmap(scaled);
+ }catch(IOException e){
+ Log.e(TAG, "Cannot get image.", e);
+ Toast.makeText(getActivity(),R.string.provisioning_byod_capture_image_error,
+ Toast.LENGTH_SHORT).show();
+ getActivity().finish();
+ }
+
} else if (arguments.containsKey(KEY_AUDIO_URI)) {
// Show audio playback UI.
dialog.setTitle(getString(R.string.provisioning_byod_verify_audio_title));
@@ -161,6 +201,13 @@
((DialogCallback) getActivity()).onDialogClose();
}
+ @Override
+ public void onDestroyView() {
+ if(scaled!=null){
+ scaled.recycle();
+ }
+ super.onDestroyView();
+ }
public interface DialogCallback {
public abstract void onDialogClose();
}
diff --git a/hostsidetests/monkey/src/com/android/cts/monkey/AbstractMonkeyTest.java b/hostsidetests/monkey/src/com/android/cts/monkey/AbstractMonkeyTest.java
old mode 100755
new mode 100644
index b31a32d..9e04274
--- a/hostsidetests/monkey/src/com/android/cts/monkey/AbstractMonkeyTest.java
+++ b/hostsidetests/monkey/src/com/android/cts/monkey/AbstractMonkeyTest.java
@@ -20,7 +20,7 @@
/**
* Base monkey command with flags to avoid side effects like airplane mode.
*/
- static final String MONKEY_CMD = "monkey --pct-motion 0 --pct-majornav 0 --pct-syskeys 0 --pct-anyevent 0 --pct-rotation 0";
+ static final String MONKEY_CMD = "monkey --pct-touch 0 --pct-motion 0 --pct-majornav 0 --pct-syskeys 0 --pct-anyevent 0 --pct-rotation 0";
IAbi mAbi;
CtsBuildHelper mBuild;
diff --git a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
old mode 100644
new mode 100755
index ba880d7..7277b9f
--- a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
+++ b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
@@ -85,6 +85,23 @@
return success;
}
+ private static int getAlphaScaledBlue(final int color) {
+ return (color & 0x000000FF) * getAlpha(color) / 255;
+ }
+
+ private static int getAlphaScaledGreen(final int color) {
+ return ((color & 0x0000FF00) >> 8) * getAlpha(color) / 255;
+ }
+
+ private static int getAlphaScaledRed(final int color) {
+ return ((color & 0x00FF0000) >> 16) * getAlpha(color) / 255;
+ }
+
+ private static int getAlpha(final int color) {
+ // use logical shift for keeping an unsigned value
+ return (color & 0xFF000000) >>> 24;
+ }
+
private static boolean compare(BufferedImage reference, BufferedImage generated, int threshold) {
final int w = generated.getWidth();
final int h = generated.getHeight();
@@ -96,15 +113,14 @@
for (int j = 0; j < h; j++) {
final int p1 = reference.getRGB(i, j);
final int p2 = generated.getRGB(i, j);
- final int dr = (p1 & 0x000000FF) - (p2 & 0x000000FF);
- final int dg = ((p1 & 0x0000FF00) - (p2 & 0x0000FF00)) >> 8;
- final int db = ((p1 & 0x00FF0000) - (p2 & 0x00FF0000)) >> 16;
- final int da = ((p1 & 0xFF000000) - (p2 & 0xFF000000)) >> 24;
+
+ final int dr = getAlphaScaledRed(p1) - getAlphaScaledRed(p2);
+ final int dg = getAlphaScaledGreen(p1) - getAlphaScaledGreen(p2);
+ final int db = getAlphaScaledBlue(p1) - getAlphaScaledBlue(p2);
if (Math.abs(db) > threshold ||
Math.abs(dg) > threshold ||
- Math.abs(dr) > threshold ||
- Math.abs(da) > threshold) {
+ Math.abs(dr) > threshold) {
return false;
}
}
diff --git a/libs/deviceutil/src/android/cts/util/MediaUtils.java b/libs/deviceutil/src/android/cts/util/MediaUtils.java
index 5908923..2ae7b13 100755
--- a/libs/deviceutil/src/android/cts/util/MediaUtils.java
+++ b/libs/deviceutil/src/android/cts/util/MediaUtils.java
@@ -287,7 +287,7 @@
ex.release();
}
}
- return false;
+ return true;
}
public static boolean checkCodecsForPath(Context context, String path) {
diff --git a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
index bf02d9c..4d1121a 100644
--- a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
+++ b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
@@ -169,8 +169,13 @@
Log.i(TAG, "Encoder " + mimeType + " with " + w + "," + h + " not supported");
return;
}
- CodecInfo infoDec = CodecInfo.getSupportedFormatInfo(mimeType, w, h, false /* encoder */);
- assertNotNull(infoDec);
+
+ CodecInfo infoDec = CodecInfo.getSupportedFormatInfo(mimeType, w, h, false);
+ if (infoDec == null) {
+ Log.i(TAG, "Codec " + mimeType + "with " + w + "," + h + " not supported");
+ return;
+ }
+
mVideoWidth = w;
mVideoHeight = h;
diff --git a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
index 38a753d..a0177e2 100644
--- a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
+++ b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
@@ -34,7 +34,7 @@
private static final String TAG = "MockJobService";
/** Wait this long before timing out the test. */
- private static final long DEFAULT_TIMEOUT_MILLIS = 30000L; // 30 seconds.
+ private static final long DEFAULT_TIMEOUT_MILLIS = 5000L; // 5 seconds.
@Override
public void onCreate() {
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java
index ed9cadd..36f44ef 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java
@@ -29,7 +29,7 @@
public void testScheduleOnce() throws Exception {
JobInfo oneTimeJob = new JobInfo.Builder(TIMING_JOB_ID, kJobServiceComponent)
- .setOverrideDeadline(5000) // 5 secs
+ .setOverrideDeadline(1000) // 1 secs
.build();
kTestEnvironment.setExpectedExecutions(1);
@@ -41,7 +41,7 @@
public void testSchedulePeriodic() throws Exception {
JobInfo periodicJob =
new JobInfo.Builder(TIMING_JOB_ID, kJobServiceComponent)
- .setPeriodic(5000L) // 5 second period.
+ .setPeriodic(1000L) // 1 second period.
.build();
kTestEnvironment.setExpectedExecutions(3);
@@ -52,8 +52,7 @@
public void testCancel() throws Exception {
JobInfo cancelJob = new JobInfo.Builder(CANCEL_JOB_ID, kJobServiceComponent)
- .setMinimumLatency(5000L) // make sure it doesn't actually run immediately
- .setOverrideDeadline(7000L)
+ .setOverrideDeadline(2000L)
.build();
kTestEnvironment.setExpectedExecutions(0);
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 76b528b..5057725 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -1,12 +1,5 @@
[
{
- description: "testWindowContentFrameStats is flaky without 75b55d0846159543aafc1b7420915497fce9b3f1",
- names: [
- "android.app.uiautomation.cts.UiAutomationTest#testWindowContentFrameStats"
- ],
- bug: 18039218
-},
-{
description: "the UsageStats is not yet stable enough",
names: [
"android.app.usage.cts.UsageStatsTest"
@@ -336,17 +329,10 @@
bug: 18030049
},
{
- description: "The new recording test is not yet passing on all devices",
+ description: "EventOrderingVerificationTest not working.",
names: [
- "android.hardware.camera2.cts.RecordingTest#testRecordingFramerateLowToHigh"
+ "android.hardware.cts.helpers.sensorverification.EventOrderingVerificationTest#testSameTimestamp"
],
- bug: 18705837
-},
-{
- description: "The new image reader test is not yet passing on all devices",
- names: [
- "android.hardware.camera2.cts.ImageReaderTest#testAllOutputYUVResolutions"
- ],
- bug: 18689511
+ bug: 23792027
}
]
diff --git a/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml b/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
index 9906227..229dbfe 100644
--- a/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
+++ b/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
@@ -42,13 +42,13 @@
<EditText
android:id="@+id/edit"
- android:layout_width="80dip"
+ android:layout_width="64dip"
android:layout_height="80dip"
android:maxLines="1000"
android:scrollbars="vertical"
android:focusable="false"
android:includeFontPadding="false"
- android:textSize="10dip"
+ android:textSize="8dip"
android:textStyle="normal"
android:fontFamily="sans-serif"
android:visibility="gone"
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
index 5deff5a..88828ea 100644
--- a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
+++ b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
@@ -135,8 +135,8 @@
}
private void assertMemoryForScreenDensity(int memoryClass, int screenDensity, int screenSize) {
- int expectedMinimumMemory = ExpectedMemorySizesClass.getExpectedMemorySize(screenSize,
- screenDensity);
+ int expectedMinimumMemory = ExpectedMemorySizesClass.getExpectedMemorySize(screenDensity,
+ screenSize);
assertTrue("Expected to have at least " + expectedMinimumMemory
+ "mb of memory for screen density " + screenDensity,
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
index 998a005..e633f1f 100644
--- a/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
@@ -219,8 +219,7 @@
hasTestProcess = true;
}
}
- // For security reasons the system process is not exposed.
- assertTrue(!hasSystemProcess && hasTestProcess);
+ assertTrue(hasSystemProcess && hasTestProcess);
for (RunningAppProcessInfo ra : list) {
if (ra.processName.equals("com.android.cts.app.stub:remote")) {
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
index 92eef80..e21dc98 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -69,7 +69,8 @@
private static final long EXPOSURE_TIME_BOUNDARY_50HZ_NS = 10000000L; // 10ms
private static final long EXPOSURE_TIME_BOUNDARY_60HZ_NS = 8333333L; // 8.3ms, Approximation.
private static final long EXPOSURE_TIME_ERROR_MARGIN_NS = 100000L; // 100us, Approximation.
- private static final int SENSITIVITY_ERROR_MARGIN = 10; // 10
+ private static final float EXPOSURE_TIME_ERROR_MARGIN_RATE = 0.03f; // 3%, Approximation.
+ private static final float SENSITIVITY_ERROR_MARGIN_RATE = 0.03f; // 3%, Approximation.
private static final int DEFAULT_NUM_EXPOSURE_TIME_STEPS = 3;
private static final int DEFAULT_NUM_SENSITIVITY_STEPS = 16;
private static final int DEFAULT_SENSITIVITY_STEP_SIZE = 100;
@@ -1985,10 +1986,12 @@
*/
private void validateExposureTime(long request, long result) {
long expTimeDelta = request - result;
+ long expTimeErrorMargin = (long)(Math.max(EXPOSURE_TIME_ERROR_MARGIN_NS, request
+ * EXPOSURE_TIME_ERROR_MARGIN_RATE));
// First, round down not up, second, need close enough.
mCollector.expectTrue("Exposture time is invalid for AE manaul control test, request: "
+ request + " result: " + result,
- expTimeDelta < EXPOSURE_TIME_ERROR_MARGIN_NS && expTimeDelta >= 0);
+ expTimeDelta < expTimeErrorMargin && expTimeDelta >= 0);
}
/**
@@ -1998,11 +2001,12 @@
* @param result Result sensitivity
*/
private void validateSensitivity(int request, int result) {
- int sensitivityDelta = request - result;
+ float sensitivityDelta = (float)(request - result);
+ float sensitivityErrorMargin = request * SENSITIVITY_ERROR_MARGIN_RATE;
// First, round down not up, second, need close enough.
mCollector.expectTrue("Sensitivity is invalid for AE manaul control test, request: "
+ request + " result: " + result,
- sensitivityDelta < SENSITIVITY_ERROR_MARGIN && sensitivityDelta >= 0);
+ sensitivityDelta < sensitivityErrorMargin && sensitivityDelta >= 0);
}
/**
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
index abc0fea..333a7f1 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -377,8 +377,8 @@
Log.i(TAG, String.format("Testing Camera %s, config %s",
cameraId, MaxOutputSizes.configToString(config)));
- // Timeout is relaxed by 500ms for LEGACY devices to reduce false positive rate in CTS
- final int TIMEOUT_FOR_RESULT_MS = (mStaticInfo.isHardwareLevelLegacy()) ? 1500 : 1000;
+ // Timeout is relaxed by 1 second for LEGACY devices to reduce false positive rate in CTS
+ final int TIMEOUT_FOR_RESULT_MS = (mStaticInfo.isHardwareLevelLegacy()) ? 2000 : 1000;
final int MIN_RESULT_COUNT = 3;
ImageDropperListener imageDropperListener = new ImageDropperListener();
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
index b4113e5..2554b17 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -426,10 +426,6 @@
waitForNumResults(resultListener, NUM_FRAMES_WAITED);
stopPreview();
-
- // Free image resources
- image.close();
- closeImageReader();
return;
}
@@ -599,9 +595,6 @@
Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
validateJpegCapture(image, maxStillSz);
- // Free image resources
- image.close();
-
stopPreview();
}
@@ -648,10 +641,6 @@
Image image = imageListener.getImage((mStaticInfo.isHardwareLevelLegacy()) ?
RELAXED_CAPTURE_IMAGE_TIMEOUT_MS : CAPTURE_IMAGE_TIMEOUT_MS);
validateJpegCapture(image, stillSz);
-
- // Free image resources
- image.close();
-
// stopPreview must be called here to make sure next time a preview stream
// is created with new size.
stopPreview();
@@ -702,9 +691,6 @@
dumpFile(rawFileName, rawBuffer);
}
- // Free image resources
- image.close();
-
stopPreview();
}
@@ -1022,9 +1008,6 @@
if (!mStaticInfo.isHardwareLevelLegacy()) {
jpegTestExifExtraTags(exif, maxStillSz, stillResult);
}
-
- // Free image resources
- image.close();
}
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/LowRamDeviceTest.java b/tests/tests/hardware/src/android/hardware/cts/LowRamDeviceTest.java
index 68efef0..a2ddb4d 100755
--- a/tests/tests/hardware/src/android/hardware/cts/LowRamDeviceTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/LowRamDeviceTest.java
@@ -105,7 +105,7 @@
if (supports64Bit) {
assertMinMemoryMb(1824);
} else {
- assertMinMemoryMb(1344);
+ assertMinMemoryMb(1099);
}
} else if (greaterThanDpi(density, DENSITY_400, screenSize,
SCREENLAYOUT_SIZE_NORMAL, SCREENLAYOUT_SIZE_SMALL) ||
diff --git a/tests/tests/media/res/raw/gb18030_5.mp3 b/tests/tests/media/res/raw/gb18030_5.mp3
deleted file mode 100644
index 70f76ce..0000000
--- a/tests/tests/media/res/raw/gb18030_5.mp3
+++ /dev/null
Binary files differ
diff --git a/tests/tests/media/res/raw/on_input_buffer_filled_sigsegv.mp4 b/tests/tests/media/res/raw/on_input_buffer_filled_sigsegv.mp4
new file mode 100644
index 0000000..110c0d6
--- /dev/null
+++ b/tests/tests/media/res/raw/on_input_buffer_filled_sigsegv.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..7b663a4
--- /dev/null
+++ b/tests/tests/media/res/raw/video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_3840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_3840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
deleted file mode 100644
index 9277fbd..0000000
--- a/tests/tests/media/res/raw/video_3840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
+++ /dev/null
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
index 969963d..c347282 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -1319,13 +1319,11 @@
/* test if the explicitly named codec is present on the system */
if (explicitCodecName != null) {
- try {
- MediaCodec codec = MediaCodec.createByCodecName(explicitCodecName);
- if (codec != null) {
- codec.release();
- add(new Codec(explicitCodecName, null, mediaList));
- }
- } catch (Exception e) {}
+ MediaCodec codec = MediaCodec.createByCodecName(explicitCodecName);
+ if (codec != null) {
+ codec.release();
+ add(new Codec(explicitCodecName, null, mediaList));
+ }
}
} catch (Throwable t) {
Log.wtf("Constructor failed", t);
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index f58e6ab..f7fcd0a 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -38,6 +38,7 @@
import com.android.cts.media.R;
+
import android.content.Context;
import android.content.res.Resources;
import android.media.AudioManager;
@@ -49,18 +50,13 @@
import android.test.AndroidTestCase;
import android.view.SoundEffectConstants;
-import java.util.TreeMap;
-
public class AudioManagerTest extends AndroidTestCase {
private final static int MP3_TO_PLAY = R.raw.testmp3;
private final static long TIME_TO_PLAY = 2000;
private AudioManager mAudioManager;
private boolean mHasVibrator;
- private boolean mUseMasterVolume;
private boolean mUseFixedVolume;
- private int[] mMasterVolumeRamp;
- private TreeMap<Integer, Integer> mMasterVolumeMap = new TreeMap<Integer, Integer>();
private boolean mIsTelevision;
@Override
@@ -69,16 +65,8 @@
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = (vibrator != null) && vibrator.hasVibrator();
- mUseMasterVolume = mContext.getResources().getBoolean(
- Resources.getSystem().getIdentifier("config_useMasterVolume", "bool", "android"));
mUseFixedVolume = mContext.getResources().getBoolean(
Resources.getSystem().getIdentifier("config_useFixedVolume", "bool", "android"));
- mMasterVolumeRamp = mContext.getResources().getIntArray(
- Resources.getSystem().getIdentifier("config_masterVolumeRamp", "array", "android"));
- assertTrue((mMasterVolumeRamp.length > 0) && (mMasterVolumeRamp.length % 2 == 0));
- for (int i = 0; i < mMasterVolumeRamp.length; i+=2) {
- mMasterVolumeMap.put(mMasterVolumeRamp[i], mMasterVolumeRamp[i+1]);
- }
PackageManager packageManager = mContext.getPackageManager();
mIsTelevision = packageManager != null
&& (packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
@@ -334,7 +322,6 @@
}
public void testVolume() throws Exception {
- int volume, volumeDelta;
int[] streams = { AudioManager.STREAM_ALARM,
AudioManager.STREAM_MUSIC,
AudioManager.STREAM_VOICE_CALL,
@@ -377,32 +364,22 @@
mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
mAudioManager.adjustSuggestedStreamVolume(ADJUST_LOWER, streams[i], 0);
- assertEquals(maxVolume - volumeDelta, mAudioManager.getStreamVolume(streams[i]));
+ assertEquals(maxVolume - 1, mAudioManager.getStreamVolume(streams[i]));
// volume lower
mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
- volume = mAudioManager.getStreamVolume(streams[i]);
- while (volume > 0) {
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+ for (int k = maxVolume; k > 0; k--) {
mAudioManager.adjustStreamVolume(streams[i], ADJUST_LOWER, 0);
- assertEquals(Math.max(0, volume - volumeDelta),
- mAudioManager.getStreamVolume(streams[i]));
- volume = mAudioManager.getStreamVolume(streams[i]);
+ assertEquals(k - 1, mAudioManager.getStreamVolume(streams[i]));
}
mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
-
// volume raise
mAudioManager.setStreamVolume(streams[i], 1, 0);
- volume = mAudioManager.getStreamVolume(streams[i]);
- while (volume < maxVolume) {
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+ for (int k = 1; k < maxVolume; k++) {
mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
- assertEquals(Math.min(volume + volumeDelta, maxVolume),
- mAudioManager.getStreamVolume(streams[i]));
- volume = mAudioManager.getStreamVolume(streams[i]);
+ assertEquals(1 + k, mAudioManager.getStreamVolume(streams[i]));
}
// volume same
@@ -437,20 +414,18 @@
}
// adjust volume as ADJUST_RAISE
- mAudioManager.setStreamVolume(STREAM_MUSIC, 0, 0);
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
- mAudioManager.adjustVolume(ADJUST_RAISE, 0);
- assertEquals(Math.min(volumeDelta, maxMusicVolume),
- mAudioManager.getStreamVolume(STREAM_MUSIC));
+ mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0);
+ for (int k = 0; k < maxMusicVolume - 1; k++) {
+ mAudioManager.adjustVolume(ADJUST_RAISE, 0);
+ assertEquals(2 + k, mAudioManager.getStreamVolume(STREAM_MUSIC));
+ }
// adjust volume as ADJUST_LOWER
mAudioManager.setStreamVolume(STREAM_MUSIC, maxMusicVolume, 0);
maxMusicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC);
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
- mAudioManager.adjustVolume(ADJUST_LOWER, 0);
- assertEquals(Math.max(0, maxMusicVolume - volumeDelta),
- mAudioManager.getStreamVolume(STREAM_MUSIC));
+ mAudioManager.adjustVolume(ADJUST_LOWER, 0);
+ assertEquals(maxMusicVolume - 1, mAudioManager.getStreamVolume(STREAM_MUSIC));
mp.stop();
mp.release();
Thread.sleep(TIME_TO_PLAY);
@@ -465,13 +440,4 @@
mAudioManager.setRingerMode(-3007);
assertEquals(ringerMode, mAudioManager.getRingerMode());
}
-
- private int getVolumeDelta(int volume) {
- if (!mUseMasterVolume) {
- return 1;
- }
- int volumeDelta = mMasterVolumeMap.floorEntry(volume).getValue();
- assertTrue(volumeDelta > 0);
- return volumeDelta;
- }
}
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 40e619b..1c9e4b9 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -1094,8 +1094,8 @@
testDecode(R.raw.video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz, 299);
}
- public void testHEVCDecode30fps3840x2160() throws Exception {
- testDecode(R.raw.video_3840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+ public void testHEVCDecode30fps2840x2160() throws Exception {
+ testDecode(R.raw.video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz, 299);
}
private void testCodecEarlyEOS(int resid, int eosFrame) throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
index 029a632..14f8b9b 100644
--- a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
+++ b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
@@ -20,6 +20,8 @@
import android.content.res.AssetFileDescriptor;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.CodecProfileLevel;
import android.media.MediaCodecList;
import android.media.MediaExtractor;
import android.media.MediaFormat;
@@ -29,6 +31,10 @@
import android.util.Log;
import android.view.Surface;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.CodecProfileLevel;
+
import com.android.cts.media.R;
import java.io.File;
@@ -111,28 +117,28 @@
private String mOutputFile;
public void testExtractDecodeEditEncodeMuxQCIF() throws Throwable {
- setSize(176, 144);
+ if(!setSize(176, 144)) return;
setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
setCopyVideo();
TestWrapper.runTest(this);
}
public void testExtractDecodeEditEncodeMuxQVGA() throws Throwable {
- setSize(320, 240);
+ if(!setSize(320, 240)) return;
setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
setCopyVideo();
TestWrapper.runTest(this);
}
public void testExtractDecodeEditEncodeMux720p() throws Throwable {
- setSize(1280, 720);
+ if(!setSize(1280, 720)) return;
setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
setCopyVideo();
TestWrapper.runTest(this);
}
public void testExtractDecodeEditEncodeMuxAudio() throws Throwable {
- setSize(1280, 720);
+ if(!setSize(1280, 720)) return;
setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
setCopyAudio();
setVerifyAudioFormat();
@@ -140,7 +146,7 @@
}
public void testExtractDecodeEditEncodeMuxAudioVideo() throws Throwable {
- setSize(1280, 720);
+ if(!setSize(1280, 720)) return;
setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
setCopyAudio();
setCopyVideo();
@@ -203,14 +209,20 @@
}
/**
- * Sets the desired frame size.
- */
- private void setSize(int width, int height) {
+ * Sets the desired frame size and returns whether the given resolution is
+ * supported.
+ *
+ * <p>If decoding/encoding using AVC as the codec, checks that the resolution
+ * is supported. For other codecs, always return {@code true}.
+ */
+ private boolean setSize(int width, int height) {
if ((width % 16) != 0 || (height % 16) != 0) {
Log.w(TAG, "WARNING: width or height not multiple of 16");
}
mWidth = width;
mHeight = height;
+
+ return isAvcSupportedSize(width, height);
}
/**
@@ -1130,4 +1142,87 @@
private static String getMimeTypeFor(MediaFormat format) {
return format.getString(MediaFormat.KEY_MIME);
}
+
+ /**
+ * Returns the first codec capable of encoding the specified MIME type, or null if no match was
+ * found.
+ */
+ private static MediaCodecInfo selectCodec(String mimeType) {
+ int numCodecs = MediaCodecList.getCodecCount();
+ for (int i = 0; i < numCodecs; i++) {
+ MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
+
+ if (!codecInfo.isEncoder()) {
+ continue;
+ }
+
+ String[] types = codecInfo.getSupportedTypes();
+ for (int j = 0; j < types.length; j++) {
+ if (types[j].equalsIgnoreCase(mimeType)) {
+ return codecInfo;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Checks whether the given resolution is supported by the AVC codec.
+ */
+ private static boolean isAvcSupportedSize(int width, int height) {
+ MediaCodecInfo mediaCodecInfo = selectCodec(OUTPUT_VIDEO_MIME_TYPE);
+ CodecCapabilities cap = mediaCodecInfo.getCapabilitiesForType(OUTPUT_VIDEO_MIME_TYPE);
+ if (cap == null) { // not supported
+ return false;
+ }
+ int highestLevel = 0;
+ for (CodecProfileLevel lvl : cap.profileLevels) {
+ if (lvl.level > highestLevel) {
+ highestLevel = lvl.level;
+ }
+ }
+ int maxW = 0;
+ int maxH = 0;
+ int bitRate = 0;
+ int fps = 0; // frame rate for the max resolution
+ switch(highestLevel) {
+ // Do not support Level 1 to 2.
+ case CodecProfileLevel.AVCLevel1:
+ case CodecProfileLevel.AVCLevel11:
+ case CodecProfileLevel.AVCLevel12:
+ case CodecProfileLevel.AVCLevel13:
+ case CodecProfileLevel.AVCLevel1b:
+ case CodecProfileLevel.AVCLevel2:
+ return false;
+ case CodecProfileLevel.AVCLevel21:
+ maxW = 352;
+ maxH = 576;
+ break;
+ case CodecProfileLevel.AVCLevel22:
+ maxW = 720;
+ maxH = 480;
+ break;
+ case CodecProfileLevel.AVCLevel3:
+ maxW = 720;
+ maxH = 480;
+ break;
+ case CodecProfileLevel.AVCLevel31:
+ maxW = 1280;
+ maxH = 720;
+ break;
+ case CodecProfileLevel.AVCLevel32:
+ maxW = 1280;
+ maxH = 720;
+ break;
+ case CodecProfileLevel.AVCLevel4: // only try up to 1080p
+ default:
+ maxW = 1920;
+ maxH = 1080;
+ break;
+ }
+ if(maxW*maxH < width*height)
+ return false;
+ else
+ return true;
+ }
}
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 7cdc483..b07df8b 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -21,6 +21,7 @@
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.cts.util.MediaUtils;
+import android.hardware.Camera;
import android.media.AudioManager;
import android.media.MediaCodec;
import android.media.MediaExtractor;
@@ -45,6 +46,7 @@
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.util.List;
import java.util.StringTokenizer;
import java.util.UUID;
import java.util.Vector;
@@ -89,6 +91,10 @@
}
}
+ public void testonInputBufferFilledSigsegv() throws Exception {
+ testIfMediaServerDied(R.raw.on_input_buffer_filled_sigsegv);
+ }
+
public void testFlacHeapOverflow() throws Exception {
testIfMediaServerDied(R.raw.heap_oob_flac);
}
@@ -99,6 +105,7 @@
public boolean onError(MediaPlayer mp, int what, int extra) {
assertTrue(mp == mMediaPlayer);
assertTrue("mediaserver process died", what != MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+ Log.w(LOG_TAG, "onError " + what);
return false;
}
});
@@ -114,10 +121,17 @@
AssetFileDescriptor afd = mResources.openRawResourceFd(res);
mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
- mMediaPlayer.prepare();
- mMediaPlayer.start();
- mOnCompletionCalled.waitForSignal();
- mMediaPlayer.release();
+ try {
+ mMediaPlayer.prepare();
+ mMediaPlayer.start();
+ if (!mOnCompletionCalled.waitForSignal(5000)) {
+ Log.w(LOG_TAG, "testIfMediaServerDied: Timed out waiting for Error/Completion");
+ }
+ } catch (Exception e) {
+ Log.w(LOG_TAG, "playback failed", e);
+ } finally {
+ mMediaPlayer.release();
+ }
}
// Bug 13652927
@@ -804,15 +818,34 @@
return getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
+ private Camera mCamera;
private void testRecordedVideoPlaybackWithAngle(int angle) throws Exception {
- final int width = RECORDED_VIDEO_WIDTH;
- final int height = RECORDED_VIDEO_HEIGHT;
+ int width = RECORDED_VIDEO_WIDTH;
+ int height = RECORDED_VIDEO_HEIGHT;
final String file = RECORDED_FILE;
final long durationMs = RECORDED_DURATION_MS;
if (!hasCamera()) {
return;
}
+
+ boolean isSupported = false;
+ mCamera = Camera.open(0);
+ Camera.Parameters parameters = mCamera.getParameters();
+ List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
+ for (Camera.Size size : previewSizes)
+ {
+ if (size.width == width && size.height == height) {
+ isSupported = true;
+ break;
+ }
+ }
+ mCamera.release();
+ mCamera = null;
+ if (!isSupported) {
+ width = previewSizes.get(0).width;
+ height = previewSizes.get(0).height;
+ }
checkOrientation(angle);
recordVideo(width, height, angle, file, durationMs);
checkDisplayedVideoSize(width, height, angle, file);
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index 216e21b..8c8215e 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -20,6 +20,7 @@
import android.cts.util.MediaUtils;
import android.hardware.Camera;
import android.media.MediaFormat;
+import android.media.CamcorderProfile;
import android.media.MediaMetadataRetriever;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
@@ -38,6 +39,7 @@
import java.io.FileOutputStream;
import java.lang.InterruptedException;
import java.lang.Runnable;
+import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -52,6 +54,8 @@
private static final int RECORDED_DUR_TOLERANCE_MS = 1000;
private static final int VIDEO_WIDTH = 176;
private static final int VIDEO_HEIGHT = 144;
+ private static int mVideoWidth = VIDEO_WIDTH;
+ private static int mVideoHeight = VIDEO_HEIGHT;
private static final int VIDEO_BIT_RATE_IN_BPS = 128000;
private static final double VIDEO_TIMELAPSE_CAPTURE_RATE_FPS = 1.0;
private static final int AUDIO_BIT_RATE_IN_BPS = 12200;
@@ -165,19 +169,17 @@
if (!hasCamera()) {
return;
}
- // Try to get camera first supported resolution.
- // If we fail for any reason, set the video size to default value.
- try {
- camera = Camera.open();
- width = camera.getParameters().getSupportedPreviewSizes().get(0).width;
- height = camera.getParameters().getSupportedPreviewSizes().get(0).height;
- } catch (Exception e) {
+ // Try to get camera profile for QUALITY_LOW; if unavailable,
+ // set the video size to default value.
+ CamcorderProfile profile = CamcorderProfile.get(
+ 0 /* cameraId */, CamcorderProfile.QUALITY_LOW);
+ if (profile != null) {
+ width = profile.videoFrameWidth;
+ height = profile.videoFrameHeight;
+ } else {
width = VIDEO_WIDTH;
height = VIDEO_HEIGHT;
}
- if (camera != null) {
- camera.release();
- }
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
@@ -205,6 +207,7 @@
int durMs = timelapse? RECORD_TIME_LAPSE_MS: RECORD_TIME_MS;
for (int cameraId = 0; cameraId < nCamera; cameraId++) {
mCamera = Camera.open(cameraId);
+ setSupportedResolution(mCamera);
recordVideoUsingCamera(mCamera, OUTPUT_PATH, durMs, timelapse);
mCamera.release();
mCamera = null;
@@ -212,6 +215,21 @@
}
}
+ private void setSupportedResolution(Camera camera) {
+ Camera.Parameters parameters = camera.getParameters();
+ List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
+ for (Camera.Size size : previewSizes)
+ {
+ if (size.width == VIDEO_WIDTH && size.height == VIDEO_HEIGHT) {
+ mVideoWidth = VIDEO_WIDTH;
+ mVideoHeight = VIDEO_HEIGHT;
+ return;
+ }
+ }
+ mVideoWidth = previewSizes.get(0).width;
+ mVideoHeight = previewSizes.get(0).height;
+ }
+
private void recordVideoUsingCamera(
Camera camera, String fileName, int durMs, boolean timelapse) throws Exception {
// FIXME:
@@ -228,7 +246,7 @@
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoFrameRate(frameRate);
- mMediaRecorder.setVideoSize(VIDEO_WIDTH, VIDEO_HEIGHT);
+ mMediaRecorder.setVideoSize(mVideoWidth, mVideoHeight);
mMediaRecorder.setPreviewDisplay(mActivity.getSurfaceHolder().getSurface());
mMediaRecorder.setOutputFile(fileName);
mMediaRecorder.setLocation(LATITUDE, LONGITUDE);
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerTest.java b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
index 4b42690..af7cfaa 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
@@ -390,8 +390,6 @@
new String[] {"电视原声带", "格斗天王(限量精装版)(预购版)", null, "11.Open Arms.( cn808.net )", null} ),
new MediaScanEntry(R.raw.gb18030_4,
new String[] {"莫扎特", "黄金古典", "柏林爱乐乐团", "第25号交响曲", "莫扎特"} ),
- new MediaScanEntry(R.raw.gb18030_5,
- new String[] {"光良", "童话", "光良", "02.童话", "鍏夎壇"} ),
new MediaScanEntry(R.raw.gb18030_6,
new String[] {"张韶涵", "潘朵拉", "張韶涵", "隐形的翅膀", "王雅君"} ),
new MediaScanEntry(R.raw.gb18030_7, // this is actually utf-8
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index 9daf3c4..538a832 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -16,16 +16,21 @@
package android.net.cts;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
import android.net.NetworkConfig;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkInfo.State;
+import android.net.NetworkRequest;
import android.net.wifi.WifiManager;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -343,4 +348,23 @@
return mReceiveLatch.await(30, TimeUnit.SECONDS);
}
}
+
+ /** Verify restricted networks cannot be requested. */
+ public void testRestrictedNetworks() {
+ // Verify we can request unrestricted networks:
+ NetworkRequest request = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_INTERNET).build();
+ NetworkCallback callback = new NetworkCallback();
+ mCm.requestNetwork(request, callback);
+ mCm.unregisterNetworkCallback(callback);
+ // Verify we cannot request restricted networks:
+ request = new NetworkRequest.Builder().addCapability(NET_CAPABILITY_IMS).build();
+ callback = new NetworkCallback();
+ try {
+ mCm.requestNetwork(request, callback);
+ fail("No exception thrown when restricted network requested.");
+ } catch (SecurityException e) {
+ // Expected.
+ }
+ }
}
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index 69ccdf0..c7d854c 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -33,7 +33,9 @@
android_security_cts_MMapExecutableTest.cpp \
android_security_cts_NetlinkSocket.cpp \
android_security_cts_AudioPolicyBinderTest.cpp \
- android_security_cts_AudioflingerBinderTest.cpp
+ android_security_cts_AudioFlingerBinderTest.cpp \
+ android_security_cts_MediaPlayerInfoLeakTest.cpp \
+ android_security_cts_AudioEffectBinderTest.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index 22e0997..e16f06b 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -28,6 +28,8 @@
extern int register_android_security_cts_MMapExecutableTest(JNIEnv* env);
extern int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env);
extern int register_android_security_cts_AudioFlingerBinderTest(JNIEnv* env);
+extern int register_android_security_cts_MediaPlayerInfoLeakTest(JNIEnv* env);
+extern int register_android_security_cts_AudioEffectBinderTest(JNIEnv* env);
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
@@ -80,5 +82,13 @@
return JNI_ERR;
}
+ if (register_android_security_cts_MediaPlayerInfoLeakTest(env)) {
+ return JNI_ERR;
+ }
+
+ if (register_android_security_cts_AudioEffectBinderTest(env)) {
+ return JNI_ERR;
+ }
+
return JNI_VERSION_1_4;
}
diff --git a/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
new file mode 100644
index 0000000..25f3f80
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#define LOG_TAG "AudioEffectBinderTest-JNI"
+
+#include <jni.h>
+#include <media/AudioEffect.h>
+#include <media/IEffect.h>
+
+using namespace android;
+
+/*
+ * Native methods used by
+ * cts/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java
+ */
+
+struct EffectClient : public BnEffectClient {
+ EffectClient() { }
+ virtual void controlStatusChanged(bool controlGranted __unused) { }
+ virtual void enableStatusChanged(bool enabled __unused) { }
+ virtual void commandExecuted(uint32_t cmdCode __unused,
+ uint32_t cmdSize __unused,
+ void *pCmdData __unused,
+ uint32_t replySize __unused,
+ void *pReplyData __unused) { }
+};
+
+struct DeathRecipient : public IBinder::DeathRecipient {
+ DeathRecipient() : mDied(false) { }
+ virtual void binderDied(const wp<IBinder>& who __unused) { mDied = true; }
+ bool died() const { return mDied; }
+ bool mDied;
+};
+
+static bool isIEffectCommandSecure(IEffect *effect)
+{
+ // some magic constants here
+ const int COMMAND_SIZE = 1024 + 12; // different than reply size to get different heap frag
+ char cmdData[COMMAND_SIZE];
+ memset(cmdData, 0xde, sizeof(cmdData));
+
+ const int REPLY_DATA_SIZE = 256;
+ char replyData[REPLY_DATA_SIZE];
+ bool secure = true;
+ for (int k = 0; k < 10; ++k) {
+ Parcel data;
+ data.writeInterfaceToken(effect->getInterfaceDescriptor());
+ data.writeInt32(0); // 0 is EFFECT_CMD_INIT
+ data.writeInt32(sizeof(cmdData));
+ data.write(cmdData, sizeof(cmdData));
+ data.writeInt32(sizeof(replyData));
+
+ Parcel reply;
+ status_t status = effect->asBinder()->transact(3, data, &reply); // 3 is COMMAND
+ ALOGV("transact status: %d", status);
+ if (status != NO_ERROR) {
+ ALOGW("invalid transaction status %d", status);
+ continue;
+ }
+
+ ALOGV("reply data avail %zu", reply.dataAvail());
+ status = reply.readInt32();
+ ALOGV("reply status %d", status);
+ if (status == NO_ERROR) {
+ continue;
+ }
+
+ int size = reply.readInt32();
+ ALOGV("reply size %d", size);
+ if (size != sizeof(replyData)) { // we expect 0 or full reply data if command failed
+ ALOGW_IF(size != 0, "invalid reply size: %d", size);
+ continue;
+ }
+
+ // Note that if reply.read() returns success, it should completely fill replyData.
+ status = reply.read(replyData, sizeof(replyData));
+ if (status != NO_ERROR) {
+ ALOGW("invalid reply read - ignoring");
+ continue;
+ }
+ unsigned int *out = (unsigned int *)replyData;
+ for (size_t index = 0; index < sizeof(replyData) / sizeof(*out); ++index) {
+ if (out[index] != 0) {
+ secure = false;
+ ALOGI("leaked data = %#08x", out[index]);
+ }
+ }
+ }
+ ALOGI("secure: %s", secure ? "YES" : "NO");
+ return secure;
+}
+
+static jboolean android_security_cts_AudioEffect_test_isCommandSecure()
+{
+ const sp<IAudioFlinger> &audioFlinger = AudioSystem::get_audio_flinger();
+ if (audioFlinger.get() == NULL) {
+ ALOGE("could not get audioflinger");
+ return JNI_FALSE;
+ }
+
+ static const effect_uuid_t EFFECT_UIID_EQUALIZER = // type
+ { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }};
+ sp<EffectClient> effectClient(new EffectClient());
+ effect_descriptor_t descriptor;
+ memset(&descriptor, 0, sizeof(descriptor));
+ descriptor.type = EFFECT_UIID_EQUALIZER;
+ descriptor.uuid = *EFFECT_UUID_NULL;
+ const int32_t priority = 0;
+ const int sessionId = AUDIO_SESSION_OUTPUT_MIX;
+ const audio_io_handle_t io = 0; // AUDIO_IO_HANDLE_NONE
+ status_t status;
+ int32_t id;
+ int enabled;
+ sp<IEffect> effect = audioFlinger->createEffect(&descriptor, effectClient,
+ priority, io, sessionId, &status, &id, &enabled);
+ if (effect.get() == NULL || status != NO_ERROR) {
+ ALOGW("could not create effect");
+ return JNI_TRUE;
+ }
+
+ sp<DeathRecipient> deathRecipient(new DeathRecipient());
+ effect->asBinder()->linkToDeath(deathRecipient);
+
+ // check exploit
+ if (!isIEffectCommandSecure(effect.get())) {
+ ALOGE("not secure!");
+ return JNI_FALSE;
+ }
+
+ sleep(1); // wait to check death
+ if (deathRecipient->died()) {
+ ALOGE("effect binder died");
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+int register_android_security_cts_AudioEffectBinderTest(JNIEnv *env)
+{
+ static JNINativeMethod methods[] = {
+ { "native_test_isCommandSecure", "()Z",
+ (void *) android_security_cts_AudioEffect_test_isCommandSecure },
+ };
+
+ jclass clazz = env->FindClass("android/security/cts/AudioEffectBinderTest");
+ return env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0]));
+}
diff --git a/tests/tests/security/jni/android_security_cts_AudioflingerBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
similarity index 83%
rename from tests/tests/security/jni/android_security_cts_AudioflingerBinderTest.cpp
rename to tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
index aa988fc..61b27f1 100644
--- a/tests/tests/security/jni/android_security_cts_AudioflingerBinderTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
@@ -242,6 +242,53 @@
return true;
}
+jboolean android_security_cts_AudioFlinger_test_createEffect(JNIEnv* env __unused,
+ jobject thiz __unused)
+{
+ sp<IAudioFlinger> af;
+ sp<MyDeathClient> dr;
+
+ if (!connectAudioFlinger(af, dr)) {
+ return false;
+ }
+
+ for (int j = 0; j < 10; ++j) {
+ Parcel data, reply;
+ data.writeInterfaceToken(af->getInterfaceDescriptor());
+ data.writeInt32((int32_t)j);
+ status_t status = af->asBinder()->transact(40, data, &reply); // 40 is CREATE_EFFECT
+ if (status != NO_ERROR) {
+ return false;
+ }
+
+ status = (status_t)reply.readInt32();
+ if (status == NO_ERROR) {
+ continue;
+ }
+
+ int id = reply.readInt32();
+ int enabled = reply.readInt32();
+ sp<IEffect> effect = interface_cast<IEffect>(reply.readStrongBinder());
+ effect_descriptor_t desc;
+ effect_descriptor_t descTarget;
+ memset(&desc, 0, sizeof(effect_descriptor_t));
+ memset(&descTarget, 0, sizeof(effect_descriptor_t));
+ reply.read(&desc, sizeof(effect_descriptor_t));
+ if (id != 0 || enabled != 0 || memcmp(&desc, &descTarget, sizeof(effect_descriptor_t))) {
+ return false;
+ }
+ }
+
+ sleep(1);
+
+ // Check that mediaserver did not crash
+ if (dr->afIsDead()) {
+ return false;
+ }
+
+ return true;
+}
+
static JNINativeMethod gMethods[] = {
{ "native_test_setMasterMute", "()Z",
(void *) android_security_cts_AudioFlinger_test_setMasterMute },
@@ -251,6 +298,8 @@
(void *) android_security_cts_AudioFlinger_test_listAudioPorts },
{ "native_test_listAudioPatches", "()Z",
(void *) android_security_cts_AudioFlinger_test_listAudioPatches },
+ { "native_test_createEffect", "()Z",
+ (void *) android_security_cts_AudioFlinger_test_createEffect },
};
int register_android_security_cts_AudioFlingerBinderTest(JNIEnv* env)
diff --git a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
index 6807523..71d9948 100644
--- a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
@@ -18,6 +18,7 @@
#include <jni.h>
#include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
#include <media/IAudioPolicyService.h>
#include <media/AudioSystem.h>
#include <system/audio.h>
@@ -151,12 +152,12 @@
return false;
}
- status_t status = aps->isStreamActive((audio_stream_type_t)(-1), 0);
- if (status == NO_ERROR) {
+ bool status = aps->isStreamActive((audio_stream_type_t)(-1), 0);
+ if (status) {
return false;
}
status = aps->isStreamActive((audio_stream_type_t)AUDIO_STREAM_CNT, 0);
- if (status == NO_ERROR) {
+ if (status) {
return false;
}
return true;
@@ -186,6 +187,64 @@
return true;
}
+jboolean android_security_cts_AudioPolicy_test_startAudioSource(JNIEnv* env __unused,
+ jobject thiz __unused)
+{
+ sp<IAudioPolicyService> aps;
+
+ if (!init(aps, NULL, NULL)) {
+ return false;
+ }
+
+ // Keep synchronized with IAudioPolicyService.cpp!
+ enum {
+ START_AUDIO_SOURCE = 41,
+ };
+
+ for (int i = 0; i < 10; ++i) {
+ Parcel data, reply;
+ data.writeInterfaceToken(aps->getInterfaceDescriptor());
+ data.writeInt32(-i);
+ aps->asBinder()->transact(START_AUDIO_SOURCE, data, &reply);
+ status_t err = (status_t)reply.readInt32();
+ if (err == NO_ERROR) {
+ continue;
+ }
+ audio_io_handle_t handle = (audio_io_handle_t)reply.readInt32();
+ if (handle != 0) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+jint android_security_cts_AudioPolicy_test_getStreamVolumeLeak(JNIEnv* env __unused,
+ jobject thiz __unused)
+{
+ sp<IAudioPolicyService> aps;
+
+ if (!init(aps, NULL, NULL)) {
+ return -1;
+ }
+
+ // Keep synchronized with IAudioPolicyService.cpp!
+ enum {
+ GET_STREAM_VOLUME = 17,
+ };
+
+ Parcel data, reply;
+ status_t err;
+ data.writeInterfaceToken(aps->getInterfaceDescriptor());
+ data.writeInt32(-1); // stream type
+ data.writeInt32(-1); // device
+ aps->asBinder()->transact(GET_STREAM_VOLUME, data, &reply);
+ int index = reply.readInt32();
+ err = reply.readInt32();
+
+ return index;
+}
+
static JNINativeMethod gMethods[] = {
{ "native_test_startOutput", "()Z",
(void *) android_security_cts_AudioPolicy_test_startOutput },
@@ -195,6 +254,10 @@
(void *) android_security_cts_AudioPolicy_test_isStreamActive },
{ "native_test_isStreamActiveRemotely", "()Z",
(void *) android_security_cts_AudioPolicy_test_isStreamActiveRemotely },
+ { "native_test_startAudioSource", "()Z",
+ (void *) android_security_cts_AudioPolicy_test_startAudioSource },
+ { "native_test_getStreamVolumeLeak", "()I",
+ (void *) android_security_cts_AudioPolicy_test_getStreamVolumeLeak },
};
int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env)
diff --git a/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp b/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp
new file mode 100644
index 0000000..41262ac
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#define LOG_TAG "MediaPlayerInfoLeakTest-JNI"
+
+#include <jni.h>
+
+#include <binder/Parcel.h>
+#include <binder/IServiceManager.h>
+
+#include <media/IMediaPlayer.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IMediaPlayerClient.h>
+
+#include <sys/stat.h>
+
+using namespace android;
+
+static status_t connectMediaPlayer(sp<IMediaPlayer>& iMP)
+{
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> mediaPlayerService = sm->checkService(String16("media.player"));
+
+ sp<IMediaPlayerService> iMPService = IMediaPlayerService::asInterface(mediaPlayerService);
+ sp<IMediaPlayerClient> client;
+ Parcel data, reply;
+ int dummyAudioSessionId = 1;
+ data.writeInterfaceToken(iMPService->getInterfaceDescriptor());
+ data.writeStrongBinder(client->asBinder());
+ data.writeInt32(dummyAudioSessionId);
+
+ // Keep synchronized with IMediaPlayerService.cpp!
+ enum {
+ CREATE = IBinder::FIRST_CALL_TRANSACTION,
+ };
+ status_t err = iMPService->asBinder()->transact(CREATE, data, &reply);
+
+ if (err == NO_ERROR) {
+ iMP = interface_cast<IMediaPlayer>(reply.readStrongBinder());
+ }
+ return err;
+}
+
+int testMediaPlayerInfoLeak(int command)
+{
+ sp<IMediaPlayer> iMP;
+ if (NO_ERROR != connectMediaPlayer(iMP)) {
+ return false;
+ }
+
+
+ Parcel data, reply;
+ data.writeInterfaceToken(iMP->getInterfaceDescriptor());
+ iMP->asBinder()->transact(command, data, &reply);
+
+ int leak = reply.readInt32();
+ status_t err = reply.readInt32();
+ return leak;
+}
+
+jint android_security_cts_MediaPlayer_test_getCurrentPositionLeak(JNIEnv* env __unused,
+ jobject thiz __unused)
+{
+ // Keep synchronized with IMediaPlayer.cpp!
+ enum {
+ GET_CURRENT_POSITION = 11,
+ };
+ return testMediaPlayerInfoLeak(GET_CURRENT_POSITION);
+}
+
+jint android_security_cts_MediaPlayer_test_getDurationLeak(JNIEnv* env __unused,
+ jobject thiz __unused)
+{
+ // Keep synchronized with IMediaPlayer.cpp!
+ enum {
+ GET_DURATION = 12,
+ };
+ return testMediaPlayerInfoLeak(GET_DURATION);
+}
+
+static JNINativeMethod gMethods[] = {
+ { "native_test_getCurrentPositionLeak", "()I",
+ (void *) android_security_cts_MediaPlayer_test_getCurrentPositionLeak },
+ { "native_test_getDurationLeak", "()I",
+ (void *) android_security_cts_MediaPlayer_test_getDurationLeak },
+};
+
+int register_android_security_cts_MediaPlayerInfoLeakTest(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/security/cts/MediaPlayerInfoLeakTest");
+ return env->RegisterNatives(clazz, gMethods,
+ sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java b/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java
new file mode 100644
index 0000000..20d9615
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 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 android.media.audiofx.AudioEffect;
+
+import java.util.UUID;
+
+import junit.framework.TestCase;
+
+public class AudioEffectBinderTest extends TestCase {
+
+ static {
+ System.loadLibrary("ctssecurity_jni");
+ }
+
+ /**
+ * Checks that IEffect::command() cannot leak data.
+ */
+ public void test_isCommandSecure() throws Exception {
+ if (isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_EQUALIZER)) {
+ assertTrue(native_test_isCommandSecure());
+ }
+ }
+
+ /* see AudioEffect.isEffectTypeAvailable(), implements hidden function */
+ private static boolean isEffectTypeAvailable(UUID type) {
+ AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
+ if (desc == null) {
+ return false;
+ }
+
+ for (int i = 0; i < desc.length; i++) {
+ if (desc[i].type.equals(type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static native boolean native_test_isCommandSecure();
+}
diff --git a/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java b/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
index 37c472e..202bd65 100644
--- a/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
+++ b/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
@@ -56,8 +56,16 @@
assertTrue(native_test_listAudioPatches());
}
+ /**
+ * Checks that IAudioFlinger::createEffect() does not leak information on the server side.
+ */
+ public void test_createEffect() throws Exception {
+ assertTrue(native_test_createEffect());
+ }
+
private static native boolean native_test_setMasterMute();
private static native boolean native_test_setMasterVolume();
private static native boolean native_test_listAudioPorts();
private static native boolean native_test_listAudioPatches();
+ private static native boolean native_test_createEffect();
}
diff --git a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java b/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
index b307247..615dbf3 100644
--- a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
+++ b/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
@@ -56,8 +56,27 @@
assertTrue(native_test_isStreamActiveRemotely());
}
+ /**
+ * Checks that IAudioPolicyService::startAudioSource() cannot leak information from
+ * server side.
+ */
+ public void test_startAudioSource() throws Exception {
+ assertTrue(native_test_startAudioSource());
+ }
+
+ /**
+ * Checks that IAudioPolicyService::getStreamVolumeIndex() does not leak information
+ * when called with an invalid stream/device type.
+ */
+ public void test_getStreamVolumeLeak() throws Exception {
+ int volume = native_test_getStreamVolumeLeak();
+ assertTrue(String.format("Leaked volume 0x%08X", volume), volume == 0);
+ }
+
private static native boolean native_test_startOutput();
private static native boolean native_test_stopOutput();
private static native boolean native_test_isStreamActive();
private static native boolean native_test_isStreamActiveRemotely();
+ private static native boolean native_test_startAudioSource();
+ private static native int native_test_getStreamVolumeLeak();
}
diff --git a/tests/tests/security/src/android/security/cts/ListeningPortsTest.java b/tests/tests/security/src/android/security/cts/ListeningPortsTest.java
index 87e957d..76c53c1 100644
--- a/tests/tests/security/src/android/security/cts/ListeningPortsTest.java
+++ b/tests/tests/security/src/android/security/cts/ListeningPortsTest.java
@@ -43,9 +43,22 @@
static {
// IPv4 exceptions
- EXCEPTION_PATTERNS.add("0.0.0.0:5555"); // emulator port
- EXCEPTION_PATTERNS.add("10.0.2.15:5555"); // net forwarding for emulator
- EXCEPTION_PATTERNS.add("127.0.0.1:5037"); // adb daemon "smart sockets"
+ // Patterns containing ":" are allowed address port combinations
+ // Pattterns contains " " are allowed address UID combinations
+ // Patterns containing both are allowed address, port, and UID combinations
+ EXCEPTION_PATTERNS.add("0.0.0.0:5555"); // emulator port
+ EXCEPTION_PATTERNS.add("0.0.0.0:9101"); // verified ports
+ EXCEPTION_PATTERNS.add("0.0.0.0:9551"); // verified ports
+ EXCEPTION_PATTERNS.add("0.0.0.0:9552"); // verified ports
+ EXCEPTION_PATTERNS.add("10.0.2.15:5555"); // net forwarding for emulator
+ EXCEPTION_PATTERNS.add("127.0.0.1:5037"); // adb daemon "smart sockets"
+ EXCEPTION_PATTERNS.add("0.0.0.0 1020"); // used by the cast receiver
+ EXCEPTION_PATTERNS.add("0.0.0.0 10000"); // used by the cast receiver
+ EXCEPTION_PATTERNS.add("127.0.0.1 10000"); // used by the cast receiver
+ EXCEPTION_PATTERNS.add(":: 1002"); // used by remote control
+ EXCEPTION_PATTERNS.add(":: 1020"); // used by remote control
+ //no current patterns involve address, port and UID combinations
+ //Example for when necessary: EXCEPTION_PATTERNS.add("0.0.0.0:5555 10000")
}
/**
@@ -185,9 +198,11 @@
List<ParsedProcEntry> entries = ParsedProcEntry.parse(procFilePath);
for (ParsedProcEntry entry : entries) {
String addrPort = entry.localAddress.getHostAddress() + ':' + entry.port;
+ String addrUid = entry.localAddress.getHostAddress() + ' ' + entry.uid;
+ String addrPortUid = addrPort + ' ' + entry.uid;
if (isPortListening(entry.state, isTcp)
- && !isException(addrPort)
+ && !(isException(addrPort) || isException(addrUid) || isException(addrPortUid))
&& (!entry.localAddress.isLoopbackAddress() ^ loopback)) {
errors += "\nFound port listening on addr="
+ entry.localAddress.getHostAddress() + ", port="
diff --git a/tests/tests/security/src/android/security/cts/MediaPlayerInfoLeakTest.java b/tests/tests/security/src/android/security/cts/MediaPlayerInfoLeakTest.java
new file mode 100644
index 0000000..e34fc05
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/MediaPlayerInfoLeakTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 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 junit.framework.TestCase;
+
+public class MediaPlayerInfoLeakTest extends TestCase {
+
+ static {
+ System.loadLibrary("ctssecurity_jni");
+ }
+
+
+ /**
+ * Checks that IMediaPlayer::getCurrentPosition() does not leak info in error case
+ */
+ public void test_getCurrentPositionLeak() throws Exception {
+ int pos = native_test_getCurrentPositionLeak();
+ assertTrue(String.format("Leaked pos 0x%08X", pos), pos == 0);
+ }
+
+ /**
+ * Checks that IMediaPlayer::getDuration() does not leak info in error case
+ */
+ public void test_getDurationLeak() throws Exception {
+ int dur = native_test_getDurationLeak();
+ assertTrue(String.format("Leaked dur 0x%08X", dur), dur == 0);
+ }
+
+ private static native int native_test_getCurrentPositionLeak();
+ private static native int native_test_getDurationLeak();
+}
diff --git a/tests/tests/security/src/android/security/cts/PutOverflowTest.java b/tests/tests/security/src/android/security/cts/PutOverflowTest.java
new file mode 100644
index 0000000..e0eb34c
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/PutOverflowTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 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 android.test.AndroidTestCase;
+import java.lang.reflect.Method;
+
+public class PutOverflowTest extends AndroidTestCase {
+ public void testCrash() throws Exception {
+ try {
+ Class<?> keystoreClass = Class.forName("android.security.KeyStore");
+ Method getInstance = keystoreClass.getMethod("getInstance");
+ Method put = keystoreClass.getMethod("put",
+ String.class, byte[].class, int.class, int.class);
+ Object keystore = getInstance.invoke(null);
+ byte[] buffer = new byte[65536];
+ Boolean result = (Boolean)put.invoke(keystore, "crashFile", buffer, -1, 0);
+ assertTrue("Fix for ANDROID-22802399 not present", result);
+ } catch (ReflectiveOperationException ignored) {
+ // Since this test requires reflection avoid causing undue failures if classes or
+ // methods were changed.
+ }
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 2be1dcb..b6ae8ec 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -186,7 +186,10 @@
break;
case TelephonyManager.PHONE_TYPE_NONE:
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_WIFI) != null) {
+ boolean nwSupported = mCm.isNetworkSupported(mCm.TYPE_WIFI);
+ PackageManager packageManager = getContext().getPackageManager();
+ // only check serial number & MAC address if device report wifi feature
+ if (packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
assertSerialNumber();
assertMacAddress(getWifiMacAddress());
} else if (mCm.getNetworkInfo(ConnectivityManager.TYPE_BLUETOOTH) != null) {
diff --git a/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
index 10d08d0..482edb0 100644
--- a/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
@@ -255,7 +255,7 @@
assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_UP, noMetaEvent));
- // |first line
+ // first lin|e
// second line
// last line
assertSelection(0);
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
index 3c6028f..6514402 100755
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
@@ -165,6 +165,9 @@
// Wait for things to settle.
getUiDevice().waitForIdle();
+ // Wait for Activity draw finish
+ getInstrumentation().waitForIdleSync();
+
// Clear the window animation stats to be with a clean slate.
uiAutomation.clearWindowAnimationFrameStats();
@@ -177,6 +180,9 @@
// Wait for things to settle.
getUiDevice().waitForIdle();
+ // Wait for Activity draw finish
+ getInstrumentation().waitForIdleSync();
+
// Get the frame stats.
WindowAnimationFrameStats stats = uiAutomation.getWindowAnimationFrameStats();