am 7e91cdc9: Added vibration feedback to Projection Offscreen Test for devices without audio feedback capabilities.
* commit '7e91cdc9c2e0eb6274719b3f66fbef1b99983998':
Added vibration feedback to Projection Offscreen Test for devices without audio feedback capabilities.
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 80e1efc..12b89b9 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -100,6 +100,7 @@
CtsDeviceBrowserBench \
CtsDeviceVideoPerf \
CtsDeviceOpenGl \
+ CtsDeviceTvProviderPerf \
CtsAccelerationTestCases \
CtsAccountManagerTestCases \
CtsAccessibilityServiceTestCases \
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 523b7a1..3aa620e 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -55,6 +55,8 @@
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
+ <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<!-- Needed by the Audio Quality Verifier to store the sound samples that will be mailed. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -1450,6 +1452,37 @@
<!-- Used by the SensorTestScreenManipulator to reset the screen timeout after turn off. -->
<activity android:name=".os.TimeoutResetActivity"/>
+ <activity android:name=".tv.TvInputDiscoveryTestActivity" android:label="@string/tv">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.cts.intent.category.MANUAL_TEST" />
+ </intent-filter>
+ <meta-data android:name="test_category" android:value="@string/test_category_tv" />
+ <meta-data android:name="test_required_features"
+ android:value="android.software.live_tv" />
+ </activity>
+
+ <activity android:name=".tv.MockTvInputSettingsActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".tv.MockTvInputSetupActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
+ <service android:name=".tv.MockTvInputService"
+ android:permission="android.permission.BIND_TV_INPUT">
+ <intent-filter>
+ <action android:name="android.media.tv.TvInputService" />
+ </intent-filter>
+ <meta-data android:name="android.media.tv.input"
+ android:resource="@xml/mock_tv_input_service" />
+ </service>
+
</application>
</manifest>
diff --git a/apps/CtsVerifier/res/layout/tv_item.xml b/apps/CtsVerifier/res/layout/tv_item.xml
new file mode 100644
index 0000000..e7311f9
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/tv_item.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <ImageView
+ android:id="@+id/status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="10dip"
+ android:contentDescription="@string/pass_button_text"
+ android:padding="10dip"
+ android:src="@drawable/fs_indeterminate" />
+
+ <TextView
+ android:id="@+id/instructions"
+ style="@style/InstructionsSmallFont"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_toRightOf="@id/status" />
+
+ <Button
+ android:id="@+id/user_action_button"
+ android:enabled="false"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_below="@id/instructions"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_toRightOf="@id/status"
+ android:visibility="gone" />
+
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index e687087..383dcae 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -36,6 +36,7 @@
<string name="test_category_features">Features</string>
<string name="test_category_deskclock">Clock</string>
<string name="test_category_jobscheduler">Job Scheduler</string>
+ <string name="test_category_tv">TV</string>
<string name="test_category_other">Other</string>
<string name="clear">Clear</string>
<string name="test_results_cleared">Test results cleared.</string>
@@ -1321,7 +1322,30 @@
<string name="js_any_connectivity_test">Device with no connectivity will not execute a job with an unmetered connectivity constraint.</string>
<string name="js_no_connectivity_test">Device with no connectivity will still execute a job with no connectivity constraints.</string>
+ <!-- String for TV app Tests -->
+ <string name="tv">TV App Behavior Verifier</string>
+ <string name="tv_info">
+ This test verifies that the default TV app is invoked via intents and issues appropriate
+ calls to framework APIs, so that TV input apps work properly with the default TV app.
+ </string>
+
+ <string name="tv_input_discover_test">TV app input discoverability test</string>
+ <string name="tv_input_discover_test_go_to_setup">
+ Press the \"Launch TV app\" button, and set up the newly installed TV input: \"CTS Verifier\".
+ </string>
+ <string name="tv_input_discover_test_verify_setup">
+ Setup activity must have been started.
+ </string>
+ <string name="tv_input_discover_test_tune_to_channel">
+ Press the \"Launch TV app\" button, and tune to the channel named \"Dummy\" from
+ \"CTS Verifier\" input. If necessary, configure the channel to be visible.
+ </string>
+ <string name="tv_input_discover_test_verify_tune">
+ Tune command must be called.
+ </string>
+
+ <string name="tv_launch_tv_app">Launch TV app</string>
+
<!-- A list of fully-qualified test classes that should not be run. -->
<string-array name="disabled_tests" />
-
</resources>
diff --git a/apps/CtsVerifier/res/xml/mock_tv_input_service.xml b/apps/CtsVerifier/res/xml/mock_tv_input_service.xml
new file mode 100644
index 0000000..1a2cf86
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/mock_tv_input_service.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2014 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.
+-->
+
+<tv-input xmlns:android="http://schemas.android.com/apk/res/android"
+ android:setupActivity="com.android.cts.verifier.tv.MockTvInputSetupActivity"
+ android:settingsActivity="com.android.cts.verifier.tv.MockTvInputSettingsActivity" />
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java
index 75eaebd..3d0e0d7 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java
@@ -31,9 +31,7 @@
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
public class MockListener extends NotificationListenerService {
static final String TAG = "MockListener";
@@ -69,10 +67,8 @@
private ArrayList<String> mPosted = new ArrayList<String>();
private ArrayMap<String, JSONObject> mNotifications = new ArrayMap<>();
- private ArrayMap<String, String> mNotificationKeys = new ArrayMap<>();
private ArrayList<String> mRemoved = new ArrayList<String>();
private ArrayList<String> mOrder = new ArrayList<>();
- private Set<String> mTestPackages = new HashSet<>();
private BroadcastReceiver mReceiver;
private int mDND = -1;
@@ -81,8 +77,6 @@
super.onCreate();
Log.d(TAG, "created");
- mTestPackages.add("com.android.cts.verifier");
-
mPosted = new ArrayList<String>();
mRemoved = new ArrayList<String>();
@@ -129,13 +123,10 @@
setResultCode(Activity.RESULT_OK);
} else if (SERVICE_CLEAR_ONE.equals(action)) {
Log.d(TAG, "SERVICE_CLEAR_ONE");
- String tag = intent.getStringExtra(EXTRA_TAG);
- String key = mNotificationKeys.get(tag);
- if (key != null) {
- MockListener.this.cancelNotification(key);
- } else {
- Log.w(TAG, "Notification does not exist: " + tag);
- }
+ MockListener.this.cancelNotification(
+ context.getApplicationInfo().packageName,
+ intent.getStringExtra(EXTRA_TAG),
+ intent.getIntExtra(EXTRA_CODE, 0));
} else if (SERVICE_CLEAR_ALL.equals(action)) {
Log.d(TAG, "SERVICE_CLEAR_ALL");
MockListener.this.cancelAllNotifications();
@@ -214,7 +205,6 @@
@Override
public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
- if (!mTestPackages.contains(sbn.getPackageName())) { return; }
Log.d(TAG, "posted: " + sbn.getTag());
mPosted.add(sbn.getTag());
JSONObject notification = new JSONObject();
@@ -226,7 +216,6 @@
notification.put(JSON_ICON, sbn.getNotification().icon);
notification.put(JSON_FLAGS, sbn.getNotification().flags);
mNotifications.put(sbn.getKey(), notification);
- mNotificationKeys.put(sbn.getTag(), sbn.getKey());
} catch (JSONException e) {
Log.e(TAG, "failed to pack up notification payload", e);
}
@@ -238,9 +227,7 @@
Log.d(TAG, "removed: " + sbn.getTag());
mRemoved.add(sbn.getTag());
mNotifications.remove(sbn.getKey());
- mNotificationKeys.remove(sbn.getTag());
onNotificationRankingUpdate(rankingMap);
- mNotificationKeys.remove(sbn.getTag());
}
public static void resetListenerData(Context context) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
index dfcf120..4a0c135 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
@@ -97,7 +97,7 @@
Sensor.TYPE_ACCELEROMETER,
SensorManager.SENSOR_DELAY_FASTEST);
TestSensorOperation verifyMeasurements =
- new TestSensorOperation(environment, 100 /* event count */);
+ TestSensorOperation.createOperation(environment, 100 /* event count */);
verifyMeasurements.addVerification(new MeanVerification(
expectations,
new float[]{1.95f, 1.95f, 1.95f} /* m / s^2 */));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java
index 6f0a7aa..2d58c64 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java
@@ -22,9 +22,7 @@
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.cts.helpers.TestSensorEnvironment;
-import android.hardware.cts.helpers.sensoroperations.TestSensorFlushOperation;
import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
-import android.hardware.cts.helpers.sensoroperations.VerifiableSensorOperation;
import java.util.concurrent.TimeUnit;
@@ -128,7 +126,7 @@
int testDurationSec = maxBatchReportLatencySec + BATCHING_PADDING_TIME_S;
TestSensorOperation operation =
- new TestSensorOperation(environment, testDurationSec,TimeUnit.SECONDS);
+ TestSensorOperation.createOperation(environment, testDurationSec,TimeUnit.SECONDS);
return executeTest(operation);
}
@@ -145,12 +143,12 @@
maxBatchReportLatencyUs);
int flushDurationSec = maxBatchReportLatencySec / 2;
- TestSensorFlushOperation operation =
- new TestSensorFlushOperation(environment, flushDurationSec, TimeUnit.SECONDS);
+ TestSensorOperation operation = TestSensorOperation
+ .createFlushOperation(environment, flushDurationSec, TimeUnit.SECONDS);
return executeTest(operation);
}
- private String executeTest(VerifiableSensorOperation operation) throws InterruptedException {
+ private String executeTest(TestSensorOperation operation) throws InterruptedException {
operation.addDefaultVerifications();
operation.setLogEvents(true);
operation.execute();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
index 4b2a7f4..d6ec951 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
@@ -156,8 +156,8 @@
getApplicationContext(),
Sensor.TYPE_GYROSCOPE,
SensorManager.SENSOR_DELAY_FASTEST);
- TestSensorOperation sensorOperation =
- new TestSensorOperation(environment, ROTATION_COLLECTION_SEC, TimeUnit.SECONDS);
+ TestSensorOperation sensorOperation = TestSensorOperation
+ .createOperation(environment, ROTATION_COLLECTION_SEC, TimeUnit.SECONDS);
int gyroscopeAxes = environment.getSensorAxesCount();
int[] expectationsDeg = getExpectationsDeg(gyroscopeAxes, rotationAxis, expectationDeg);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java
index 553147b..1ec5dc1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java
@@ -79,7 +79,7 @@
Sensor.TYPE_MAGNETIC_FIELD,
SensorManager.SENSOR_DELAY_FASTEST);
TestSensorOperation verifyNorm =
- new TestSensorOperation(environment, 100 /* event count */);
+ TestSensorOperation.createOperation(environment, 100 /* event count */);
float expectedMagneticFieldEarth =
(SensorManager.MAGNETIC_FIELD_EARTH_MAX + SensorManager.MAGNETIC_FIELD_EARTH_MIN) / 2;
@@ -124,7 +124,7 @@
Sensor.TYPE_MAGNETIC_FIELD,
SensorManager.SENSOR_DELAY_FASTEST);
TestSensorOperation verifyStdDev =
- new TestSensorOperation(environment, 100 /* event count */);
+ TestSensorOperation.createOperation(environment, 100 /* event count */);
verifyStdDev.addVerification(new StandardDeviationVerification(
new float[]{2f, 2f, 2f} /* uT */));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
new file mode 100644
index 0000000..8c5b18c
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.tv;
+
+import android.content.Context;
+import android.media.tv.TvInputService;
+import android.net.Uri;
+import android.util.Pair;
+import android.view.Surface;
+import android.view.View;
+
+public class MockTvInputService extends TvInputService {
+ private static final String TAG = "MockTvInputService";
+
+ private static Object sLock = new Object();
+ private static Pair<View, Runnable> sTuneCallback = null;
+
+ static void expectTune(View postTarget, Runnable successCallback) {
+ synchronized (sLock) {
+ sTuneCallback = Pair.create(postTarget, successCallback);
+ }
+ }
+
+ @Override
+ public Session onCreateSession(String inputId) {
+ return new MockSessionImpl(this);
+ }
+
+ private static class MockSessionImpl extends Session {
+ private MockSessionImpl(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onRelease() {
+ }
+
+ @Override
+ public boolean onSetSurface(Surface surface) {
+ return true;
+ }
+
+ @Override
+ public void onSetStreamVolume(float volume) {
+ }
+
+ @Override
+ public boolean onTune(Uri channelUri) {
+ Pair<View, Runnable> tuneCallback = null;
+ synchronized (sLock) {
+ tuneCallback = sTuneCallback;
+ sTuneCallback = null;
+ }
+ if (tuneCallback != null) {
+ tuneCallback.first.post(tuneCallback.second);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onSelectTrack(int type, String trackId) {
+ return true;
+ }
+
+ @Override
+ public void onSetCaptionEnabled(boolean enabled) {
+ }
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSettingsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSettingsActivity.java
new file mode 100644
index 0000000..4231db7
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSettingsActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.tv;
+
+import android.preference.PreferenceActivity;
+
+public class MockTvInputSettingsActivity extends PreferenceActivity {
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSetupActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSetupActivity.java
new file mode 100644
index 0000000..00f0091
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSetupActivity.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.tv;
+
+import android.app.Activity;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.media.tv.TvContract;
+import android.media.tv.TvInputInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Pair;
+import android.view.View;
+
+public class MockTvInputSetupActivity extends Activity {
+ private static final String TAG = "MockTvInputSetupActivity";
+
+ private static final String CHANNEL_NUMBER = "999-999";
+ private static final String CHANNEL_NAME = "Dummy";
+
+ private static Object sLock = new Object();
+ private static Pair<View, Runnable> sLaunchCallback = null;
+
+ static void expectLaunch(View postTarget, Runnable successCallback) {
+ synchronized (sLock) {
+ sLaunchCallback = Pair.create(postTarget, successCallback);
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+ final String inputId = getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID);
+ final Uri uri = TvContract.buildChannelsUriForInput(inputId);
+ final String[] projection = { TvContract.Channels._ID };
+ try (Cursor cursor = getContentResolver().query(uri, projection, null, null, null)) {
+ // If we already have channels, just finish without doing anything.
+ if (cursor != null && cursor.getCount() > 0) {
+ return;
+ }
+ }
+ ContentValues values = new ContentValues();
+ values.put(TvContract.Channels.COLUMN_INPUT_ID, inputId);
+ values.put(TvContract.Channels.COLUMN_DISPLAY_NUMBER, CHANNEL_NUMBER);
+ values.put(TvContract.Channels.COLUMN_DISPLAY_NAME, CHANNEL_NAME);
+ Uri channelUri = getContentResolver().insert(uri, values);
+ // If the channel's ID happens to be zero, we add another and delete the one.
+ if (ContentUris.parseId(channelUri) == 0) {
+ getContentResolver().insert(uri, values);
+ getContentResolver().delete(channelUri, null, null);
+ }
+ } finally {
+ Pair<View, Runnable> launchCallback = null;
+ synchronized (sLock) {
+ launchCallback = sLaunchCallback;
+ sLaunchCallback = null;
+ }
+ if (launchCallback != null) {
+ launchCallback.first.post(launchCallback.second);
+ }
+
+ setResult(Activity.RESULT_OK);
+ finish();
+ }
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java
new file mode 100644
index 0000000..cb6df8a
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.tv;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.content.Intent;
+import android.media.tv.TvContract;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * Tests for verifying TV app behavior.
+ */
+public abstract class TvAppVerifierActivity extends PassFailButtons.Activity {
+ private static final String TAG = "TvAppVerifierActivity";
+
+ protected static final Intent TV_APP_INTENT = new Intent(Intent.ACTION_VIEW,
+ TvContract.buildChannelUri(0));
+
+ private static final long TIMEOUT_MS = 5l * 60l * 1000l; // 5 mins.
+
+ private LayoutInflater mInflater;
+ private ViewGroup mItemList;
+ private View mPostTarget;
+
+ protected View getPostTarget() {
+ return mPostTarget;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mInflater = getLayoutInflater();
+ // Reusing location_mode_main.
+ View view = mInflater.inflate(R.layout.location_mode_main, null);
+ mPostTarget = mItemList = (ViewGroup) view.findViewById(R.id.test_items);
+ createTestItems();
+ setContentView(view);
+ setPassFailButtonClickListeners();
+ setInfoResources(R.string.tv, R.string.tv_info, -1);
+
+ getPassButton().setEnabled(false);
+ }
+
+ protected void setButtonEnabled(View item, boolean enabled) {
+ View button = item.findViewById(R.id.user_action_button);
+ button.setClickable(enabled);
+ button.setEnabled(enabled);
+ }
+
+ protected void setPassState(View item, boolean passed) {
+ ImageView status = (ImageView) item.findViewById(R.id.status);
+ status.setImageResource(passed ? R.drawable.fs_good : R.drawable.fs_error);
+ View button = item.findViewById(R.id.user_action_button);
+ button.setClickable(false);
+ button.setEnabled(false);
+ status.invalidate();
+ }
+
+ protected abstract void createTestItems();
+
+ /**
+ * Call this to create a test step where the user must perform some action.
+ */
+ protected View createUserItem(int instructionTextId, int buttonTextId, View.OnClickListener l) {
+ View item = mInflater.inflate(R.layout.tv_item, mItemList, false);
+ TextView instructions = (TextView) item.findViewById(R.id.instructions);
+ instructions.setText(instructionTextId);
+ Button button = (Button) item.findViewById(R.id.user_action_button);
+ button.setVisibility(View.VISIBLE);
+ button.setText(buttonTextId);
+ button.setOnClickListener(l);
+ mItemList.addView(item);
+ return item;
+ }
+
+ /**
+ * Call this to create a test step where the test automatically evaluates whether
+ * an expected condition is satisfied.
+ */
+ protected View createAutoItem(int stringId) {
+ View item = mInflater.inflate(R.layout.tv_item, mItemList, false);
+ TextView instructions = (TextView) item.findViewById(R.id.instructions);
+ instructions.setText(stringId);
+ mItemList.addView(item);
+ return item;
+ }
+
+ static boolean containsButton(View item, View button) {
+ return item.findViewById(R.id.user_action_button) == button;
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
new file mode 100644
index 0000000..cee05e2
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.tv;
+
+import com.android.cts.verifier.R;
+
+import android.view.View;
+
+/**
+ * Tests for verifying TV app behavior.
+ */
+public class TvInputDiscoveryTestActivity extends TvAppVerifierActivity
+ implements View.OnClickListener {
+ private static final String TAG = "TvInputDiscoveryTestActivity";
+
+ private static final long TIMEOUT_MS = 5l * 60l * 1000l; // 5 mins.
+
+ private View mGoToSetupItem;
+ private View mVerifySetupItem;
+ private View mTuneToChannelItem;
+ private View mVerifyTuneItem;
+
+ @Override
+ public void onClick(View v) {
+ final View postTarget = getPostTarget();
+
+ if (containsButton(mGoToSetupItem, v)) {
+ final Runnable failCallback = new Runnable() {
+ @Override
+ public void run() {
+ setPassState(mVerifySetupItem, false);
+ }
+ };
+ postTarget.postDelayed(failCallback, TIMEOUT_MS);
+ MockTvInputSetupActivity.expectLaunch(postTarget, new Runnable() {
+ @Override
+ public void run() {
+ postTarget.removeCallbacks(failCallback);
+ setPassState(mGoToSetupItem, true);
+ setPassState(mVerifySetupItem, true);
+ setButtonEnabled(mTuneToChannelItem, true);
+ }
+ });
+ } else if (containsButton(mTuneToChannelItem, v)) {
+ final Runnable failCallback = new Runnable() {
+ @Override
+ public void run() {
+ setPassState(mVerifyTuneItem, false);
+ }
+ };
+ postTarget.postDelayed(failCallback, TIMEOUT_MS);
+ MockTvInputService.expectTune(postTarget, new Runnable() {
+ @Override
+ public void run() {
+ postTarget.removeCallbacks(failCallback);
+ setPassState(mTuneToChannelItem, true);
+ setPassState(mVerifyTuneItem, true);
+ getPassButton().setEnabled(true);
+ }
+ });
+ }
+ startActivity(TV_APP_INTENT);
+ }
+
+ @Override
+ protected void createTestItems() {
+ mGoToSetupItem = createUserItem(R.string.tv_input_discover_test_go_to_setup,
+ R.string.tv_launch_tv_app, this);
+ setButtonEnabled(mGoToSetupItem, true);
+ mVerifySetupItem = createAutoItem(R.string.tv_input_discover_test_verify_setup);
+ mTuneToChannelItem = createUserItem(R.string.tv_input_discover_test_tune_to_channel,
+ R.string.tv_launch_tv_app, this);
+ mVerifyTuneItem = createAutoItem(R.string.tv_input_discover_test_verify_tune);
+ }
+}
diff --git a/build/test_host_java_library.mk b/build/test_host_java_library.mk
index baf9e75..8e071e4 100644
--- a/build/test_host_java_library.mk
+++ b/build/test_host_java_library.mk
@@ -21,14 +21,18 @@
cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
-$(cts_library_xml): PRIVATE_PATH := $(LOCAL_PATH)/src
+cts_src_dirs := $(LOCAL_PATH)/src
+cts_src_dirs += $(sort $(dir $(LOCAL_GENERATED_SOURCES)))
+cts_src_dirs := $(addprefix -s , $(cts_src_dirs))
+
+$(cts_library_xml): PRIVATE_SRC_DIRS := $(cts_src_dirs)
$(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
$(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
$(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
$(cts_library_xml): $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE).jar $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
$(hide) echo Generating test description for host library $(PRIVATE_LIBRARY)
$(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
+ $(hide) $(CTS_JAVA_TEST_SCANNER) $(PRIVATE_SRC_DIRS) \
-d $(CTS_JAVA_TEST_SCANNER_DOCLET) | \
$(CTS_XML_GENERATOR) -t hostSideOnly \
-j $(PRIVATE_JAR_PATH) \
diff --git a/build/test_package.mk b/build/test_package.mk
index 353ae07..acb8121 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -28,12 +28,16 @@
cts_package_apk := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).apk
cts_package_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).xml
+cts_src_dirs := $(LOCAL_PATH)
+cts_src_dirs += $(sort $(dir $(LOCAL_GENERATED_SOURCES)))
+cts_src_dirs := $(addprefix -s , $(cts_src_dirs))
+
$(cts_package_apk): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
$(cts_package_apk): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk | $(ACP)
$(hide) mkdir -p $(CTS_TESTCASES_OUT)
$(hide) $(ACP) -fp $(call intermediates-dir-for,APPS,$(PRIVATE_PACKAGE))/package.apk $@
-$(cts_package_xml): PRIVATE_PATH := $(LOCAL_PATH)
+$(cts_library_xml): PRIVATE_SRC_DIRS := $(cts_src_dirs)
$(cts_package_xml): PRIVATE_INSTRUMENTATION := $(LOCAL_INSTRUMENTATION_FOR)
$(cts_package_xml): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
ifneq ($(filter cts/suite/cts/%, $(LOCAL_PATH)),)
@@ -48,7 +52,7 @@
$(hide) echo Generating test description for java package $(PRIVATE_PACKAGE)
$(hide) mkdir -p $(CTS_TESTCASES_OUT)
$(hide) $(CTS_JAVA_TEST_SCANNER) \
- -s $(PRIVATE_PATH) \
+ $(PRIVATE_SRC_DIRS) \
-d $(CTS_JAVA_TEST_SCANNER_DOCLET) | \
$(CTS_XML_GENERATOR) \
-t $(PRIVATE_TEST_TYPE) \
diff --git a/build/test_uiautomator.mk b/build/test_uiautomator.mk
index 5e2f07a..085d672 100644
--- a/build/test_uiautomator.mk
+++ b/build/test_uiautomator.mk
@@ -24,12 +24,16 @@
cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
+cts_src_dirs := $(LOCAL_PATH)/src
+cts_src_dirs += $(sort $(dir $(LOCAL_GENERATED_SOURCES)))
+cts_src_dirs := $(addprefix -s , $(cts_src_dirs))
+
$(cts_library_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
$(cts_library_jar): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE))/javalib.jar | $(ACP)
$(hide) mkdir -p $(CTS_TESTCASES_OUT)
$(hide) $(ACP) -fp $(call intermediates-dir-for,JAVA_LIBRARIES,$(PRIVATE_MODULE))/javalib.jar $@
-$(cts_library_xml): PRIVATE_PATH := $(LOCAL_PATH)/src
+$(cts_library_xml): PRIVATE_SRC_DIRS := $(cts_src_dirs)
$(cts_library_xml): PRIVATE_TEST_APP_PACKAGE := $(LOCAL_CTS_TEST_APP_PACKAGE)
$(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
$(cts_library_xml): PRIVATE_TEST_APK := $(LOCAL_CTS_TEST_APK)
@@ -38,7 +42,7 @@
$(cts_library_xml): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE))/javalib.jar $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
$(hide) echo Generating test description for uiautomator library $(PRIVATE_LIBRARY)
$(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
+ $(hide) $(CTS_JAVA_TEST_SCANNER) $(PRIVATE_SRC_DIRS) \
-d $(CTS_JAVA_TEST_SCANNER_DOCLET) | \
$(CTS_XML_GENERATOR) -t uiAutomator \
-i $(PRIVATE_TEST_APK) \
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index fe8f9ee..18ee963 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -27,6 +27,8 @@
import android.provider.DocumentsProvider;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
import android.test.InstrumentationTestCase;
import android.test.MoreAsserts;
@@ -66,6 +68,20 @@
mActivity.finish();
}
+ private UiObject findRoot(String label) throws UiObjectNotFoundException {
+ final UiSelector rootsList = new UiSelector().resourceId(
+ "com.android.documentsui:id/container_roots").childSelector(
+ new UiSelector().resourceId("android:id/list"));
+
+ // Wait for the first list item to appear
+ assertTrue("First list item",
+ new UiObject(rootsList.childSelector(new UiSelector())).waitForExists(TIMEOUT));
+
+ // Now scroll around to find our item
+ new UiScrollable(rootsList).scrollIntoView(new UiSelector().text(label));
+ return new UiObject(rootsList.childSelector(new UiSelector().text(label)));
+ }
+
public void testOpenSimple() throws Exception {
if (!supportedHardware()) return;
@@ -83,13 +99,13 @@
// Ensure that we see both of our roots
mDevice.waitForIdle();
- assertTrue("CtsLocal root", new UiObject(new UiSelector().text("CtsLocal")).waitForExists(TIMEOUT));
- assertTrue("CtsCreate root", new UiObject(new UiSelector().text("CtsCreate")).exists());
- assertFalse("CtsGetContent", new UiObject(new UiSelector().text("CtsGetContent")).exists());
+ assertTrue("CtsLocal root", findRoot("CtsLocal").exists());
+ assertTrue("CtsCreate root", findRoot("CtsCreate").exists());
+ assertFalse("CtsGetContent root", findRoot("CtsGetContent").exists());
// Pick a specific file from our test provider
mDevice.waitForIdle();
- new UiObject(new UiSelector().text("CtsLocal")).click();
+ findRoot("CtsLocal").click();
mDevice.waitForIdle();
new UiObject(new UiSelector().text("FILE1")).click();
@@ -118,7 +134,8 @@
mActivity.startActivityForResult(intent, 42);
mDevice.waitForIdle();
- new UiObject(new UiSelector().text("CtsCreate")).click();
+ findRoot("CtsCreate").click();
+
mDevice.waitForIdle();
new UiObject(new UiSelector().resourceId("com.android.documentsui:id/container_save")
.childSelector(new UiSelector().resourceId("android:id/button1"))).click();
@@ -142,7 +159,7 @@
mActivity.startActivityForResult(intent, 42);
mDevice.waitForIdle();
- new UiObject(new UiSelector().text("CtsCreate")).click();
+ findRoot("CtsCreate").click();
// Pick file2, which should be selected since MIME matches, then try
// picking a non-matching MIME, which should leave file2 selected.
@@ -168,7 +185,8 @@
mActivity.startActivityForResult(intent, 42);
mDevice.waitForIdle();
- new UiObject(new UiSelector().text("CtsCreate")).click();
+ findRoot("CtsCreate").click();
+
mDevice.waitForIdle();
new UiObject(new UiSelector().text("DIR2")).click();
mDevice.waitForIdle();
@@ -244,12 +262,12 @@
// Look around, we should be able to see both DocumentsProviders and
// other GET_CONTENT sources.
mDevice.waitForIdle();
- assertTrue("CtsLocal root", new UiObject(new UiSelector().text("CtsLocal")).waitForExists(TIMEOUT));
- assertTrue("CtsCreate root", new UiObject(new UiSelector().text("CtsCreate")).exists());
- assertTrue("CtsGetContent", new UiObject(new UiSelector().text("CtsGetContent")).exists());
+ assertTrue("CtsLocal root", findRoot("CtsLocal").exists());
+ assertTrue("CtsCreate root", findRoot("CtsCreate").exists());
+ assertTrue("CtsGetContent root", findRoot("CtsGetContent").exists());
mDevice.waitForIdle();
- new UiObject(new UiSelector().text("CtsGetContent")).click();
+ findRoot("CtsGetContent").click();
final Result result = mActivity.getResult();
assertEquals("ReSuLt", result.data.getAction());
diff --git a/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk
index eb71540..715905a 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk
@@ -18,7 +18,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetPermDefSigningA
@@ -31,7 +30,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetPermDefSigningB
diff --git a/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk
index 000b12a..eceea38 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk
@@ -18,7 +18,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetPermUseSigningA
@@ -31,7 +30,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetPermUseSigningB
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
index 6220790..efba345 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
@@ -18,7 +18,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetSigningAUpgradeA
@@ -30,7 +29,6 @@
#apks signed by cts-keyset-test-b
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetSigningBUpgradeA
@@ -43,7 +41,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetSigningAAndBUpgradeA
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk
index 534dba3..219689e 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk
@@ -18,7 +18,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetSigningAUpgradeAAndB
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk
index 75729e0..040c378 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk
@@ -18,7 +18,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetSigningAUpgradeAOrB
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk
index 121c342..62b5461 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk
@@ -18,7 +18,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetSigningAUpgradeB
@@ -31,7 +30,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetSigningBUpgradeB
@@ -44,7 +42,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetSigningAAndCUpgradeB
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk
index a8746ec..5fc4ab9 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk
@@ -18,7 +18,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_PACKAGE_NAME := CtsKeySetSigningAUpgradeNone
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml b/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
index e1f6886..5bbdf76 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
@@ -24,9 +24,10 @@
<application>
<activity android:name="com.android.cts.intent.receiver.IntentReceiverActivity">
<intent-filter>
+ <action android:name="com.android.cts.action.COPY_TO_CLIPBOARD" />
<action android:name="com.android.cts.action.READ_FROM_URI" />
- <action android:name="com.android.cts.action.WRITE_TO_URI" />
<action android:name="com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION" />
+ <action android:name="com.android.cts.action.WRITE_TO_URI" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
index 59f0752..294c678 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
@@ -16,6 +16,8 @@
package com.android.cts.intent.receiver;
import android.app.Activity;
+import android.content.ClipboardManager;
+import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@@ -35,21 +37,36 @@
private static final String TAG = "IntentReceiverActivity";
- private static final String ACTION_READ_FROM_URI = "com.android.cts.action.READ_FROM_URI";
+ private static final String ACTION_COPY_TO_CLIPBOARD =
+ "com.android.cts.action.COPY_TO_CLIPBOARD";
- private static final String ACTION_WRITE_TO_URI = "com.android.cts.action.WRITE_TO_URI";
+ private static final String ACTION_READ_FROM_URI =
+ "com.android.cts.action.READ_FROM_URI";
private static final String ACTION_TAKE_PERSISTABLE_URI_PERMISSION =
"com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION";
+ private static final String ACTION_WRITE_TO_URI =
+ "com.android.cts.action.WRITE_TO_URI";
+
+
private static final String EXTRA_CAUGHT_SECURITY_EXCEPTION = "extra_caught_security_exception";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Intent received = getIntent();
- String action = received.getAction();
- Uri uri = getIntent().getClipData().getItemAt(0).getUri();
- if (ACTION_READ_FROM_URI.equals(action)) {
+ final Intent received = getIntent();
+ final String action = received.getAction();
+ final ClipData clipData = getIntent().getClipData();
+ final Uri uri = clipData != null ? clipData.getItemAt(0).getUri() : null;
+ if (ACTION_COPY_TO_CLIPBOARD.equals(action)) {
+ String text = received.getStringExtra("extra_text");
+ Log.i(TAG, "Copying \"" + text + "\" to the clipboard");
+ ClipData clip = ClipData.newPlainText("", text);
+ ClipboardManager clipboard =
+ (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ clipboard.setPrimaryClip(clip);
+ setResult(Activity.RESULT_OK);
+ } else if (ACTION_READ_FROM_URI.equals(action)) {
Intent result = new Intent();
String message = null;
try {
@@ -63,6 +80,11 @@
Log.i(TAG, "Message received in reading test: " + message);
result.putExtra("extra_response", message);
setResult(Activity.RESULT_OK, result);
+ } else if (ACTION_TAKE_PERSISTABLE_URI_PERMISSION.equals(action)) {
+ Log.i(TAG, "Taking persistable uri permission to " + uri);
+ getContentResolver().takePersistableUriPermission(uri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ setResult(Activity.RESULT_OK);
} else if (ACTION_WRITE_TO_URI.equals(action)) {
Intent result = new Intent();
String message = received.getStringExtra("extra_message");
@@ -76,11 +98,6 @@
Log.i(TAG, "Caught a IOException while trying to write to " + uri, e);
}
setResult(Activity.RESULT_OK, result);
- } else if (ACTION_TAKE_PERSISTABLE_URI_PERMISSION.equals(action)) {
- Log.i(TAG, "Taking persistable uri permission to " + uri);
- getContentResolver().takePersistableUriPermission(uri,
- Intent.FLAG_GRANT_READ_URI_PERMISSION);
- setResult(Activity.RESULT_OK);
}
finish();
}
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderTest.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/ContentTest.java
similarity index 94%
rename from hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderTest.java
rename to hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/ContentTest.java
index 47de0da..1aaa5ab 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderTest.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/ContentTest.java
@@ -32,7 +32,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
-public class IntentSenderTest extends InstrumentationTestCase {
+public class ContentTest extends InstrumentationTestCase {
private static final String MESSAGE = "Sample Message";
@@ -57,8 +57,8 @@
@Override
public void tearDown() throws Exception {
- super.tearDown();
mActivity.finish();
+ super.tearDown();
}
/**
@@ -73,7 +73,7 @@
intent.setClipData(ClipData.newRawUri("", uri));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- final Intent result = mActivity.getResult(intent);
+ final Intent result = mActivity.getCrossProfileResult(intent);
assertNotNull(result);
assertEquals(MESSAGE, result.getStringExtra("extra_response"));
}
@@ -95,7 +95,7 @@
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_READ_URI_PERMISSION);
- mActivity.getResult(intent);
+ mActivity.getCrossProfileResult(intent);
assertEquals(MESSAGE, getFirstLineFromUri(uri));
}
@@ -107,7 +107,7 @@
Intent intent = new Intent(ACTION_READ_FROM_URI);
intent.setClipData(ClipData.newRawUri("", uri));
- final Intent result = mActivity.getResult(intent);
+ final Intent result = mActivity.getCrossProfileResult(intent);
assertNotNull(result);
assertEquals(MESSAGE, result.getStringExtra("extra_response"));
}
@@ -136,7 +136,7 @@
Intent notGrant = new Intent(ACTION_READ_FROM_URI);
notGrant.setClipData(ClipData.newRawUri("", uriNotGranted));
- final Intent result = mActivity.getResult(notGrant);
+ final Intent result = mActivity.getCrossProfileResult(notGrant);
assertNotNull(result);
// The receiver did not have permission to read the uri. So it should have caught a security
// exception.
@@ -155,7 +155,7 @@
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// We're expecting to run into a security exception
- final Intent result = mActivity.getResult(intent);
+ final Intent result = mActivity.getCrossProfileResult(intent);
if (result == null) {
// This is fine; probably of a SecurityException when off in the
// system somewhere.
@@ -170,7 +170,7 @@
grantPersistable.setClipData(ClipData.newRawUri("", uri));
grantPersistable.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
- mActivity.getResult(grantPersistable);
+ mActivity.getCrossProfileResult(grantPersistable);
}
private Uri getBasicContentProviderUri(String path) {
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java
new file mode 100644
index 0000000..a5d83db
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.intent.sender;
+
+import android.content.ClipboardManager;
+import android.content.ClipData;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+public class CopyPasteTest extends InstrumentationTestCase
+ implements ClipboardManager.OnPrimaryClipChangedListener {
+
+ private IntentSenderActivity mActivity;
+ private ClipboardManager mClipboard;
+ private Semaphore mNotified;
+
+ private static String ACTION_COPY_TO_CLIPBOARD = "com.android.cts.action.COPY_TO_CLIPBOARD";
+
+ private static String INITIAL_TEXT = "initial text";
+ private static String NEW_TEXT = "sample text";
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ Context context = getInstrumentation().getTargetContext();
+ mActivity = launchActivity(context.getPackageName(), IntentSenderActivity.class, null);
+ mClipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ mActivity.finish();
+ super.tearDown();
+ }
+
+ public void testCanReadAcrossProfiles() throws Exception {
+ ClipData clip = ClipData.newPlainText(""/*label*/, INITIAL_TEXT);
+ mClipboard.setPrimaryClip(clip);
+ assertEquals(INITIAL_TEXT , getTextFromClipboard());
+
+ askCrossProfileReceiverToCopy(NEW_TEXT);
+
+ assertEquals(NEW_TEXT, getTextFromClipboard());
+ }
+
+ public void testCannotReadAcrossProfiles() throws Exception {
+ ClipData clip = ClipData.newPlainText(""/*label*/, INITIAL_TEXT);
+ mClipboard.setPrimaryClip(clip);
+ assertEquals(INITIAL_TEXT , getTextFromClipboard());
+
+ askCrossProfileReceiverToCopy(NEW_TEXT);
+
+ String clipboardText = getTextFromClipboard();
+ assertTrue("The clipboard text is " + clipboardText + " but should be <null> or "
+ + INITIAL_TEXT, clipboardText == null || clipboardText.equals(INITIAL_TEXT));
+ }
+
+ public void testIsNotified() throws Exception {
+ try {
+ mNotified = new Semaphore(0);
+ mActivity.addPrimaryClipChangedListener(this);
+
+ askCrossProfileReceiverToCopy(NEW_TEXT);
+
+ assertTrue(mNotified.tryAcquire(5, TimeUnit.SECONDS));
+ } finally {
+ mActivity.removePrimaryClipChangedListener(this);
+ }
+ }
+
+ private void askCrossProfileReceiverToCopy(String text) throws Exception {
+ Intent intent = new Intent(ACTION_COPY_TO_CLIPBOARD);
+ intent.putExtra("extra_text", text);
+ mActivity.getCrossProfileResult(intent);
+ }
+
+ private String getTextFromClipboard() {
+ ClipData clip = mClipboard.getPrimaryClip();
+ if (clip == null) {
+ return null;
+ }
+ ClipData.Item item = clip.getItemAt(0);
+ if (item == null) {
+ return null;
+ }
+ CharSequence text = item.getText();
+ if (text == null) {
+ return null;
+ }
+ return text.toString();
+ }
+
+
+ @Override
+ public void onPrimaryClipChanged() {
+ mNotified.release();
+ }
+
+}
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
index 00fa6b7..fd421ac 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
@@ -17,15 +17,27 @@
package com.android.cts.intent.sender;
import android.app.Activity;
+import android.content.ClipboardManager;
+import android.content.ClipboardManager.OnPrimaryClipChangedListener;
+import android.content.ComponentName;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.util.Log;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
+import java.util.List;
public class IntentSenderActivity extends Activity {
+ private static String TAG = "IntentSenderActivity";
+
private final SynchronousQueue<Result> mResult = new SynchronousQueue<>();
+ private ClipboardManager mClipboardManager;
+
public static class Result {
public final int resultCode;
public final Intent data;
@@ -37,6 +49,12 @@
}
@Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mClipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ }
+
+ @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
try {
@@ -52,4 +70,38 @@
final Result result = mResult.poll(30, TimeUnit.SECONDS);
return (result != null) ? result.data : null;
}
+
+ /**
+ * This method will send an intent accross profiles to IntentReceiverActivity, and return the
+ * result intent set by IntentReceiverActivity.
+ */
+ public Intent getCrossProfileResult(Intent intent)
+ throws Exception {
+ PackageManager pm = getPackageManager();
+ List<ResolveInfo> ris = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ // There should be two matches:
+ // - com.android.cts.intent.receiver (on the current profile).
+ // - One that will send the intent to the other profile.
+ // It's the second one we want to send the intent to.
+
+ for (ResolveInfo ri : ris) {
+ if (!ri.activityInfo.packageName.equals("com.android.cts.intent.receiver")) {
+ intent.setComponent(new ComponentName(ri.activityInfo.packageName,
+ ri.activityInfo.name));
+ return getResult(intent);
+ }
+ }
+ Log.e(TAG, "The intent " + intent + " cannot be sent accross profiles");
+ return null;
+ }
+
+ public void addPrimaryClipChangedListener(OnPrimaryClipChangedListener listener) {
+ mClipboardManager.addPrimaryClipChangedListener(listener);
+ }
+
+ public void removePrimaryClipChangedListener(
+ OnPrimaryClipChangedListener listener) {
+ mClipboardManager.removePrimaryClipChangedListener(listener);
+ }
+
}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
index 9615991..49001e9 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
@@ -21,8 +21,15 @@
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.IntentFilter;
+import android.os.UserManager;
import android.test.AndroidTestCase;
+/**
+ * The methods in this class are not really tests.
+ * They are just performing an action that is needed for a test.
+ * But we're still using an AndroidTestCase because it's an easy way to call
+ * device-side methods from the host.
+ */
public class CrossProfileUtils extends AndroidTestCase {
private static final String ACTION_READ_FROM_URI = "com.android.cts.action.READ_FROM_URI";
@@ -31,16 +38,14 @@
private static final String ACTION_TAKE_PERSISTABLE_URI_PERMISSION =
"com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION";
+ private static String ACTION_COPY_TO_CLIPBOARD = "com.android.cts.action.COPY_TO_CLIPBOARD";
+
public void addParentCanAccessManagedFilters() {
removeAllFilters();
final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
Context.DEVICE_POLICY_SERVICE);
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ACTION_READ_FROM_URI);
- intentFilter.addAction(ACTION_WRITE_TO_URI);
- intentFilter.addAction(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
- dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, intentFilter,
+ dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, getIntentFilter(),
DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
}
@@ -49,12 +54,17 @@
final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
Context.DEVICE_POLICY_SERVICE);
+ dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, getIntentFilter(),
+ DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+ }
+
+ public IntentFilter getIntentFilter() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_READ_FROM_URI);
intentFilter.addAction(ACTION_WRITE_TO_URI);
intentFilter.addAction(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
- dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, intentFilter,
- DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+ intentFilter.addAction(ACTION_COPY_TO_CLIPBOARD);
+ return intentFilter;
}
public void removeAllFilters() {
@@ -62,4 +72,18 @@
Context.DEVICE_POLICY_SERVICE);
dpm.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
}
+
+ public void disallowCrossProfileCopyPaste() {
+ DevicePolicyManager dpm = (DevicePolicyManager)
+ getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
+ dpm.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
+ UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
+ }
+
+ public void allowCrossProfileCopyPaste() {
+ DevicePolicyManager dpm = (DevicePolicyManager)
+ getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
+ dpm.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+ UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
+ }
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 6ece85c..51b7930 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -49,6 +49,8 @@
if (mHasFeature) {
mUserId = createManagedProfile();
installApp(MANAGED_PROFILE_APK);
+ installApp(INTENT_RECEIVER_APK);
+ installApp(INTENT_SENDER_APK);
setProfileOwner(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
startUser(mUserId);
}
@@ -59,8 +61,9 @@
if (mHasFeature) {
removeUser(mUserId);
getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
+ getDevice().uninstallPackage(INTENT_SENDER_PKG);
+ getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
}
-
super.tearDown();
}
@@ -114,30 +117,58 @@
return;
}
- try {
- getDevice().uninstallPackage(INTENT_SENDER_PKG);
- getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
- installAppAsUser(INTENT_SENDER_APK, 0);
- installAppAsUser(INTENT_RECEIVER_APK, mUserId);
+ // Test from parent to managed
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ "removeAllFilters", mUserId));
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ "addManagedCanAccessParentFilters", mUserId));
+ assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", 0));
- // Test from parent to managed
- assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
- "addManagedCanAccessParentFilters", mUserId));
- assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".IntentSenderTest", 0));
+ // Test from managed to parent
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ "removeAllFilters", mUserId));
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ "addParentCanAccessManagedFilters", mUserId));
+ assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", mUserId));
- getDevice().uninstallPackage(INTENT_SENDER_PKG);
- getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
- installAppAsUser(INTENT_SENDER_APK, mUserId);
- installAppAsUser(INTENT_RECEIVER_APK, 0);
+ }
- // Test from managed to parent
- assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
- "addParentCanAccessManagedFilters", mUserId));
- assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".IntentSenderTest", mUserId));
+ public void testCrossProfileCopyPaste() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
- } finally {
- getDevice().uninstallPackage(INTENT_SENDER_PKG);
- getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ "allowCrossProfileCopyPaste", mUserId));
+ // Test that managed can see what is copied in the parent.
+ testCrossProfileCopyPasteInternal(mUserId, true);
+ // Test that the parent can see what is copied in managed.
+ testCrossProfileCopyPasteInternal(0, true);
+
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ "disallowCrossProfileCopyPaste", mUserId));
+ // Test that managed can still see what is copied in the parent.
+ testCrossProfileCopyPasteInternal(mUserId, true);
+ // Test that the parent cannot see what is copied in managed.
+ testCrossProfileCopyPasteInternal(0, false);
+ }
+
+ private void testCrossProfileCopyPasteInternal(int userId, boolean shouldSucceed)
+ throws DeviceNotAvailableException {
+ final String direction = (userId == 0) ? "addManagedCanAccessParentFilters"
+ : "addParentCanAccessManagedFilters";
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ "removeAllFilters", mUserId));
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ direction, mUserId));
+ if (shouldSucceed) {
+ assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".CopyPasteTest",
+ "testCanReadAcrossProfiles", userId));
+ assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".CopyPasteTest",
+ "testIsNotified", userId));
+ } else {
+ assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".CopyPasteTest",
+ "testCannotReadAcrossProfiles", userId));
}
}
diff --git a/hostsidetests/security/Android.mk b/hostsidetests/security/Android.mk
index a42ee8a..6ff0ebf 100644
--- a/hostsidetests/security/Android.mk
+++ b/hostsidetests/security/Android.mk
@@ -23,12 +23,27 @@
# Must match the package name in CtsTestCaseList.mk
LOCAL_MODULE := CtsSecurityHostTestCases
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed ddmlib-prebuilt tradefed-prebuilt
LOCAL_CTS_TEST_PACKAGE := android.host.security
LOCAL_JAVA_RESOURCE_FILES := $(HOST_OUT_EXECUTABLES)/sepolicy-analyze
+selinux_general_policy := $(call intermediates-dir-for,ETC,general_sepolicy.conf)/general_sepolicy.conf
+
+selinux_neverallow_gen := cts/tools/selinux/SELinuxNeverallowTestGen.py
+
+selinux_neverallow_gen_data := cts/tools/selinux/SELinuxNeverallowTestFrame.py
+
+LOCAL_GENERATED_SOURCES := $(call local-generated-sources-dir)/android/cts/security/SELinuxNeverallowRulesTest.java
+
+$(LOCAL_GENERATED_SOURCES) : PRIVATE_SELINUX_GENERAL_POLICY := $(selinux_general_policy)
+$(LOCAL_GENERATED_SOURCES) : $(selinux_neverallow_gen) $(selinux_general_policy) $(selinux_neverallow_gen_data)
+ mkdir -p $(dir $@)
+ $< $(PRIVATE_SELINUX_GENERAL_POLICY) $@
+
include $(BUILD_CTS_HOST_JAVA_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
similarity index 76%
rename from hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
rename to hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
index e2c98fe..96845b1 100644
--- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security.cts;
+package android.cts.security;
import com.android.cts.tradefed.build.CtsBuildHelper;
import com.android.ddmlib.Log;
@@ -26,9 +26,10 @@
import java.io.BufferedReader;
import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.FileOutputStream;
import java.lang.String;
import java.net.URL;
import java.util.Scanner;
@@ -42,15 +43,42 @@
*/
public class SELinuxHostTest extends DeviceTestCase {
+ private File sepolicyAnalyze;
+ private File devicePolicyFile;
+
/**
* A reference to the device under test.
*/
private ITestDevice mDevice;
+ private File copyResourceToTempFile(String resName) throws IOException {
+ InputStream is = this.getClass().getResourceAsStream(resName);
+ File tempFile = File.createTempFile("SELinuxHostTest", ".tmp");
+ FileOutputStream os = new FileOutputStream(tempFile);
+ int rByte = 0;
+ while ((rByte = is.read()) != -1) {
+ os.write(rByte);
+ }
+ os.flush();
+ os.close();
+ tempFile.deleteOnExit();
+ return tempFile;
+ }
+
@Override
protected void setUp() throws Exception {
super.setUp();
mDevice = getDevice();
+
+ /* retrieve the sepolicy-analyze executable from jar */
+ sepolicyAnalyze = copyResourceToTempFile("/sepolicy-analyze");
+ sepolicyAnalyze.setExecutable(true);
+
+ /* obtain sepolicy file from running device */
+ devicePolicyFile = File.createTempFile("sepolicy", ".tmp");
+ devicePolicyFile.deleteOnExit();
+ mDevice.executeAdbCommand("pull", "/sys/fs/selinux/policy",
+ devicePolicyFile.getAbsolutePath());
}
/**
@@ -60,25 +88,9 @@
*/
public void testAllEnforcing() throws Exception {
- /* retrieve the sepolicy-analyze executable from jar */
- InputStream is = this.getClass().getResourceAsStream("/sepolicy-analyze");
- File execFile = File.createTempFile("sepolicy-analyze", ".tmp");
- FileOutputStream os = new FileOutputStream(execFile);
- int rByte = 0;
- while ((rByte = is.read()) != -1) {
- os.write(rByte);
- }
- os.flush();
- os.close();
- execFile.setExecutable(true);
-
- /* obtain sepolicy file from running device */
- File policyFile = File.createTempFile("sepolicy", ".tmp");
- mDevice.executeAdbCommand("pull", "/sys/fs/selinux/policy", policyFile.getAbsolutePath());
-
/* run sepolicy-analyze permissive check on policy file */
- ProcessBuilder pb = new ProcessBuilder(execFile.getAbsolutePath(), "-p", "-P",
- policyFile.getAbsolutePath());
+ ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
+ devicePolicyFile.getAbsolutePath(), "permissive");
pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
pb.redirectErrorStream(true);
Process p = pb.start();
@@ -90,10 +102,6 @@
errorString.append(line);
errorString.append("\n");
}
-
- /* clean up and check condition */
- execFile.delete();
- policyFile.delete();
assertTrue("The following SELinux domains were found to be in permissive mode:\n"
+ errorString, errorString.length() == 0);
}
diff --git a/libs/deviceutil/src/android/cts/util/MediaUtils.java b/libs/deviceutil/src/android/cts/util/MediaUtils.java
new file mode 100644
index 0000000..8e88b47
--- /dev/null
+++ b/libs/deviceutil/src/android/cts/util/MediaUtils.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2014 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.cts.util;
+
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.media.MediaCodecList;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import java.lang.reflect.Method;
+import static java.lang.reflect.Modifier.isPublic;
+import static java.lang.reflect.Modifier.isStatic;
+import java.util.Map;
+import android.util.Log;
+
+import java.io.IOException;
+
+public class MediaUtils {
+ final public static String TAG = "MediaUtils";
+
+ /**
+ * Finds test name (heuristically) and prints out standard skip message.
+ *
+ * Since it uses heuristics, this method has only been verified for media
+ * tests. This centralizes the way to signal a skipped test.
+ */
+ public static void skipTest(String tag, String reason) {
+ int bestScore = -1;
+ String testName = "test???";
+ Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
+ for (Map.Entry<Thread, StackTraceElement[]> entry : traces.entrySet()) {
+ StackTraceElement[] stack = entry.getValue();
+ for (int index = 0; index < stack.length; ++index) {
+ // method name must start with "test"
+ String methodName = stack[index].getMethodName();
+ if (!methodName.startsWith("test")) {
+ continue;
+ }
+
+ int score = 0;
+ // see if there is a public non-static void method that takes no argument
+ Class<?> clazz;
+ try {
+ clazz = Class.forName(stack[index].getClassName());
+ ++score;
+ for (final Method method : clazz.getDeclaredMethods()) {
+ if (method.getName().equals(methodName)
+ && isPublic(method.getModifiers())
+ && !isStatic(method.getModifiers())
+ && method.getParameterTypes().length == 0
+ && method.getReturnType().equals(Void.TYPE)) {
+ ++score;
+ break;
+ }
+ }
+ if (score == 1) {
+ // if we could read the class, but method is not public void, it is
+ // not a candidate
+ continue;
+ }
+ } catch (ClassNotFoundException e) {
+ }
+
+ // even if we cannot verify the method signature, there are signals in the stack
+
+ // usually test method is invoked by reflection
+ int depth = 1;
+ while (index + depth < stack.length
+ && stack[index + depth].getMethodName().equals("invoke")
+ && stack[index + depth].getClassName().equals(
+ "java.lang.reflect.Method")) {
+ ++depth;
+ }
+ if (depth > 1) {
+ ++score;
+ // and usually test method is run by runMethod method in android.test package
+ if (index + depth < stack.length) {
+ if (stack[index + depth].getClassName().startsWith("android.test.")) {
+ ++score;
+ }
+ if (stack[index + depth].getMethodName().equals("runMethod")) {
+ ++score;
+ }
+ }
+ }
+
+ if (score > bestScore) {
+ bestScore = score;
+ testName = methodName;
+ }
+ }
+ }
+
+ Log.i(tag, "SKIPPING " + testName + "(): " + reason);
+ }
+
+ /**
+ * Finds test name (heuristically) and prints out standard skip message.
+ *
+ * Since it uses heuristics, this method has only been verified for media
+ * tests. This centralizes the way to signal a skipped test.
+ */
+ public static void skipTest(String reason) {
+ skipTest(TAG, reason);
+ }
+
+ /**
+ * return true iff all audio and video tracks are supported
+ */
+ public static boolean hasCodecsForMedia(MediaExtractor ex) {
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ for (int i = 0; i < ex.getTrackCount(); ++i) {
+ MediaFormat format = ex.getTrackFormat(i);
+ // only check for audio and video codecs
+ String mime = format.getString(MediaFormat.KEY_MIME).toLowerCase();
+ if (!mime.startsWith("audio/") && !mime.startsWith("video/")) {
+ continue;
+ }
+ if (mcl.findDecoderForFormat(format) == null) {
+ Log.i(TAG, "no decoder for " + format);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * return true iff any track starting with mimePrefix is supported
+ */
+ public static boolean hasCodecForMediaAndDomain(MediaExtractor ex, String mimePrefix) {
+ mimePrefix = mimePrefix.toLowerCase();
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ for (int i = 0; i < ex.getTrackCount(); ++i) {
+ MediaFormat format = ex.getTrackFormat(i);
+ String mime = format.getString(MediaFormat.KEY_MIME);
+ if (mime.toLowerCase().startsWith(mimePrefix)) {
+ if (mcl.findDecoderForFormat(format) == null) {
+ Log.i(TAG, "no decoder for " + format);
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * return true iff all audio and video tracks are supported
+ */
+ public static boolean hasCodecsForResource(Context context, int resourceId) {
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ try {
+ AssetFileDescriptor afd = null;
+ MediaExtractor ex = null;
+ try {
+ afd = context.getResources().openRawResourceFd(resourceId);
+ ex = new MediaExtractor();
+ ex.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+ return hasCodecsForMedia(ex);
+ } finally {
+ if (ex != null) {
+ ex.release();
+ }
+ if (afd != null) {
+ afd.close();
+ }
+ }
+ } catch (IOException e) {
+ Log.i(TAG, "could not open resource");
+ }
+ return false;
+ }
+
+ /**
+ * return true iff any track starting with mimePrefix is supported
+ */
+ public static boolean hasCodecForResourceAndDomain(
+ Context context, int resourceId, String mimePrefix) {
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ try {
+ AssetFileDescriptor afd = null;
+ MediaExtractor ex = null;
+ try {
+ afd = context.getResources().openRawResourceFd(resourceId);
+ ex = new MediaExtractor();
+ ex.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+ return hasCodecForMediaAndDomain(ex, mimePrefix);
+ } finally {
+ if (ex != null) {
+ ex.release();
+ }
+ if (afd != null) {
+ afd.close();
+ }
+ }
+ } catch (IOException e) {
+ Log.i(TAG, "could not open resource");
+ }
+ return false;
+ }
+}
diff --git a/suite/cts/deviceTests/tvproviderperf/Android.mk b/suite/cts/deviceTests/tvproviderperf/Android.mk
new file mode 100644
index 0000000..e268955
--- /dev/null
+++ b/suite/cts/deviceTests/tvproviderperf/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2014 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsDeviceTvProviderPerf
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+
diff --git a/suite/cts/deviceTests/tvproviderperf/AndroidManifest.xml b/suite/cts/deviceTests/tvproviderperf/AndroidManifest.xml
new file mode 100644
index 0000000..d345ab2
--- /dev/null
+++ b/suite/cts/deviceTests/tvproviderperf/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.tvproviderperf">
+
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
+ <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.cts.tvproviderperf"
+ android:label="TvProvider performance measurement" />
+</manifest>
diff --git a/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java b/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
new file mode 100644
index 0000000..f43beb5
--- /dev/null
+++ b/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.tvproviderperf;
+
+import android.content.ComponentName;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.OperationApplicationException;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.cts.util.CtsAndroidTestCase;
+import android.media.tv.TvContract;
+import android.media.tv.TvContract.Channels;
+import android.media.tv.TvContract.Programs;
+import android.net.Uri;
+import android.os.RemoteException;
+
+import com.android.cts.util.MeasureRun;
+import com.android.cts.util.MeasureTime;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+import com.android.cts.util.ReportLog;
+import com.android.cts.util.TimeoutReq;
+import com.android.cts.util.Stat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test performance of TvProvider on a device. TvProvider typically handles hundreds of
+ * thousands of records periodically, so it is desirable to have performance under a reasonable
+ * bar.
+ */
+public class TvProviderPerfTest extends CtsAndroidTestCase {
+ private ContentResolver mContentResolver;
+ private String mInputId;
+ private boolean mHasTvInputFramework;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mHasTvInputFramework = getContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LIVE_TV);
+ if (!mHasTvInputFramework) return;
+ mContentResolver = getContext().getContentResolver();
+ mInputId = TvContract.buildInputId(new ComponentName(getContext(), getClass()));
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ if (!mHasTvInputFramework) return;
+ mContentResolver.delete(Programs.CONTENT_URI, null, null);
+ mContentResolver.delete(Channels.CONTENT_URI, null, null);
+ } finally {
+ super.tearDown();
+ }
+ }
+
+ @TimeoutReq(minutes = 10)
+ public void testChannels() throws Exception {
+ if (!mHasTvInputFramework) return;
+ double[] averages = new double[3];
+
+ // Insert
+ final ArrayList<ContentProviderOperation> operations = new ArrayList<>();
+ final int TRANSACTION_SIZE = 1000;
+ final int TRANSACTION_RUNS = 100;
+ double[] applyBatchTimes = MeasureTime.measure(TRANSACTION_RUNS, new MeasureRun() {
+ @Override
+ public void run(int i) {
+ operations.clear();
+ for (int j = 0; j < TRANSACTION_SIZE; ++j) {
+ ContentValues values = new ContentValues();
+ values.put(Channels.COLUMN_INPUT_ID, mInputId);
+ values.put(Channels.COLUMN_SERVICE_TYPE,
+ Channels.SERVICE_TYPE_AUDIO_VIDEO);
+ values.put(Channels.COLUMN_TYPE, Channels.TYPE_OTHER);
+ operations.add(
+ ContentProviderOperation.newInsert(Channels.CONTENT_URI)
+ .withValues(values).build());
+ }
+ try {
+ mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+ } catch (OperationApplicationException | RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ getReportLog().printArray("Elapsed time for insert: ",
+ applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ averages[0] = Stat.getAverage(applyBatchTimes);
+
+ // Update
+ final String[] projection = { Channels._ID };
+ try (final Cursor cursor = mContentResolver.query(Channels.CONTENT_URI,
+ projection, null, null, null)) {
+ applyBatchTimes = MeasureTime.measure(TRANSACTION_RUNS, new MeasureRun() {
+ @Override
+ public void run(int i) {
+ operations.clear();
+ for (int j = 0; j < TRANSACTION_SIZE && cursor.moveToNext(); ++j) {
+ Uri channelUri = TvContract.buildChannelUri(cursor.getLong(0));
+ String number = Integer.toString(i * TRANSACTION_SIZE + j);
+ operations.add(
+ ContentProviderOperation.newUpdate(channelUri)
+ .withValue(Channels.COLUMN_DISPLAY_NUMBER, number)
+ .build());
+ }
+ try {
+ mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+ } catch (OperationApplicationException | RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ }
+ getReportLog().printArray("Elapsed time for update: ",
+ applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ averages[1] = Stat.getAverage(applyBatchTimes);
+
+ // Delete
+ applyBatchTimes = MeasureTime.measure(1, new MeasureRun() {
+ @Override
+ public void run(int i) {
+ mContentResolver.delete(TvContract.buildChannelsUriForInput(mInputId), null, null);
+ }
+ });
+ getReportLog().printArray("Elapsed time for delete: ",
+ applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ averages[2] = Stat.getAverage(applyBatchTimes);
+
+ // Query is not interesting for channels.
+ getReportLog().printArray("Average elapsed time for (insert, update, delete): ",
+ averages, ResultType.LOWER_BETTER, ResultUnit.MS);
+ }
+
+ @TimeoutReq(minutes = 15)
+ public void testPrograms() throws Exception {
+ if (!mHasTvInputFramework) return;
+ double[] averages = new double[5];
+
+ // Prepare (insert channels)
+ final ArrayList<ContentProviderOperation> operations = new ArrayList<>();
+ final int TRANSACTION_SIZE = 1000;
+ final int NUM_CHANNELS = 100;
+ final List<Uri> channelUris = new ArrayList<>();
+
+ operations.clear();
+ for (int i = 0; i < NUM_CHANNELS; ++i) {
+ ContentValues values = new ContentValues();
+ values.put(Channels.COLUMN_INPUT_ID, mInputId);
+ values.put(Channels.COLUMN_SERVICE_TYPE,
+ Channels.SERVICE_TYPE_AUDIO_VIDEO);
+ values.put(Channels.COLUMN_TYPE, Channels.TYPE_OTHER);
+ operations.add(
+ ContentProviderOperation.newInsert(Channels.CONTENT_URI)
+ .withValues(values).build());
+ }
+ try {
+ ContentProviderResult[] results =
+ mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+ for (ContentProviderResult result : results) {
+ channelUris.add(result.uri);
+ }
+ } catch (OperationApplicationException | RemoteException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Insert
+ double[] applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
+ @Override
+ public void run(int i) {
+ operations.clear();
+ Uri channelUri = channelUris.get(i);
+ long channelId = ContentUris.parseId(channelUri);
+ for (int j = 0; j < TRANSACTION_SIZE; ++j) {
+ ContentValues values = new ContentValues();
+ values.put(Programs.COLUMN_CHANNEL_ID, channelId);
+ operations.add(
+ ContentProviderOperation.newInsert(Programs.CONTENT_URI)
+ .withValues(values).build());
+ }
+ try {
+ mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+ } catch (OperationApplicationException | RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ getReportLog().printArray("Elapsed time for insert: ",
+ applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ averages[0] = Stat.getAverage(applyBatchTimes);
+
+ // Update
+ final long PROGRAM_DURATION_MS = 60 * 1000;
+ final String[] projection = { Programs._ID };
+ applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
+ @Override
+ public void run(int i) {
+ Uri channelUri = channelUris.get(i);
+ operations.clear();
+ try (final Cursor cursor = mContentResolver.query(
+ TvContract.buildProgramsUriForChannel(channelUri),
+ projection, null, null, null)) {
+ long startTimeMs = 0;
+ long endTimeMs = 0;
+ while (cursor.moveToNext()) {
+ Uri programUri = TvContract.buildProgramUri(cursor.getLong(0));
+ endTimeMs += PROGRAM_DURATION_MS;
+ operations.add(
+ ContentProviderOperation.newUpdate(programUri)
+ .withValue(Programs.COLUMN_START_TIME_UTC_MILLIS, startTimeMs)
+ .withValue(Programs.COLUMN_END_TIME_UTC_MILLIS, endTimeMs)
+ .build());
+ startTimeMs = endTimeMs;
+ }
+ }
+ try {
+ mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+ } catch (OperationApplicationException | RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ getReportLog().printArray("Elapsed time for update: ",
+ applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ averages[1] = Stat.getAverage(applyBatchTimes);
+
+ // Query
+ applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
+ @Override
+ public void run(int i) {
+ Uri channelUri = channelUris.get(i);
+ int j = 0;
+ try (final Cursor cursor = mContentResolver.query(
+ TvContract.buildProgramsUriForChannel(
+ channelUri, 0,
+ PROGRAM_DURATION_MS * TRANSACTION_SIZE / 2),
+ projection, null, null, null)) {
+ while (cursor.moveToNext()) {
+ ++j;
+ }
+ }
+ }
+ });
+ getReportLog().printArray("Elapsed time for query: ",
+ applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ averages[2] = Stat.getAverage(applyBatchTimes);
+
+ // Delete programs
+ applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
+ @Override
+ public void run(int i) {
+ Uri channelUri = channelUris.get(i);
+ mContentResolver.delete(
+ TvContract.buildProgramsUriForChannel(
+ channelUri,
+ PROGRAM_DURATION_MS * TRANSACTION_SIZE / 2,
+ PROGRAM_DURATION_MS * TRANSACTION_SIZE),
+ null, null);
+ }
+ });
+ getReportLog().printArray("Elapsed time for delete programs: ",
+ applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ averages[3] = Stat.getAverage(applyBatchTimes);
+
+ // Delete channels
+ applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
+ @Override
+ public void run(int i) {
+ Uri channelUri = channelUris.get(i);
+ mContentResolver.delete(channelUri, null, null);
+ }
+ });
+ getReportLog().printArray("Elapsed time for delete channels: ",
+ applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ averages[4] = Stat.getAverage(applyBatchTimes);
+
+ getReportLog().printArray("Average elapsed time for (insert, update, query, "
+ + "delete channels, delete programs): ",
+ averages, ResultType.LOWER_BETTER, ResultUnit.MS);
+ }
+}
diff --git a/suite/cts/deviceTests/videoperf/Android.mk b/suite/cts/deviceTests/videoperf/Android.mk
index cb398a9..cd82dde 100644
--- a/suite/cts/deviceTests/videoperf/Android.mk
+++ b/suite/cts/deviceTests/videoperf/Android.mk
@@ -24,7 +24,7 @@
LOCAL_PACKAGE_NAME := CtsDeviceVideoPerf
-LOCAL_SDK_VERSION := 16
+LOCAL_SDK_VERSION := current
include $(BUILD_CTS_PACKAGE)
diff --git a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
index b9edfa4..b7d1d27 100644
--- a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
+++ b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
@@ -19,7 +19,9 @@
import android.media.MediaCodecInfo;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecInfo.CodecProfileLevel;
+import android.media.MediaCodecInfo.VideoCapabilities;
import android.media.MediaCodecList;
+import android.media.MediaFormat;
import android.util.Log;
@@ -38,21 +40,33 @@
public boolean mSupportPlanar = false;
private static final String TAG = "CodecInfo";
- private static final String VIDEO_AVC = "video/avc";
+ private static final String VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
/**
* Check if given codec with given (w,h) is supported.
- * @param mimeType codec type in mime format like "video/avc"
+ * @param mimeType codec type in mime format like MediaFormat.MIMETYPE_VIDEO_AVC
* @param w video width
* @param h video height
* @param isEncoder whether the codec is encoder or decoder
* @return null if the configuration is not supported.
*/
- public static CodecInfo getSupportedFormatInfo(String mimeType, int w, int h,
- boolean isEncoder) {
- CodecCapabilities cap = getCodecCapability(mimeType, isEncoder);
- if (cap == null) { // not supported
+ public static CodecInfo getSupportedFormatInfo(
+ String mimeType, int w, int h, boolean isEncoder) {
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ MediaFormat format = MediaFormat.createVideoFormat(mimeType, w, h);
+ String codec = isEncoder
+ ? mcl.findEncoderForFormat(format)
+ : mcl.findDecoderForFormat(format);
+ if (codec == null) { // not supported
return null;
}
+ CodecCapabilities cap = null;
+ for (MediaCodecInfo info : mcl.getCodecInfos()) {
+ if (info.getName().equals(codec)) {
+ cap = info.getCapabilitiesForType(mimeType);
+ break;
+ }
+ }
+ VideoCapabilities vidCap = cap.getVideoCapabilities();
CodecInfo info = new CodecInfo();
for (int color : cap.colorFormats) {
if (color == CodecCapabilities.COLOR_FormatYUV420SemiPlanar) {
@@ -70,129 +84,13 @@
}
if (mimeType.equals(VIDEO_AVC)) {
- int highestLevel = 0;
- for (CodecProfileLevel lvl : cap.profileLevels) {
- if (lvl.level > highestLevel) {
- highestLevel = lvl.level;
- }
- }
- Log.i(TAG, "Avc highest level " + Integer.toHexString(highestLevel));
- int maxW = 0;
- int maxH = 0;
- int bitRate = 0;
- int mbW = (w + 15) / 16; // size in macroblocks
- int mbH = (h + 15) / 16;
- int maxMacroblocksPerSecond = 0; // max decoding speed
- 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 null;
- case CodecProfileLevel.AVCLevel21:
- maxW = 352;
- maxH = 576;
- bitRate = 4000000;
- maxMacroblocksPerSecond = 19800;
- break;
- case CodecProfileLevel.AVCLevel22:
- maxW = 720;
- maxH = 480;
- bitRate = 4000000;
- maxMacroblocksPerSecond = 20250;
- break;
- case CodecProfileLevel.AVCLevel3:
- maxW = 720;
- maxH = 480;
- bitRate = 10000000;
- maxMacroblocksPerSecond = 40500;
- break;
- case CodecProfileLevel.AVCLevel31:
- maxW = 1280;
- maxH = 720;
- bitRate = 14000000;
- maxMacroblocksPerSecond = 108000;
- break;
- case CodecProfileLevel.AVCLevel32:
- maxW = 1280;
- maxH = 720;
- bitRate = 20000000;
- maxMacroblocksPerSecond = 216000;
- break;
- case CodecProfileLevel.AVCLevel4:
- maxW = 1920;
- maxH = 1080;
- bitRate = 20000000;
- maxMacroblocksPerSecond = 245760;
- break;
- case CodecProfileLevel.AVCLevel41:
- maxW = 1920;
- maxH = 1080;
- bitRate = 50000000;
- maxMacroblocksPerSecond = 245760;
- break;
- case CodecProfileLevel.AVCLevel42:
- maxW = 2048;
- maxH = 1080;
- bitRate = 50000000;
- maxMacroblocksPerSecond = 522240;
- break;
- case CodecProfileLevel.AVCLevel5:
- maxW = 3672;
- maxH = 1536;
- bitRate = 135000000;
- maxMacroblocksPerSecond = 589824;
- break;
- case CodecProfileLevel.AVCLevel51:
- default:
- maxW = 4096;
- maxH = 2304;
- bitRate = 240000000;
- maxMacroblocksPerSecond = 983040;
- break;
- }
- if ((w > maxW) || (h > maxH)) {
- Log.i(TAG, "Requested resolution (" + w + "," + h + ") exceeds (" +
- maxW + "," + maxH + ")");
- return null;
- }
- info.mFps = maxMacroblocksPerSecond / mbH / mbW;
- info.mBitRate = bitRate;
- Log.i(TAG, "AVC Level " + Integer.toHexString(highestLevel) + " bit rate " + bitRate +
- " fps " + info.mFps);
+ info.mFps = vidCap.getSupportedFrameRatesFor(w, h).getUpper().intValue();
+ info.mBitRate = vidCap.getBitrateRange().getUpper();
+ Log.i(TAG, "AVC bit rate " + info.mBitRate + " fps " + info.mFps);
}
return info;
}
- /**
- * Search for given codecName and returns CodecCapabilities if found
- * @param codecName
- * @param isEncoder true for encoder, false for decoder
- * @return null if the codec is not supported
- */
- private static CodecCapabilities getCodecCapability(
- String codecName, boolean isEncoder) {
- int codecCount = MediaCodecList.getCodecCount();
- for (int i = 0; i < codecCount; ++i) {
- MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
- String[] types = info.getSupportedTypes();
- if (isEncoder != info.isEncoder()) {
- continue;
- }
- for (int j = 0; j < types.length; ++j) {
- if (types[j].compareTo(codecName) == 0) {
- CodecCapabilities cap = info.getCapabilitiesForType(types[j]);
- Log.i(TAG, "Use codec " + info.getName());
- return cap;
- }
- }
- }
- return null;
- }
-
// for debugging
private static void printIntArray(String msg, int[] data) {
StringBuilder builder = new StringBuilder();
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 a009ce2..aacb7a5 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
@@ -18,6 +18,7 @@
import android.graphics.Point;
import android.media.MediaCodec;
+import android.media.MediaCodecList;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaFormat;
import android.util.Log;
@@ -27,6 +28,7 @@
import com.android.cts.util.ResultUnit;
import com.android.cts.util.Stat;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.lang.System;
import java.util.Random;
@@ -49,7 +51,7 @@
// is not very high.
private static final long VIDEO_CODEC_WAIT_TIME_US = 5000;
private static final boolean VERBOSE = false;
- private static final String VIDEO_AVC = "video/avc";
+ private static final String VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
private static final int TOTAL_FRAMES = 300;
private static final int NUMBER_OF_REPEAT = 10;
// i frame interval for encoder
@@ -130,12 +132,12 @@
* @param numberRepeat how many times to repeat the encoding / decoding process
*/
private void doTest(String mimeType, int w, int h, int numberRepeat) throws Exception {
- CodecInfo infoEnc = CodecInfo.getSupportedFormatInfo(mimeType, w, h, true);
+ CodecInfo infoEnc = CodecInfo.getSupportedFormatInfo(mimeType, w, h, true /* encoder */);
if (infoEnc == null) {
- Log.i(TAG, "Codec " + mimeType + "with " + w + "," + h + " not supported");
+ Log.i(TAG, "Encoder " + mimeType + " with " + w + "," + h + " not supported");
return;
}
- CodecInfo infoDec = CodecInfo.getSupportedFormatInfo(mimeType, w, h, false);
+ CodecInfo infoDec = CodecInfo.getSupportedFormatInfo(mimeType, w, h, false /* encoder */);
assertNotNull(infoDec);
mVideoWidth = w;
mVideoHeight = h;
@@ -207,8 +209,11 @@
* @return time taken in ms to encode the frames. This does not include initialization time.
*/
private double runEncoder(String mimeType, MediaFormat format, int totalFrames) {
- MediaCodec codec = MediaCodec.createEncoderByType(mimeType);
+ MediaCodec codec = null;
try {
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ String encoderName = mcl.findEncoderForFormat(format);
+ codec = MediaCodec.createByCodecName(encoderName);
codec.configure(
format,
null /* surface */,
@@ -216,7 +221,11 @@
MediaCodec.CONFIGURE_FLAG_ENCODE);
} catch (IllegalStateException e) {
Log.e(TAG, "codec '" + mimeType + "' failed configuration.");
+ codec.release();
assertTrue("codec '" + mimeType + "' failed configuration.", false);
+ } catch (IOException | NullPointerException e) {
+ Log.i(TAG, "could not find codec for " + format);
+ return Double.NaN;
}
codec.start();
ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
@@ -347,7 +356,15 @@
* @return returns length-2 array with 0: time for decoding, 1 : rms error of pixels
*/
private double[] runDecoder(String mimeType, MediaFormat format) {
- MediaCodec codec = MediaCodec.createDecoderByType(mimeType);
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ String decoderName = mcl.findDecoderForFormat(format);
+ MediaCodec codec = null;
+ try {
+ codec = MediaCodec.createByCodecName(decoderName);
+ } catch (IOException | NullPointerException e) {
+ Log.i(TAG, "could not find codec for " + format);
+ return null;
+ }
codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
codec.start();
ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index dd8660f..924a0ce 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -93,13 +93,6 @@
bug: 17530117
},
{
- description: "this test removes the stay-awake option, causing the screen to turn off during the execution of subsequent tests",
- names: [
- "android.admin.cts.DevicePolicyManagerTest#testMaximumTimeToLock"
- ],
- bug: 18002490
-},
-{
description: "these tests locks the screen with an emtpy password or swipe-to-unlock, blocking subsequent test to dismiss keyguard",
names: [
"android.admin.cts.DevicePolicyManagerTest#testPasswordQuality_something",
@@ -142,7 +135,8 @@
"com.android.cts.devicepolicy.ManagedProfileTest#testWipeData",
"com.android.cts.devicepolicy.ManagedProfileTest#testCrossProfileIntentFilters",
"com.android.cts.devicepolicy.ManagedProfileTest#testCrossProfileContent",
- "com.android.cts.devicepolicy.ManagedProfileTest#testNoDebuggingFeaturesRestriction"
+ "com.android.cts.devicepolicy.ManagedProfileTest#testNoDebuggingFeaturesRestriction",
+ "com.android.cts.devicepolicy.ManagedProfileTest#testCrossProfileCopyPaste"
]
},
{
@@ -335,10 +329,7 @@
"android.hardware.cts.SingleSensorTests#testLinearAcceleration_10hz",
"android.hardware.cts.SingleSensorTests#testLinearAcceleration_5hz",
"android.hardware.cts.SingleSensorTests#testLinearAcceleration_1hz",
- "android.hardware.cts.SensorTest#testValuesForAllSensors",
- "android.hardware.cts.SensorTest#testSensorTimeStamps",
- "android.hardware.cts.SensorTest#testBatchAndFlush",
- "android.hardware.cts.SensorTest#testBatchAndFlushWithHandler"
+ "android.hardware.cts.SensorTest#testSensorTimeStamps"
],
bug: 17675466
},
diff --git a/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index d0255f3..04060e5 100644
--- a/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -486,24 +486,6 @@
}
}
- public void testMaximumTimeToLock() {
- if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testMaximumTimeToLock");
- return;
- }
- long originalValue = mDevicePolicyManager.getMaximumTimeToLock(mComponent);
- try {
- for (long testLength : new long[] {
- 5000L /* 5 sec */, 60000L /* 1 min */, 1800000 /* 30 min */}) {
- mDevicePolicyManager.setMaximumTimeToLock(mComponent, testLength);
- assertEquals(testLength,
- mDevicePolicyManager.getMaximumTimeToLock(mComponent));
- }
- } finally {
- mDevicePolicyManager.setMaximumTimeToLock(mComponent, originalValue);
- }
- }
-
public void testCreateUser_failIfNotDeviceOwner() {
if (!mDeviceAdmin) {
Log.w(TAG, "Skipping testCreateUser_failIfNotDeviceOwner");
diff --git a/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java b/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
index 35a0b4c..306428f 100644
--- a/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
+++ b/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
@@ -16,8 +16,11 @@
package android.animation.cts;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
@@ -25,6 +28,7 @@
import android.test.ActivityInstrumentationTestCase2;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
+import android.view.animation.LinearInterpolator;
public class AnimatorSetTest extends
ActivityInstrumentationTestCase2<AnimationActivity> {
@@ -34,6 +38,7 @@
private Object object;
private ObjectAnimator yAnimator;
private ObjectAnimator xAnimator;
+ Set<Integer> identityHashes = new HashSet<Integer>();
public AnimatorSetTest() {
super(AnimationActivity.class);
@@ -158,4 +163,79 @@
}
});
}
+
+ private void assertUnique(Object object) {
+ assertUnique(object, "");
+ }
+
+ private void assertUnique(Object object, String msg) {
+ final int code = System.identityHashCode(object);
+ assertTrue("object should be unique " + msg + ", obj:" + object, identityHashes.add(code));
+
+ }
+
+ public void testClone() {
+ AnimatorSet set1 = new AnimatorSet();
+ final AnimatorListenerAdapter setListener = new AnimatorListenerAdapter() {};
+ set1.addListener(setListener);
+ ObjectAnimator animator1 = new ObjectAnimator();
+ animator1.setDuration(100);
+ animator1.setPropertyName("x");
+ animator1.setIntValues(5);
+ animator1.setInterpolator(new LinearInterpolator());
+ AnimatorListenerAdapter listener1 = new AnimatorListenerAdapter(){};
+ AnimatorListenerAdapter listener2 = new AnimatorListenerAdapter(){};
+ animator1.addListener(listener1);
+
+ ObjectAnimator animator2 = new ObjectAnimator();
+ animator2.setDuration(100);
+ animator2.setInterpolator(new LinearInterpolator());
+ animator2.addListener(listener2);
+ animator2.setPropertyName("y");
+ animator2.setIntValues(10);
+
+ set1.playTogether(animator1, animator2);
+
+ AnimateObject target = new AnimateObject();
+ set1.setTarget(target);
+ set1.start();
+ assertTrue(set1.isStarted());
+
+ animator1.getListeners();
+ AnimatorSet set2 = set1.clone();
+ assertFalse(set2.isStarted());
+
+ assertUnique(set1);
+ assertUnique(animator1);
+ assertUnique(animator2);
+
+ assertUnique(set2);
+ assertEquals(2, set2.getChildAnimations().size());
+
+ Animator clone1 = set2.getChildAnimations().get(0);
+ Animator clone2 = set2.getChildAnimations().get(1);
+
+ for (Animator animator : set2.getChildAnimations()) {
+ assertUnique(animator);
+ }
+
+ assertTrue(clone1.getListeners().contains(listener1));
+ assertTrue(clone2.getListeners().contains(listener2));
+
+ assertTrue(set2.getListeners().contains(setListener));
+
+ for (Animator.AnimatorListener listener : set1.getListeners()) {
+ assertTrue(set2.getListeners().contains(listener));
+ }
+
+ assertEquals(animator1.getDuration(), clone1.getDuration());
+ assertEquals(animator2.getDuration(), clone2.getDuration());
+ assertSame(animator1.getInterpolator(), clone1.getInterpolator());
+ assertSame(animator2.getInterpolator(), clone2.getInterpolator());
+ }
+
+ class AnimateObject {
+ int x = 1;
+ int y = 2;
+ }
}
diff --git a/tests/tests/animation/src/android/animation/cts/AnimatorTest.java b/tests/tests/animation/src/android/animation/cts/AnimatorTest.java
index fac9ff9..a08a5eb 100644
--- a/tests/tests/animation/src/android/animation/cts/AnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/AnimatorTest.java
@@ -182,6 +182,27 @@
assertNull(listListenersTwo);
}
+ public void testNullObjectAnimator() throws Throwable {
+ Object object = mActivity.view.newBall;
+ final ObjectAnimator animator = ObjectAnimator.ofFloat(object, "y", 0, 100);
+ MyListener listener = new MyListener();
+ animator.addListener(listener);
+ mActivity.view.newBall.setY(0);
+ startAnimation(animator);
+ int sleepCount = 0;
+ while (mActivity.view.newBall.getY() == 0 && sleepCount++ < 50) {
+ Thread.sleep(1);
+ }
+ assertNotSame(0, mActivity.view.newBall.getY());
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ animator.setTarget(null);
+ }
+ });
+ assertTrue(listener.mCancel);
+ }
+
class MyListener implements Animator.AnimatorListener{
boolean mStart = false;
boolean mEnd = false;
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 5b1909a..d3890df 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -132,11 +132,12 @@
Activities.ActivityThree.class,
};
+ final long startTime = System.currentTimeMillis() - MINUTE;
+
// Launch the series of Activities.
launchSubActivities(activitySequence);
final long endTime = System.currentTimeMillis();
- final long startTime = endTime - DAY;
UsageEvents events = mUsageStatsManager.queryEvents(startTime, endTime);
// Consume all the events.
@@ -147,15 +148,26 @@
eventList.add(event);
}
+ // Find the last Activity's MOVE_TO_FOREGROUND event.
+ int end = eventList.size();
+ while (end > 0) {
+ UsageEvents.Event event = eventList.get(end - 1);
+ if (event.getClassName().equals(activitySequence[activitySequence.length - 1].getName())
+ && event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
+ break;
+ }
+ end--;
+ }
+
// We expect 2 events per Activity launched (foreground + background)
// except for the last Activity, which was in the foreground when
// we queried the event log.
- assertTrue(eventList.size() >= (activitySequence.length * 2) - 1);
- final int offset = eventList.size() - ((activitySequence.length * 2) - 1);
+ final int start = end - ((activitySequence.length * 2) - 1);
+ assertTrue("Not enough events", start >= 0);
final int activityCount = activitySequence.length;
for (int i = 0; i < activityCount; i++) {
- int index = offset + (i * 2);
+ final int index = start + (i * 2);
// Check for foreground event.
UsageEvents.Event event = eventList.get(index);
@@ -163,10 +175,10 @@
assertEquals(activitySequence[i].getName(), event.getClassName());
assertEquals(UsageEvents.Event.MOVE_TO_FOREGROUND, event.getEventType());
- index += 1;
+ // Only check for the background event if this is not the
+ // last activity.
if (i < activityCount - 1) {
- // Check for background event.
- event = eventList.get(index);
+ event = eventList.get(index + 1);
assertEquals(mTargetPackage, event.getPackageName());
assertEquals(activitySequence[i].getName(), event.getClassName());
assertEquals(UsageEvents.Event.MOVE_TO_BACKGROUND, event.getEventType());
@@ -182,6 +194,7 @@
@Ignore
public void ignore_testStatsAreShiftedInTimeWhenSystemTimeChanges() throws Exception {
launchSubActivity(Activities.ActivityOne.class);
+ launchSubActivity(Activities.ActivityThree.class);
long endTime = System.currentTimeMillis();
long startTime = endTime - MINUTE;
@@ -214,18 +227,19 @@
}
public void testUsageEventsParceling() throws Exception {
- final long startTime = System.currentTimeMillis();
+ final long startTime = System.currentTimeMillis() - MINUTE;
+ // Ensure some data is in the UsageStats log.
@SuppressWarnings("unchecked")
Class<? extends Activity>[] activityClasses = new Class[] {
+ Activities.ActivityTwo.class,
Activities.ActivityOne.class,
Activities.ActivityThree.class,
- Activities.ActivityTwo.class,
};
launchSubActivities(activityClasses);
final long endTime = System.currentTimeMillis();
- UsageEvents events = mUsageStatsManager.queryEvents(startTime - TIME_DIFF_THRESHOLD, endTime);
+ UsageEvents events = mUsageStatsManager.queryEvents(startTime, endTime);
assertTrue(events.getNextEvent(new UsageEvents.Event()));
Parcel p = Parcel.obtain();
@@ -255,6 +269,7 @@
// Launch an Activity.
launchSubActivity(Activities.ActivityFour.class);
+ launchSubActivity(Activities.ActivityThree.class);
final long endTime = System.currentTimeMillis();
@@ -287,10 +302,12 @@
}
public void testNoAccessSilentlyFails() throws Exception {
+ final long startTime = System.currentTimeMillis() - MINUTE;
+
launchSubActivity(Activities.ActivityOne.class);
+ launchSubActivity(Activities.ActivityThree.class);
final long endTime = System.currentTimeMillis();
- final long startTime = endTime - MINUTE;
List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST,
startTime, endTime);
assertFalse(stats.isEmpty());
diff --git a/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
index 620c51f..495501f 100644
--- a/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -141,6 +141,8 @@
boolean manualSensor = false;
boolean manualPostProcessing = false;
boolean raw = false;
+ boolean readSensorSettings = false;
+ boolean burstCapture = false;
CameraCharacteristics[] cameraChars = new CameraCharacteristics[cameraIds.length];
for (String cameraId : cameraIds) {
CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(cameraId);
@@ -160,8 +162,14 @@
case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW:
raw = true;
break;
+ case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS:
+ readSensorSettings = true;
+ break;
+ case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE:
+ burstCapture = true;
+ break;
default:
- // Capabilities don't have a matching system feature
+ // Capabilities that don't have a matching system feature
break;
}
}
@@ -171,6 +179,8 @@
assertFeature(manualPostProcessing,
PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING);
assertFeature(raw, PackageManager.FEATURE_CAMERA_CAPABILITY_RAW);
+ assertFeature(readSensorSettings, PackageManager.FEATURE_CAMERA_CAPABILITY_READ_SENSOR_SETTINGS);
+ assertFeature(burstCapture, PackageManager.FEATURE_CAMERA_CAPABILITY_BURST_CAPTURE);
}
private void checkFrontCamera() {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimationDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimationDrawableTest.java
index c278ed2..46f74dc 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimationDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimationDrawableTest.java
@@ -277,68 +277,82 @@
assertStoppedAnimation(THIRD_FRAME_INDEX, THIRD_FRAME_DURATION);
}
- public void testInflate() throws XmlPullParserException, IOException {
- mAnimationDrawable = new AnimationDrawable();
- DrawableContainerState drawableContainerState =
- (DrawableContainerState) mAnimationDrawable.getConstantState();
-
+ public void testInflateCorrect() throws XmlPullParserException, IOException {
XmlResourceParser parser = getResourceParser(R.xml.anim_list_correct);
- mAnimationDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
+ AnimationDrawable dr = new AnimationDrawable();
+ dr.inflate(mResources, parser, Xml.asAttributeSet(parser));
// android:visible="false"
- assertFalse(mAnimationDrawable.isVisible());
+ assertFalse(dr.isVisible());
// android:oneShot="true"
- assertTrue(mAnimationDrawable.isOneShot());
+ assertTrue(dr.isOneShot());
// android:variablePadding="true"
- assertNull(drawableContainerState.getConstantPadding());
- assertEquals(2, mAnimationDrawable.getNumberOfFrames());
- assertEquals(2000, mAnimationDrawable.getDuration(0));
- assertEquals(1000, mAnimationDrawable.getDuration(1));
- assertSame(mAnimationDrawable.getFrame(0), mAnimationDrawable.getCurrent());
+ DrawableContainerState state =
+ (DrawableContainerState) dr.getConstantState();
+ assertNull(state.getConstantPadding());
+ assertEquals(2, dr.getNumberOfFrames());
+ assertEquals(2000, dr.getDuration(0));
+ assertEquals(1000, dr.getDuration(1));
+ assertSame(dr.getFrame(0), dr.getCurrent());
+ }
- parser = getResourceParser(R.xml.anim_list_missing_list_attrs);
- mAnimationDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
- // use current the visibility
- assertFalse(mAnimationDrawable.isVisible());
+ public void testInflateMissingAttributes() throws XmlPullParserException, IOException {
+ XmlResourceParser parser = getResourceParser(R.xml.anim_list_missing_list_attrs);
+ AnimationDrawable dr = new AnimationDrawable();
+ dr.inflate(mResources, parser, Xml.asAttributeSet(parser));
+ // use default visibility
+ assertTrue(dr.isVisible());
// default value of android:oneShot is false
- assertFalse(mAnimationDrawable.isOneShot());
+ assertFalse(dr.isOneShot());
// default value of android:variablePadding is false
// TODO: its not clear what the value of constant padding should be when variablePadding
// is false
//assertNotNull(drawableContainerState.getConstantPadding());
// add a new frame from xml
- assertEquals(3, mAnimationDrawable.getNumberOfFrames());
- assertEquals(2000, mAnimationDrawable.getDuration(0));
- assertEquals(1000, mAnimationDrawable.getDuration(1));
- assertEquals(2000, mAnimationDrawable.getDuration(2));
- assertSame(mAnimationDrawable.getFrame(0), mAnimationDrawable.getCurrent());
+ assertEquals(3, dr.getNumberOfFrames());
+ assertEquals(2000, dr.getDuration(0));
+ assertEquals(1000, dr.getDuration(1));
+ assertEquals(2000, dr.getDuration(2));
+ assertSame(dr.getFrame(0), dr.getCurrent());
+ }
- parser = getResourceParser(R.xml.anim_list_missing_item_drawable);
+ public void testInflateMissingDrawable() throws XmlPullParserException, IOException {
+ XmlResourceParser parser = getResourceParser(R.xml.anim_list_missing_item_drawable);
+ AnimationDrawable dr = new AnimationDrawable();
try {
- mAnimationDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
+ dr.inflate(mResources, parser, Xml.asAttributeSet(parser));
fail("Should throw XmlPullParserException if drawable of item is missing");
} catch (XmlPullParserException e) {
// expected
}
}
- public void testInflateWithNullParameters() throws XmlPullParserException, IOException {
+ public void testInflateNullResources() throws XmlPullParserException, IOException {
XmlResourceParser parser = getResourceParser(R.drawable.animationdrawable);
+ AnimationDrawable dr = new AnimationDrawable();
try {
- mAnimationDrawable.inflate(null, parser, Xml.asAttributeSet(parser));
+ dr.inflate(null, parser, Xml.asAttributeSet(parser));
fail("Should throw NullPointerException if resource is null");
} catch (NullPointerException e) {
// expected
}
+ }
+ public void testInflateNullXmlPullParser() throws XmlPullParserException, IOException {
+ XmlResourceParser parser = getResourceParser(R.drawable.animationdrawable);
+ AnimationDrawable dr = new AnimationDrawable();
try {
- mAnimationDrawable.inflate(mResources, null, Xml.asAttributeSet(parser));
+ dr.inflate(mResources, null, Xml.asAttributeSet(parser));
fail("Should throw NullPointerException if parser is null");
} catch (NullPointerException e) {
// expected
}
+ }
+ public void testInflateNullAttributeSet() throws XmlPullParserException, IOException {
+ XmlResourceParser parser = getResourceParser(R.drawable.animationdrawable);
+ AnimationDrawable dr = new AnimationDrawable();
try {
- mAnimationDrawable.inflate(mResources, parser, null);
+ dr.inflate(mResources, parser, null);
fail("Should throw NullPointerException if AttributeSet is null");
} catch (NullPointerException e) {
// expected
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
index 190fffa..6281582 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
@@ -413,8 +413,8 @@
attrs = DrawableTestUtils.getAttributeSet(parser, "scale_nodrawable");
try {
scaleDrawable.inflate(res, parser, attrs);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
+ fail("Should throw XmlPullParserException");
+ } catch (XmlPullParserException e) {
}
try {
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
index 192fb85..32a6880 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -41,7 +41,9 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
/**
* <p>Basic test for CameraManager class.</p>
@@ -485,7 +487,127 @@
mCameraManager.registerAvailabilityCallback(mListener, mHandler);
mCameraManager.unregisterAvailabilityCallback(mListener);
mCameraManager.unregisterAvailabilityCallback(mListener);
-
- // TODO: test the listener callbacks
}
+
+ /**
+ * Test that the availability callbacks fire when expected
+ */
+ public void testCameraManagerListenerCallbacks() throws Exception {
+ final int AVAILABILITY_TIMEOUT_MS = 10;
+
+ final LinkedBlockingQueue<String> availableEventQueue = new LinkedBlockingQueue<>();
+ final LinkedBlockingQueue<String> unavailableEventQueue = new LinkedBlockingQueue<>();
+
+ CameraManager.AvailabilityCallback ac = new CameraManager.AvailabilityCallback() {
+ @Override
+ public void onCameraAvailable(String cameraId) {
+ availableEventQueue.offer(cameraId);
+ }
+
+ @Override
+ public void onCameraUnavailable(String cameraId) {
+ unavailableEventQueue.offer(cameraId);
+ }
+ };
+
+ mCameraManager.registerAvailabilityCallback(ac, mHandler);
+ String[] cameras = mCameraManager.getCameraIdList();
+
+ // Verify we received available for all cameras' initial state in a reasonable amount of time
+ HashSet<String> expectedAvailableCameras = new HashSet<String>(Arrays.asList(cameras));
+ while (expectedAvailableCameras.size() > 0) {
+ String id = availableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+ java.util.concurrent.TimeUnit.MILLISECONDS);
+ assertTrue("Did not receive initial availability notices for some cameras",
+ id != null);
+ expectedAvailableCameras.remove(id);
+ }
+ // Verify no unavailable cameras were reported
+ assertTrue("Some camera devices are initially unavailable",
+ unavailableEventQueue.size() == 0);
+
+ // Verify transitions for individual cameras
+ for (String id : cameras) {
+ MockStateCallback mockListener = MockStateCallback.mock();
+ mCameraListener = new BlockingStateCallback(mockListener);
+
+ mCameraManager.openCamera(id, mCameraListener, mHandler);
+
+ // Block until opened
+ mCameraListener.waitForState(BlockingStateCallback.STATE_OPENED,
+ CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+ // Then verify only open happened, and get the camera handle
+ CameraDevice camera = verifyCameraStateOpened(id, mockListener);
+
+ // Verify that we see the expected 'unavailable' event.
+ String candidateId = unavailableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+ java.util.concurrent.TimeUnit.MILLISECONDS);
+ assertTrue(String.format("Received unavailability notice for wrong ID " +
+ "(expected %s, got %s)", id, candidateId),
+ id == candidateId);
+ assertTrue("Availability events received unexpectedly",
+ availableEventQueue.size() == 0);
+
+ // Verify that we see the expected 'available' event after closing the camera
+
+ camera.close();
+
+ mCameraListener.waitForState(BlockingStateCallback.STATE_CLOSED,
+ CameraTestUtils.CAMERA_CLOSE_TIMEOUT_MS);
+
+ candidateId = availableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+ java.util.concurrent.TimeUnit.MILLISECONDS);
+ assertTrue(String.format("Received availability notice for wrong ID " +
+ "(expected %s, got %s)", id, candidateId),
+ id == candidateId);
+ assertTrue("Unavailability events received unexpectedly",
+ unavailableEventQueue.size() == 0);
+
+ }
+
+ // Verify that we can unregister the listener and see no more events
+ assertTrue("Availability events received unexpectedly",
+ availableEventQueue.size() == 0);
+ assertTrue("Unavailability events received unexpectedly",
+ unavailableEventQueue.size() == 0);
+
+ mCameraManager.unregisterAvailabilityCallback(ac);
+
+ {
+ // Open an arbitrary camera and make sure we don't hear about it
+
+ MockStateCallback mockListener = MockStateCallback.mock();
+ mCameraListener = new BlockingStateCallback(mockListener);
+
+ mCameraManager.openCamera(cameras[0], mCameraListener, mHandler);
+
+ // Block until opened
+ mCameraListener.waitForState(BlockingStateCallback.STATE_OPENED,
+ CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+ // Then verify only open happened, and close the camera
+ CameraDevice camera = verifyCameraStateOpened(cameras[0], mockListener);
+
+ camera.close();
+
+ mCameraListener.waitForState(BlockingStateCallback.STATE_CLOSED,
+ CameraTestUtils.CAMERA_CLOSE_TIMEOUT_MS);
+
+ // No unavailability or availability callback should have occured
+ String candidateId = unavailableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+ java.util.concurrent.TimeUnit.MILLISECONDS);
+ assertTrue(String.format("Received unavailability notice for ID %s unexpectedly ",
+ candidateId),
+ candidateId == null);
+
+ candidateId = availableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+ java.util.concurrent.TimeUnit.MILLISECONDS);
+ assertTrue(String.format("Received availability notice for ID %s unexpectedly ",
+ candidateId),
+ candidateId == null);
+
+
+ }
+
+ } // testCameraManagerListenerCallbacks
+
}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
index 0c36832..303099a 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -63,6 +63,7 @@
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
/**
* A package private utility class for wrapping up the camera2 cts test common utility functions
@@ -199,6 +200,7 @@
public static class SimpleCaptureCallback extends CameraCaptureSession.CaptureCallback {
private final LinkedBlockingQueue<CaptureResult> mQueue =
new LinkedBlockingQueue<CaptureResult>();
+ private AtomicLong mNumFramesArrived = new AtomicLong(0);
@Override
public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
@@ -210,6 +212,7 @@
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {
try {
+ mNumFramesArrived.incrementAndGet();
mQueue.put(result);
} catch (InterruptedException e) {
throw new UnsupportedOperationException(
@@ -227,6 +230,10 @@
long frameNumber) {
}
+ public long getTotalNumFrames() {
+ return mNumFramesArrived.get();
+ }
+
public CaptureResult getCaptureResult(long timeout) {
try {
CaptureResult result = mQueue.poll(timeout, TimeUnit.MILLISECONDS);
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 ec2f95b..03a6f76 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -282,11 +282,6 @@
try {
openDevice(mCameraIds[i]);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
-
Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
// Update preview surface with given size for all sub-tests.
@@ -351,11 +346,6 @@
try {
openDevice(mCameraIds[i]);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
-
faceDetectionTestByCamera();
} finally {
closeDevice();
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 1a00d9e..31460bd 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -28,6 +28,7 @@
import android.test.AndroidTestCase;
import android.util.Log;
import android.util.Rational;
+import android.util.Range;
import android.util.Size;
import java.util.ArrayList;
@@ -267,7 +268,8 @@
int counter = 0;
for (CameraCharacteristics c : mCharacteristics) {
int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
- assertNotNull("android.request.availableCapabilities must never be null");
+ assertNotNull("android.request.availableCapabilities must never be null",
+ actualCapabilities);
if (!arrayContains(actualCapabilities,
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
Log.i(TAG, "RAW capability is not supported in camera " + counter++ +
@@ -339,6 +341,100 @@
}
/**
+ * Test values for static metadata used by the BURST capability.
+ */
+ public void testStaticBurstCharacteristics() {
+ int counter = 0;
+ for (CameraCharacteristics c : mCharacteristics) {
+ int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+ assertNotNull("android.request.availableCapabilities must never be null",
+ actualCapabilities);
+
+ // Check if the burst capability is defined
+ boolean haveBurstCapability = arrayContains(actualCapabilities,
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
+
+ StreamConfigurationMap config =
+ c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ assertNotNull(String.format("No stream configuration map found for: ID %s",
+ mIds[counter]), config);
+
+ // Ensure that max YUV size matches max JPEG size
+ Size maxYuvSize = CameraTestUtils.getMaxSize(
+ config.getOutputSizes(ImageFormat.YUV_420_888));
+ Size maxJpegSize = CameraTestUtils.getMaxSize(config.getOutputSizes(ImageFormat.JPEG));
+
+ boolean haveMaxYuv = maxYuvSize != null ?
+ (maxJpegSize.getWidth() <= maxYuvSize.getWidth() &&
+ maxJpegSize.getHeight() <= maxYuvSize.getHeight()) : false;
+
+ // Ensure that YUV output is fast enough - needs to be at least 20 fps
+
+ long maxYuvRate =
+ config.getOutputMinFrameDuration(ImageFormat.YUV_420_888, maxYuvSize);
+ final long MIN_DURATION_BOUND_NS = 50000000; // 50 ms, 20 fps
+
+ boolean haveMaxYuvRate = maxYuvRate <= MIN_DURATION_BOUND_NS;
+
+ // Ensure that there's an FPS range that's fast enough to capture at above
+ // minFrameDuration, for full-auto bursts
+ Range[] fpsRanges = c.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
+ float minYuvFps = 1.f / maxYuvRate;
+
+ boolean haveFastAeTargetFps = false;
+ for (Range<Integer> r : fpsRanges) {
+ if (r.getLower() >= minYuvFps) {
+ haveFastAeTargetFps = true;
+ break;
+ }
+ }
+
+ // Ensure that maximum sync latency is small enough for fast setting changes, even if
+ // it's not quite per-frame
+
+ Integer maxSyncLatencyValue = c.get(CameraCharacteristics.SYNC_MAX_LATENCY);
+ assertNotNull(String.format("No sync latency declared for ID %s", mIds[counter]),
+ maxSyncLatencyValue);
+
+ int maxSyncLatency = maxSyncLatencyValue;
+ final long MAX_LATENCY_BOUND = 4;
+ boolean haveFastSyncLatency =
+ (maxSyncLatency <= MAX_LATENCY_BOUND) && (maxSyncLatency >= 0);
+
+ if (haveBurstCapability) {
+ assertTrue(
+ String.format("BURST-capable camera device %s does not have maximum YUV " +
+ "size that is at least max JPEG size",
+ mIds[counter]),
+ haveMaxYuv);
+ assertTrue(
+ String.format("BURST-capable camera device %s YUV frame rate is too slow" +
+ "(%d ns min frame duration reported, less than %d ns expected)",
+ mIds[counter], maxYuvRate, MIN_DURATION_BOUND_NS),
+ haveMaxYuvRate);
+ assertTrue(
+ String.format("BURST-capable camera device %s does not list an AE target " +
+ " FPS range with min FPS >= %f, for full-AUTO bursts",
+ mIds[counter], minYuvFps),
+ haveFastAeTargetFps);
+ assertTrue(
+ String.format("BURST-capable camera device %s YUV sync latency is too long" +
+ "(%d frames reported, [0, %d] frames expected)",
+ mIds[counter], maxSyncLatency, MAX_LATENCY_BOUND),
+ haveFastSyncLatency);
+ } else {
+ assertTrue(
+ String.format("Camera device %s has all the requirements for BURST" +
+ " capability but does not report it!", mIds[counter]),
+ !(haveMaxYuv && haveMaxYuvRate &&
+ haveFastAeTargetFps && haveFastSyncLatency));
+ }
+
+ counter++;
+ }
+ }
+
+ /**
* Check key is present in characteristics if the hardware level is at least {@code hwLevel};
* check that the key is present if the actual capabilities are one of {@code capabilities}.
*
@@ -351,7 +447,8 @@
assertNotNull("android.info.supportedHardwareLevel must never be null", actualHwLevel);
int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
- assertNotNull("android.request.availableCapabilities must never be null");
+ assertNotNull("android.request.availableCapabilities must never be null",
+ actualCapabilities);
List<Key<?>> allKeys = c.getKeys();
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
index 61f25fb..a68f78d 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -88,10 +88,6 @@
try {
Log.v(TAG, "Testing jpeg capture for Camera " + id);
openDevice(id);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
bufferFormatTestByCamera(ImageFormat.JPEG, /*repeating*/false);
} finally {
closeDevice(id);
@@ -117,10 +113,6 @@
try {
Log.v(TAG, "Testing repeating jpeg capture for Camera " + id);
openDevice(id);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
bufferFormatTestByCamera(ImageFormat.JPEG, /*repeating*/true);
} finally {
closeDevice(id);
@@ -156,10 +148,7 @@
try {
Log.v(TAG, "YUV and JPEG testing for camera " + id);
openDevice(id);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
+
bufferFormatWithYuvTestByCamera(ImageFormat.JPEG);
} finally {
closeDevice(id);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java
index 8b8f2f6..d4a0e73 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -195,11 +195,6 @@
try {
openDevice(id);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
-
boolean partialsExpected = mStaticInfo.getPartialResultCount() > 1;
long startTimeMs;
boolean isPartialTimingValid = partialsExpected;
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index 669de2d..386696c 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -30,6 +30,7 @@
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaCodecList;
+import android.media.MediaFormat;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Environment;
@@ -287,8 +288,9 @@
updatePreviewSurfaceWithVideoSize(size);
// Start recording
+ SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
startSlowMotionRecording(/*useMediaRecorder*/true, videoFramerate, captureRate,
- fpsRange);
+ fpsRange, resultListener);
long startTime = SystemClock.elapsedRealtime();
// Record certain duration.
@@ -296,10 +298,12 @@
// Stop recording and preview
stopRecording(/*useMediaRecorder*/true);
- int duration = (int) (SystemClock.elapsedRealtime() - startTime);
+ // Convert number of frames camera produced into the duration in unit of ms.
+ int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
+ videoFramerate);
// Validation.
- validateRecording(size, duration * SLOWMO_SLOW_FACTOR);
+ validateRecording(size, durationMs);
}
@@ -329,7 +333,8 @@
}
private void startSlowMotionRecording(boolean useMediaRecorder, int videoFrameRate,
- int captureRate, Range<Integer> fpsRange) throws Exception {
+ int captureRate, Range<Integer> fpsRange,
+ CameraCaptureSession.CaptureCallback listener) throws Exception {
List<Surface> outputSurfaces = new ArrayList<Surface>(2);
assertTrue("Both preview and recording surfaces should be valid",
mPreviewSurface.isValid() && mRecordingSurface.isValid());
@@ -370,7 +375,7 @@
for (int i = 0; i < slowMotionFactor - 1; i++) {
slowMoRequests.add(recordingOnlyBuilder.build()); // Recording only.
}
- mSession.setRepeatingBurst(slowMoRequests, null, null);
+ mSession.setRepeatingBurst(slowMoRequests, listener, mHandler);
if (useMediaRecorder) {
mMediaRecorder.start();
@@ -415,18 +420,25 @@
updatePreviewSurfaceWithVideoSize(videoSz);
// Start recording
- startRecording(/* useMediaRecorder */true);
- long startTime = SystemClock.elapsedRealtime();
+ SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+ startRecording(/* useMediaRecorder */true, resultListener);
// Record certain duration.
SystemClock.sleep(RECORDING_DURATION_MS);
// Stop recording and preview
stopRecording(/* useMediaRecorder */true);
- int duration = (int) (SystemClock.elapsedRealtime() - startTime);
+ // Convert number of frames camera produced into the duration in unit of ms.
+ int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
+ profile.videoFrameRate);
+
+ if (VERBOSE) {
+ Log.v(TAG, "video frame rate: " + profile.videoFrameRate +
+ ", num of frames produced: " + resultListener.getTotalNumFrames());
+ }
// Validation.
- validateRecording(videoSz, duration);
+ validateRecording(videoSz, durationMs);
}
}
@@ -458,18 +470,20 @@
updatePreviewSurfaceWithVideoSize(sz);
// Start recording
- startRecording(/* useMediaRecorder */true);
- long startTime = SystemClock.elapsedRealtime();
+ SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+ startRecording(/* useMediaRecorder */true, resultListener);
// Record certain duration.
SystemClock.sleep(RECORDING_DURATION_MS);
// Stop recording and preview
stopRecording(/* useMediaRecorder */true);
- int duration = (int) (SystemClock.elapsedRealtime() - startTime);
+ // Convert number of frames camera produced into the duration in unit of ms.
+ int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
+ VIDEO_FRAME_RATE);
// Validation.
- validateRecording(sz, duration);
+ validateRecording(sz, durationMs);
}
}
@@ -497,11 +511,6 @@
openDevice(id);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
-
initSupportedVideoSize(id);
videoSnapshotTestByCamera(burstTest);
@@ -861,7 +870,8 @@
// TODO: Don't skip this for video snapshot
if (!mStaticInfo.isHardwareLevelLegacy()) {
assertTrue(String.format(
- "Video duration doesn't match: recorded %dms, expected %dms", duration,
+ "Camera %s: Video duration doesn't match: recorded %dms, expected %dms",
+ mCamera.getId(), duration,
durationMs), Math.abs(duration - durationMs) < DURATION_MARGIN_MS);
}
} finally {
@@ -1050,133 +1060,10 @@
* by AVC specification for certain level.
*/
private static boolean isSupportedByAVCEncoder(Size sz, int frameRate) {
- String mimeType = "video/avc";
- MediaCodecInfo codecInfo = getEncoderInfo(mimeType);
- if (codecInfo == null) {
- return false;
- }
- CodecCapabilities cap = codecInfo.getCapabilitiesForType(mimeType);
- if (cap == null) {
- return false;
- }
-
- int highestLevel = 0;
- for (CodecProfileLevel lvl : cap.profileLevels) {
- if (lvl.level > highestLevel) {
- highestLevel = lvl.level;
- }
- }
- // Don't support anything meaningful for level 1 or 2.
- if (highestLevel <= CodecProfileLevel.AVCLevel2) {
- return false;
- }
-
- if(VERBOSE) {
- Log.v(TAG, "The highest level supported by encoder is: " + highestLevel);
- }
-
- // Put bitRate here for future use.
- int maxW, maxH, bitRate;
- // Max encoding speed.
- int maxMacroblocksPerSecond = 0;
- switch(highestLevel) {
- case CodecProfileLevel.AVCLevel21:
- maxW = 352;
- maxH = 576;
- bitRate = 4000000;
- maxMacroblocksPerSecond = 19800;
- break;
- case CodecProfileLevel.AVCLevel22:
- maxW = 720;
- maxH = 480;
- bitRate = 4000000;
- maxMacroblocksPerSecond = 20250;
- break;
- case CodecProfileLevel.AVCLevel3:
- maxW = 720;
- maxH = 480;
- bitRate = 10000000;
- maxMacroblocksPerSecond = 40500;
- break;
- case CodecProfileLevel.AVCLevel31:
- maxW = 1280;
- maxH = 720;
- bitRate = 14000000;
- maxMacroblocksPerSecond = 108000;
- break;
- case CodecProfileLevel.AVCLevel32:
- maxW = 1280;
- maxH = 720;
- bitRate = 20000000;
- maxMacroblocksPerSecond = 216000;
- break;
- case CodecProfileLevel.AVCLevel4:
- maxW = 1920;
- maxH = 1088; // It should be 1088 in terms of AVC capability.
- bitRate = 20000000;
- maxMacroblocksPerSecond = 245760;
- break;
- case CodecProfileLevel.AVCLevel41:
- maxW = 1920;
- maxH = 1088; // It should be 1088 in terms of AVC capability.
- bitRate = 50000000;
- maxMacroblocksPerSecond = 245760;
- break;
- case CodecProfileLevel.AVCLevel42:
- maxW = 2048;
- maxH = 1088; // It should be 1088 in terms of AVC capability.
- bitRate = 50000000;
- maxMacroblocksPerSecond = 522240;
- break;
- case CodecProfileLevel.AVCLevel5:
- maxW = 3672;
- maxH = 1536;
- bitRate = 135000000;
- maxMacroblocksPerSecond = 589824;
- break;
- case CodecProfileLevel.AVCLevel51:
- default:
- maxW = 4096;
- maxH = 2304;
- bitRate = 240000000;
- maxMacroblocksPerSecond = 983040;
- break;
- }
-
- // Check size limit.
- if (sz.getWidth() > maxW || sz.getHeight() > maxH) {
- Log.i(TAG, "Requested resolution " + sz.toString() + " exceeds (" +
- maxW + "," + maxH + ")");
- return false;
- }
-
- // Check frame rate limit.
- Size sizeInMb = new Size((sz.getWidth() + 15) / 16, (sz.getHeight() + 15) / 16);
- int maxFps = maxMacroblocksPerSecond / (sizeInMb.getWidth() * sizeInMb.getHeight());
- if (frameRate > maxFps) {
- Log.i(TAG, "Requested frame rate " + frameRate + " exceeds " + maxFps);
- return false;
- }
-
- return true;
- }
-
- private static MediaCodecInfo getEncoderInfo(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;
+ MediaFormat format = MediaFormat.createVideoFormat(
+ MediaFormat.MIMETYPE_VIDEO_AVC, sz.getWidth(), sz.getHeight());
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ return mcl.findEncoderForFormat(format) != null;
}
}
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 7960200..192bf56 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -128,10 +128,13 @@
{YUV , PREVIEW, YUV, PREVIEW, JPEG, MAXIMUM } // Two-input in-app processing with still capture.
};
- final int[][] FULL_COMBINATIONS = {
+ final int[][] BURST_COMBINATIONS = {
{PRIV, PREVIEW, PRIV, MAXIMUM }, // Maximum-resolution GPU processing with preview.
{PRIV, PREVIEW, YUV, MAXIMUM }, // Maximum-resolution in-app processing with preview.
{YUV, PREVIEW, YUV, MAXIMUM }, // Maximum-resolution two-input in-app processsing.
+ };
+
+ final int[][] FULL_COMBINATIONS = {
{PRIV, PREVIEW, PRIV, PREVIEW, JPEG, MAXIMUM }, //Video recording with maximum-size video snapshot.
{YUV, VGA, PRIV, PREVIEW, YUV, MAXIMUM }, // Standard video recording plus maximum-resolution in-app processing.
{YUV, VGA, YUV, PREVIEW, YUV, MAXIMUM } // Preview plus two-input maximum-resolution in-app processing.
@@ -149,7 +152,7 @@
};
final int[][][] TABLES =
- { LEGACY_COMBINATIONS, LIMITED_COMBINATIONS, FULL_COMBINATIONS, RAW_COMBINATIONS };
+ { LEGACY_COMBINATIONS, LIMITED_COMBINATIONS, BURST_COMBINATIONS, FULL_COMBINATIONS, RAW_COMBINATIONS };
// Sanity check the tables
int tableIdx = 0;
@@ -185,11 +188,6 @@
final StaticMetadata staticInfo = new StaticMetadata(cc);
- if (staticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
-
openDevice(id);
// Always run legacy-level tests
@@ -208,7 +206,14 @@
testOutputCombination(id, config, maxSizes);
}
- // Check for FULL and RAW and run those if appropriate
+ // Check for BURST_CAPTURE, FULL and RAW and run those if appropriate
+
+ if (staticInfo.isCapabilitySupported(
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE)) {
+ for (int[] config : BURST_COMBINATIONS) {
+ testOutputCombination(id, config, maxSizes);
+ }
+ }
if (staticInfo.isHardwareLevelFull()) {
for (int[] config : FULL_COMBINATIONS) {
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java
index ec7ecf8..ed5eba9 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java
@@ -52,6 +52,9 @@
private static final float MIN_FPS_FOR_FULL_DEVICE = 20.0f;
private String mCameraId;
+ // Last defined capability enum, for iterating over all of them
+ private static final int LAST_CAPABILITY_ENUM = REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE;
+
/**
* Test the available capability for different hardware support level devices.
*/
@@ -65,11 +68,13 @@
if (mStaticInfo.isHardwareLevelFull()) {
// Capability advertisement must be right.
- mCollector.expectTrue("Full device must contains MANUAL_SENSOR capability",
+ mCollector.expectTrue("Full device must contain MANUAL_SENSOR capability",
availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR));
- mCollector.expectTrue("Full device must contains MANUAL_POST_PROCESSING capability",
+ mCollector.expectTrue("Full device must contain MANUAL_POST_PROCESSING capability",
availableCaps.contains(
REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING));
+ mCollector.expectTrue("Full device must contain BURST_CAPTURE capability",
+ availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE));
// Max resolution fps must be >= 20.
mCollector.expectTrue("Full device must support at least 20fps for max resolution",
@@ -80,6 +85,12 @@
mStaticInfo.isPerFrameControlSupported());
}
+ if (availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+ mCollector.expectTrue("MANUAL_SENSOR capability always requires " +
+ "READ_SENSOR_SETTINGS capability as well",
+ availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS));
+ }
+
// TODO: test all the keys mandatory for all capability devices.
}
}
@@ -121,7 +132,7 @@
List<Integer> availableCaps = mStaticInfo.getAvailableCapabilitiesChecked();
for (Integer capability = REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE;
- capability <= REQUEST_AVAILABLE_CAPABILITIES_RAW; capability++) {
+ capability <= LAST_CAPABILITY_ENUM; capability++) {
boolean isCapabilityAvailable = availableCaps.contains(capability);
validateCapability(capability, isCapabilityAvailable);
}
@@ -227,6 +238,7 @@
private void validateCapability(Integer capability, boolean isCapabilityAvailable) {
List<CaptureRequest.Key<?>> requestKeys = new ArrayList<>();
+ Set<CaptureResult.Key<?>> resultKeys = new HashSet<>();
/* For available capabilities, only check request keys in this test
Characteristics keys are tested in ExtendedCameraCharacteristicsTest
Result keys are tested in CaptureResultTest */
@@ -298,6 +310,7 @@
requestKeys.add(CaptureRequest.SENSOR_SENSITIVITY);
if (mStaticInfo.hasFocuser()) {
requestKeys.add(CaptureRequest.LENS_APERTURE);
+ requestKeys.add(CaptureRequest.LENS_FOCUS_DISTANCE);
requestKeys.add(CaptureRequest.LENS_FILTER_DENSITY);
requestKeys.add(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE);
}
@@ -307,15 +320,37 @@
// RAW_CAPABILITY needs to check for not just capture request keys
validateRawCapability(isCapabilityAvailable);
return;
+ case REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE:
+ // Tested in ExtendedCameraCharacteristicsTest
+ return;
+ case REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS:
+ capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS";
+ resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION);
+ resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME);
+ resultKeys.add(CaptureResult.SENSOR_SENSITIVITY);
+ if (mStaticInfo.hasFocuser()) {
+ resultKeys.add(CaptureResult.LENS_APERTURE);
+ resultKeys.add(CaptureResult.LENS_FOCUS_DISTANCE);
+ resultKeys.add(CaptureResult.LENS_FILTER_DENSITY);
+ }
+ break;
default:
capabilityName = "Unknown";
- Assert.fail(String.format("Unknown capability: %d", capability));
+ assertTrue(String.format("Unknown capability set: %d", capability),
+ !isCapabilityAvailable);
+ return;
}
- boolean matchExpectation =
- validateRequestKeysPresence(capabilityName, requestKeys, isCapabilityAvailable);
+ boolean matchExpectation = true;
+ if (!requestKeys.isEmpty()) {
+ matchExpectation &= validateRequestKeysPresence(capabilityName, requestKeys, isCapabilityAvailable);
+ }
+ if(!resultKeys.isEmpty()) {
+ matchExpectation &= validateResultKeysPresence(capabilityName, resultKeys, isCapabilityAvailable);
+ }
+
// In case of isCapabilityAvailable == true, error has been filed in
- // validateRequestKeysPresence
+ // validateRequest/ResultKeysPresence
if (!matchExpectation && !isCapabilityAvailable) {
mCollector.addMessage(String.format(
"Camera %s doesn't list capability %s but contain all required keys",
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 e816659..c6da122 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -263,11 +263,6 @@
Log.i(TAG, "Testing Still preview capture combination for Camera " + id);
openDevice(id);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test for legacy devices");
- continue;
- }
-
previewStillCombinationTestByCamera();
} finally {
closeDevice();
@@ -314,11 +309,6 @@
Log.i(TAG, "Testing AE regions for Camera " + id);
openDevice(id);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
-
boolean aeRegionsSupported = isRegionsSupportedFor3A(MAX_REGIONS_AE_INDEX);
if (!aeRegionsSupported) {
continue;
@@ -369,11 +359,6 @@
Log.i(TAG, "Testing AF regions for Camera " + id);
openDevice(id);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
-
boolean afRegionsSupported = isRegionsSupportedFor3A(MAX_REGIONS_AF_INDEX);
if (!afRegionsSupported) {
continue;
@@ -1259,6 +1244,8 @@
CaptureRequest.Builder stillRequest =
mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
stillRequest.set(CaptureRequest.CONTROL_AE_LOCK, true);
+ CaptureResult normalResult;
+ CaptureResult compensatedResult;
// The following variables should only be read under the MANUAL_SENSOR capability guard:
long minExposureValue = -1;
@@ -1290,13 +1277,13 @@
// Wait for AE to be stabilized before capture: CONVERGED or FLASH_REQUIRED.
waitForAeStable(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
- CaptureResult result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+ normalResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
long normalExposureValue = -1;
if (mStaticInfo.isCapabilitySupported(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
// get and check if current exposure value is valid
- normalExposureValue = getExposureValue(result);
+ normalExposureValue = getExposureValue(normalResult);
mCollector.expectInRange("Exposure setting out of bound", normalExposureValue,
minExposureValue, maxExposureValuePreview);
@@ -1306,6 +1293,12 @@
expectedExposureValue > maxExposureValueStill) {
continue;
}
+ Log.v(TAG, "Expect ratio: " + expectedRatio +
+ " normalExposureValue: " + normalExposureValue +
+ " expectedExposureValue: " + expectedExposureValue +
+ " minExposureValue: " + minExposureValue +
+ " maxExposureValuePreview: " + maxExposureValuePreview +
+ " maxExposureValueStill: " + maxExposureValueStill);
}
// Now issue exposure compensation and wait for AE locked. AE could take a few
@@ -1326,29 +1319,39 @@
CaptureRequest request = stillRequest.build();
mSession.capture(request, resultListener, mHandler);
- result = resultListener.getCaptureResultForRequest(request, WAIT_FOR_RESULT_TIMEOUT_MS);
+ compensatedResult = resultListener.getCaptureResultForRequest(
+ request, WAIT_FOR_RESULT_TIMEOUT_MS);
if (mStaticInfo.isCapabilitySupported(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
// Verify the exposure value compensates as requested
- long compensatedExposureValue = getExposureValue(result);
+ long compensatedExposureValue = getExposureValue(compensatedResult);
mCollector.expectInRange("Exposure setting out of bound", compensatedExposureValue,
minExposureValue, maxExposureValueStill);
double observedRatio = (double) compensatedExposureValue / normalExposureValue;
double error = observedRatio / expectedRatio;
- mCollector.expectInRange(String.format(
- "Exposure compensation ratio exceeds error tolerence:"
- + " expected(%f) observed(%f) ", expectedRatio, observedRatio),
- error,
+ String errorString = String.format(
+ "Exposure compensation ratio exceeds error tolerence:" +
+ " expected(%f) observed(%f)." +
+ " Normal exposure time %d us, sensitivity %d." +
+ " Compensated exposure time %d us, sensitivity %d",
+ expectedRatio, observedRatio,
+ (int) (getValueNotNull(
+ normalResult, CaptureResult.SENSOR_EXPOSURE_TIME) / 1000),
+ getValueNotNull(normalResult, CaptureResult.SENSOR_SENSITIVITY),
+ (int) (getValueNotNull(
+ compensatedResult, CaptureResult.SENSOR_EXPOSURE_TIME) / 1000),
+ getValueNotNull(compensatedResult, CaptureResult.SENSOR_SENSITIVITY));
+ mCollector.expectInRange(errorString, error,
1.0 - AE_COMPENSATION_ERROR_TOLERANCE,
1.0 + AE_COMPENSATION_ERROR_TOLERANCE);
}
mCollector.expectEquals("Exposure compensation result should match requested value.",
exposureCompensation,
- result.get(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION));
+ compensatedResult.get(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION));
mCollector.expectTrue("Exposure lock should be set",
- result.get(CaptureResult.CONTROL_AE_LOCK));
+ compensatedResult.get(CaptureResult.CONTROL_AE_LOCK));
Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
validateJpegCapture(image, maxStillSz);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
index b3d4cf9..01da4c8 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -74,11 +74,6 @@
Log.i(TAG, "Testing preview for Camera " + mCameraIds[i]);
openDevice(mCameraIds[i]);
- if (mStaticInfo.isHardwareLevelLegacy()) {
- Log.i(TAG, "Skipping test on legacy devices");
- continue;
- }
-
previewTestByCamera();
} finally {
closeDevice();
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index a5c7083..9837fb7 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -1480,7 +1480,7 @@
checkArrayValuesInRange(key, availableCaps,
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
- CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW);
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
capList = Arrays.asList(CameraTestUtils.toObject(availableCaps));
return capList;
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java
index 687826c..bd47024 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java
@@ -20,9 +20,7 @@
import android.hardware.SensorManager;
import android.hardware.cts.helpers.SensorStats;
import android.hardware.cts.helpers.TestSensorEnvironment;
-import android.hardware.cts.helpers.sensoroperations.TestSensorFlushOperation;
import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
-import android.hardware.cts.helpers.sensoroperations.VerifiableSensorOperation;
import android.hardware.cts.helpers.sensorverification.ISensorVerification;
import java.util.concurrent.TimeUnit;
@@ -263,7 +261,7 @@
rateUs,
maxBatchReportLatencyUs);
TestSensorOperation operation =
- new TestSensorOperation(environment, testDurationSec, TimeUnit.SECONDS);
+ TestSensorOperation.createOperation(environment, testDurationSec, TimeUnit.SECONDS);
executeTest(environment, operation, false /* flushExpected */);
}
@@ -279,15 +277,15 @@
shouldEmulateSensorUnderLoad(),
rateUs,
maxBatchReportLatencyUs);
- TestSensorFlushOperation operation =
- new TestSensorFlushOperation(environment, flushDurationSec, TimeUnit.SECONDS);
+ TestSensorOperation operation = TestSensorOperation
+ .createFlushOperation(environment, flushDurationSec, TimeUnit.SECONDS);
executeTest(environment, operation, true /* flushExpected */);
}
private void executeTest(
TestSensorEnvironment environment,
- VerifiableSensorOperation operation,
+ TestSensorOperation operation,
boolean flushExpected) throws Throwable {
operation.addDefaultVerifications();
operation.setLogEvents(true);
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
index 50cb12d..4dfa16e 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
@@ -24,7 +24,6 @@
import android.hardware.cts.helpers.sensoroperations.RepeatingSensorOperation;
import android.hardware.cts.helpers.sensoroperations.SequentialSensorOperation;
import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
-import android.hardware.cts.helpers.sensoroperations.VerifiableSensorOperation;
import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
import java.util.Random;
@@ -81,7 +80,7 @@
shouldEmulateSensorUnderLoad(),
SensorManager.SENSOR_DELAY_FASTEST);
TestSensorOperation continuousOperation =
- new TestSensorOperation(environment, 100 /* eventCount */);
+ TestSensorOperation.createOperation(environment, 100 /* eventCount */);
continuousOperation.addVerification(new EventOrderingVerification());
operation.add(new RepeatingSensorOperation(continuousOperation, ITERATIONS));
@@ -93,7 +92,7 @@
sensor.getMinDelay(),
MAX_REPORTING_LATENCY_US);
TestSensorOperation batchingOperation =
- new TestSensorOperation(batchingEnvironment, 100 /* eventCount */);
+ TestSensorOperation.createOperation(batchingEnvironment, 100 /* eventCount */);
batchingOperation.addVerification(new EventOrderingVerification());
operation.add(new RepeatingSensorOperation(batchingOperation, ITERATIONS));
}
@@ -145,7 +144,7 @@
generateSamplingRateInUs(sensorType),
generateReportLatencyInUs());
TestSensorOperation sensorOperation =
- new TestSensorOperation(environment, 100 /* eventCount */);
+ TestSensorOperation.createOperation(environment, 100 /* eventCount */);
sensorOperation.addVerification(new EventOrderingVerification());
sequentialOperation.add(sensorOperation);
}
@@ -229,7 +228,7 @@
shouldEmulateSensorUnderLoad(),
SensorManager.SENSOR_DELAY_FASTEST);
TestSensorOperation tester =
- new TestSensorOperation(testerEnvironment, 100 /* event count */);
+ TestSensorOperation.createOperation(testerEnvironment, 100 /* event count */);
tester.addVerification(new EventOrderingVerification());
TestSensorEnvironment testeeEnvironment = new TestSensorEnvironment(
@@ -237,8 +236,8 @@
sensorTypeTestee,
shouldEmulateSensorUnderLoad(),
SensorManager.SENSOR_DELAY_FASTEST);
- VerifiableSensorOperation testee =
- new TestSensorOperation(testeeEnvironment, 100 /* event count */);
+ TestSensorOperation testee =
+ TestSensorOperation.createOperation(testeeEnvironment, 100 /* event count */);
testee.addVerification(new EventOrderingVerification());
ParallelSensorOperation operation = new ParallelSensorOperation();
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
index d8b8e51..08d06c6 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
@@ -18,6 +18,8 @@
import com.android.cts.util.TimeoutReq;
+import junit.framework.Assert;
+
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
@@ -27,44 +29,70 @@
import android.hardware.SensorManager;
import android.hardware.TriggerEvent;
import android.hardware.TriggerEventListener;
+import android.hardware.cts.helpers.SensorNotSupportedException;
+import android.hardware.cts.helpers.SensorTestStateNotSupportedException;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEventListener;
+import android.hardware.cts.helpers.TestSensorManager;
+import android.hardware.cts.helpers.sensoroperations.ParallelSensorOperation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.EventGapVerification;
+import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
+import android.hardware.cts.helpers.sensorverification.EventTimestampSynchronizationVerification;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.PowerManager;
import android.os.SystemClock;
import android.util.Log;
+import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class SensorTest extends SensorTestCase {
- private SensorManager mSensorManager;
- private TriggerListener mTriggerListener;
- private SensorListener mSensorListener;
- private List<Sensor> mSensorList;
private static final String TAG = "SensorTest";
+
// Test only SDK defined sensors. Any sensors with type > 100 are ignored.
private static final int MAX_OFFICIAL_ANDROID_SENSOR_TYPE = 100;
- private static final long TIMEOUT_TOLERANCE_US = TimeUnit.SECONDS.toMicros(5);
- private static final double MIN_SAMPLING_FREQUENCY_MULTIPLIER_TOLERANCE = 0.9;
+
private PowerManager.WakeLock mWakeLock;
+ private SensorManager mSensorManager;
+ private NullTriggerEventListener mNullTriggerEventListener;
+ private NullSensorEventListener mNullSensorEventListener;
+ private List<Sensor> mSensorList;
@Override
protected void setUp() throws Exception {
- super.setUp();
- mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
- mTriggerListener = new TriggerListener();
- mSensorListener = new SensorListener();
- mSensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
- PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
+ Context context = getContext();
+ PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+
+ mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+ mNullTriggerEventListener = new NullTriggerEventListener();
+ mNullSensorEventListener = new NullSensorEventListener();
+
+ mSensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+ assertNotNull("SensorList was null.", mSensorList);
+ if (mSensorList.isEmpty()) {
+ // several devices will not have sensors, so we need to skip the tests in those cases
+ throw new SensorTestStateNotSupportedException(
+ "Sensors are not available in the system.");
+ }
+
+ mWakeLock.acquire();
}
+ @Override
+ protected void tearDown(){
+ if (mWakeLock != null && mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ }
+
+ @SuppressWarnings("deprecation")
public void testSensorOperations() {
// Because we can't know every sensors unit details, so we can't assert
// get values with specified values.
- List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
- assertNotNull(sensors);
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
boolean hasAccelerometer = getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_SENSOR_ACCELEROMETER);
@@ -149,7 +177,6 @@
}
assertTrue(sensors.get(0).getName() + " defined as non-wake-up sensor",
sensors.get(0).isWakeUpSensor());
- return;
}
// Some sensors like proximity, significant motion etc. are defined as wake-up sensors by
@@ -207,372 +234,137 @@
public void testRequestTriggerWithNonTriggerSensor() {
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
- boolean result;
- if (sensor != null) {
- result = mSensorManager.requestTriggerSensor(mTriggerListener, sensor);
- assertFalse(result);
+ if (sensor == null) {
+ throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER);
}
+ boolean result = mSensorManager.requestTriggerSensor(mNullTriggerEventListener, sensor);
+ assertFalse(result);
}
public void testCancelTriggerWithNonTriggerSensor() {
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
- boolean result;
- if (sensor != null) {
- result = mSensorManager.cancelTriggerSensor(mTriggerListener, sensor);
- assertFalse(result);
+ if (sensor == null) {
+ throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER);
}
+ boolean result = mSensorManager.cancelTriggerSensor(mNullTriggerEventListener, sensor);
+ assertFalse(result);
}
public void testRegisterWithTriggerSensor() {
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
- boolean result;
- if (sensor != null) {
- result = mSensorManager.registerListener(mSensorListener, sensor,
- SensorManager.SENSOR_DELAY_NORMAL);
- assertFalse(result);
+ if (sensor == null) {
+ throw new SensorNotSupportedException(Sensor.TYPE_SIGNIFICANT_MOTION);
}
+ boolean result = mSensorManager.registerListener(
+ mNullSensorEventListener,
+ sensor,
+ SensorManager.SENSOR_DELAY_NORMAL);
+ assertFalse(result);
}
public void testRegisterTwiceWithSameSensor() {
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
- boolean result;
- if (sensor != null) {
- result = mSensorManager.registerListener(mSensorListener, sensor,
- SensorManager.SENSOR_DELAY_NORMAL);
- assertTrue(result);
- result = mSensorManager.registerListener(mSensorListener, sensor,
- SensorManager.SENSOR_DELAY_NORMAL);
- assertFalse(result);
+ if (sensor == null) {
+ throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER);
}
+
+ boolean result = mSensorManager.registerListener(mNullSensorEventListener, sensor,
+ SensorManager.SENSOR_DELAY_NORMAL);
+ assertTrue(result);
+
+ result = mSensorManager.registerListener(mNullSensorEventListener, sensor,
+ SensorManager.SENSOR_DELAY_NORMAL);
+ assertFalse(result);
}
- class SensorEventTimeStampListener implements SensorEventListener {
- SensorEventTimeStampListener(long eventReportLatencyNs, CountDownLatch latch) {
- mEventReportLatencyNs = eventReportLatencyNs;
- mPrevTimeStampNs = -1;
- mLatch = latch;
- numErrors = 0;
- }
-
- @Override
- public void onSensorChanged(SensorEvent event) {
- if (mPrevTimeStampNs == -1) {
- mPrevTimeStampNs = event.timestamp;
- return;
- }
- long currTimeStampNs = event.timestamp;
- if (currTimeStampNs <= mPrevTimeStampNs) {
- Log.w(TAG, "Timestamps not monotonically increasing curr_ts_ns=" +
- event.timestamp + " prev_ts_ns=" + mPrevTimeStampNs);
- numErrors++;
- mPrevTimeStampNs = currTimeStampNs;
- return;
- }
- mLatch.countDown();
-
- final long elapsedRealtimeNs = SystemClock.elapsedRealtimeNanos();
-
- if (elapsedRealtimeNs <= currTimeStampNs) {
- Log.w(TAG, "Timestamps into the future curr elapsedRealTimeNs=" + elapsedRealtimeNs
- + " current sensor ts_ns=" + currTimeStampNs);
- ++numErrors;
- } else if (elapsedRealtimeNs-currTimeStampNs > SYNC_TOLERANCE + mEventReportLatencyNs) {
- Log.w(TAG, "Timestamp sync error elapsedRealTimeNs=" + elapsedRealtimeNs +
- " curr_ts_ns=" + currTimeStampNs +
- " diff_ns=" + (elapsedRealtimeNs - currTimeStampNs) +
- " SYNC_TOLERANCE_NS=" + SYNC_TOLERANCE +
- " eventReportLatencyNs=" + mEventReportLatencyNs);
- ++numErrors;
- }
- mPrevTimeStampNs = currTimeStampNs;
- }
-
- public int getNumErrors() {
- return numErrors;
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
-
- private int numErrors;
- private long mEventReportLatencyNs;
- private long mPrevTimeStampNs;
- private final CountDownLatch mLatch;
- private final long SYNC_TOLERANCE = 500000000L; // 500 milli seconds approx.
- }
-
- // Register for each sensor and compare the timestamps of SensorEvents that you get with
- // elapsedRealTimeNano.
+ // TODO: remove when parametized tests are supported and EventTimestampSynchronization
+ // verification is added to default verifications
@TimeoutReq(minutes=60)
public void testSensorTimeStamps() throws Exception {
- final int numEvents = 2000;
- try {
- mWakeLock.acquire();
- int numErrors = 0;
- for (Sensor sensor : mSensorList) {
- // Skip OEM defined sensors and non continuous sensors.
- if (sensor.getReportingMode() != Sensor.REPORTING_MODE_CONTINUOUS) {
- continue;
- }
-
- for (int iterations = 0; iterations < 2; ++iterations) {
- // Test in both batch mode and non-batch mode for every sensor.
- long maxBatchReportLatencyNs = 10000000000L; // 10 secs
- if (iterations % 2 == 0) maxBatchReportLatencyNs = 0;
-
- final long samplingPeriodNs = (long)(TimeUnit.MICROSECONDS.toNanos(
- sensor.getMinDelay())/MIN_SAMPLING_FREQUENCY_MULTIPLIER_TOLERANCE);
- // If there is a FIFO and a wake-lock is held, events will be reported when
- // the batch timeout expires or when the FIFO is full which ever occurs
- // earlier.
- final long eventReportLatencyNs = Math.min(maxBatchReportLatencyNs,
- sensor.getFifoMaxEventCount() * samplingPeriodNs);
-
- final CountDownLatch eventsRemaining = new CountDownLatch(numEvents);
- SensorEventTimeStampListener listener = new SensorEventTimeStampListener(
- eventReportLatencyNs, eventsRemaining);
-
- Log.i(TAG, "Running timeStamp test on " + sensor.getName());
- boolean result = mSensorManager.registerListener(listener, sensor,
- SensorManager.SENSOR_DELAY_FASTEST,
- (int)maxBatchReportLatencyNs/1000);
- assertTrue("Sensor registerListener failed ", result);
-
- long timeToWaitUs = samplingPeriodNs/1000 + eventReportLatencyNs/1000 +
- TIMEOUT_TOLERANCE_US;
- long totalTimeWaitedUs = waitToCollectAllEvents(timeToWaitUs,
- (int)(eventReportLatencyNs/1000), eventsRemaining);
-
- mSensorManager.unregisterListener(listener);
- if (eventsRemaining.getCount() > 0) {
- failTimedOut(sensor.getName(), (double) totalTimeWaitedUs/1000,
- numEvents, (double) sensor.getMinDelay()/1000,
- eventsRemaining.getCount(),
- numEvents - eventsRemaining.getCount());
- }
- if (listener.getNumErrors() > 5) {
- fail("Check logcat. Timestamp test failed. numErrors=" +
- listener.getNumErrors() + " " + sensor.getName() +
- " maxBatchReportLatencyNs=" + maxBatchReportLatencyNs +
- " samplingPeriodNs=" + sensor.getMinDelay());
- numErrors += listener.getNumErrors();
- } else {
- Log.i(TAG, "TimeStamp test PASS'd on " + sensor.getName());
- }
- }
- }
- } finally {
- mWakeLock.release();
+ ArrayList<Throwable> errorsFound = new ArrayList<>();
+ for (Sensor sensor : mSensorList) {
+ // test both continuous and batching mode sensors
+ verifyLongActivation(sensor, 0 /* maxReportLatencyUs */, errorsFound);
+ verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10), errorsFound);
}
+ assertOnErrors(errorsFound);
}
- private void failTimedOut(String sensorName, double totalTimeWaitedMs, int numEvents,
- double minDelayMs, long eventsRemaining, long eventsReceived) {
- final String TIMED_OUT_FORMAT = "Timed out waiting for events from %s " +
- "waited for time=%.1fms to receive totalEvents=%d at samplingRate=%.1fHz" +
- " remainingEvents=%d received events=%d";
- fail(String.format(TIMED_OUT_FORMAT, sensorName, totalTimeWaitedMs, numEvents,
- 1000/minDelayMs, eventsRemaining, eventsReceived));
- }
-
- // Register for updates from each continuous mode sensor, wait for N events, call flush and
- // wait for flushCompleteEvent before unregistering for the sensor.
+ // TODO: remove when parameterized tests are supported (see SensorBatchingTests.java)
@TimeoutReq(minutes=20)
public void testBatchAndFlush() throws Exception {
- try {
- mWakeLock.acquire();
- for (Sensor sensor : mSensorList) {
- // Skip ONLY one-shot sensors.
- if (sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) {
- registerListenerCallFlush(sensor, null);
- }
- }
- } finally {
- mWakeLock.release();
+ ArrayList<Throwable> errorsFound = new ArrayList<>();
+ for (Sensor sensor : mSensorList) {
+ verifyRegisterListenerCallFlush(sensor, null /* handler */, errorsFound);
}
+ assertOnErrors(errorsFound);
}
- // Same as testBatchAndFlush but using Handler version of the API to register for sensors.
- // onSensorChanged is now called on a background thread.
+ /**
+ * Verifies that sensor events arrive in the given message queue (Handler).
+ */
@TimeoutReq(minutes=10)
public void testBatchAndFlushWithHandler() throws Exception {
- try {
- mWakeLock.acquire();
- HandlerThread handlerThread = new HandlerThread("sensorThread");
- handlerThread.start();
- Handler handler = new Handler(handlerThread.getLooper());
- for (Sensor sensor : mSensorList) {
- // Skip ONLY one-shot sensors.
- if (sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) {
- registerListenerCallFlush(sensor, handler);
- }
+ Sensor sensor = null;
+ for (Sensor s : mSensorList) {
+ if (s.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) {
+ sensor = s;
+ break;
}
- } finally {
- mWakeLock.release();
}
+ if (sensor == null) {
+ throw new SensorTestStateNotSupportedException(
+ "There are no Continuous sensors in the device.");
+ }
+
+ TestSensorEnvironment environment = new TestSensorEnvironment(
+ getContext(),
+ sensor,
+ SensorManager.SENSOR_DELAY_FASTEST,
+ (int) TimeUnit.SECONDS.toMicros(5));
+ TestSensorManager sensorManager = new TestSensorManager(environment);
+
+ HandlerThread handlerThread = new HandlerThread("sensorThread");
+ handlerThread.start();
+ Handler handler = new Handler(handlerThread.getLooper());
+ TestSensorEventListener listener = new TestSensorEventListener(handler);
+
+ sensorManager.registerListener(listener);
+ listener.waitForEvents(1);
+ sensorManager.requestFlush();
+ listener.waitForFlushComplete();
+ listener.assertEventsReceivedInHandler();
}
- private void registerListenerCallFlush(Sensor sensor, Handler handler)
- throws InterruptedException {
- if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
- return;
- }
- final int numEvents = 500;
- final int rateUs = 0; // DELAY_FASTEST
- final int maxBatchReportLatencyUs = 10000000;
- final CountDownLatch eventsRemaining = new CountDownLatch(numEvents);
- final CountDownLatch flushReceived = new CountDownLatch(1);
- SensorEventListener2 listener = new SensorEventListener2() {
- @Override
- public void onSensorChanged(SensorEvent event) {
- eventsRemaining.countDown();
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
-
- @Override
- public void onFlushCompleted(Sensor sensor) {
- flushReceived.countDown();
- }
- };
- // Consider only continuous mode sensors for testing registerListener.
- // For on-change sensors, call registerListener() so that the listener is associated
- // with the sensor so that flush(listener) can be called on it.
- try {
- Log.i(TAG, "testBatch " + sensor.getName());
- boolean result = mSensorManager.registerListener(listener, sensor,
- rateUs, maxBatchReportLatencyUs, handler);
- assertTrue("registerListener failed " + sensor.getName(), result);
-
- // Wait for 500 events or N seconds before the test times out.
- if (sensor.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) {
- // Wait for approximately the time required to generate these events + a tolerance
- // of 10 seconds.
- long timeToWaitUs =
- numEvents*(long)(sensor.getMinDelay()/MIN_SAMPLING_FREQUENCY_MULTIPLIER_TOLERANCE)
- + maxBatchReportLatencyUs + TIMEOUT_TOLERANCE_US;
-
- long totalTimeWaitedUs = waitToCollectAllEvents(timeToWaitUs,
- maxBatchReportLatencyUs, eventsRemaining);
- if (eventsRemaining.getCount() > 0) {
- failTimedOut(sensor.getName(), (double)totalTimeWaitedUs/1000, numEvents,
- (double)sensor.getMinDelay()/1000,
- eventsRemaining.getCount(), numEvents - eventsRemaining.getCount());
- }
- }
- Log.i(TAG, "testFlush " + sensor.getName());
- result = mSensorManager.flush(listener);
- assertTrue("flush failed " + sensor.getName(), result);
- boolean collectedAllEvents = flushReceived.await(TIMEOUT_TOLERANCE_US,
- TimeUnit.MICROSECONDS);
- if (!collectedAllEvents) {
- fail("Timed out waiting for flushCompleteEvent from " + sensor.getName() +
- " waitedFor="+ TIMEOUT_TOLERANCE_US/1000 + "ms");
- }
- Log.i(TAG, "testBatchAndFlush PASS " + sensor.getName());
- } finally {
- mSensorManager.unregisterListener(listener);
- }
- }
-
- // Wait till the CountDownLatch counts down to zero. If the events are not delivered within
- // timetoWaitUs, wait an additional maxReportLantencyUs and check if the sensor is streaming
- // data or not. If the sensor is not streaming at all, fail the test or else wait in increments
- // of maxReportLantencyUs to collect sensor events.
- private long waitToCollectAllEvents(long timeToWaitUs, int maxReportLatencyUs,
- CountDownLatch eventsRemaining)
- throws InterruptedException {
- boolean collectedAllEvents = false;
- long totalTimeWaitedUs = 0;
- long remainingEvents;
- final long INCREMENTAL_WAIT_US = maxReportLatencyUs + TimeUnit.SECONDS.toMicros(1);
- do {
- totalTimeWaitedUs += timeToWaitUs;
- remainingEvents = eventsRemaining.getCount();
- collectedAllEvents = eventsRemaining.await(timeToWaitUs, TimeUnit.MICROSECONDS);
- timeToWaitUs = INCREMENTAL_WAIT_US;
- } while (!collectedAllEvents &&
- (remainingEvents - eventsRemaining.getCount() >=(long)INCREMENTAL_WAIT_US/1000000));
- return totalTimeWaitedUs;
- }
-
- // Call registerListener for multiple sensors at a time and call flush.
+ // TODO: after L release move to SensorBatchingTests and run in all sensors with default
+ // verifications enabled
public void testBatchAndFlushWithMutipleSensors() throws Exception {
- final int MAX_SENSORS = 3;
- int numSensors = mSensorList.size() < MAX_SENSORS ? mSensorList.size() : MAX_SENSORS;
- if (numSensors == 0) {
- return;
+ final int maxSensors = 3;
+ final int maxReportLatencyUs = (int) TimeUnit.SECONDS.toMicros(10);
+ int sensorsCount = mSensorList.size();
+ int numSensors = sensorsCount < maxSensors ? sensorsCount : maxSensors;
+
+ StringBuilder builder = new StringBuilder();
+ ParallelSensorOperation parallelSensorOperation = new ParallelSensorOperation();
+ for (int i = 0; i < sensorsCount && numSensors > 0; ++i) {
+ Sensor sensor = mSensorList.get(i);
+ // skip all non-continuous sensors
+ if (sensor.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) {
+ TestSensorEnvironment environment = new TestSensorEnvironment(
+ getContext(),
+ sensor,
+ shouldEmulateSensorUnderLoad(),
+ SensorManager.SENSOR_DELAY_FASTEST,
+ maxReportLatencyUs);
+ FlushExecutor executor = new FlushExecutor(environment, 500 /* eventCount */);
+ parallelSensorOperation.add(new TestSensorOperation(environment, executor));
+ --numSensors;
+ builder.append(sensor.getName()).append(", ");
+ }
}
- final int numEvents = 500;
- int rateUs = 0; // DELAY_FASTEST
- final int maxBatchReportLatencyUs = 10000000;
- final CountDownLatch eventsRemaining = new CountDownLatch(numSensors * numEvents);
- final CountDownLatch flushReceived = new CountDownLatch(numSensors);
- SensorEventListener2 listener = new SensorEventListener2() {
- @Override
- public void onSensorChanged(SensorEvent event) {
- eventsRemaining.countDown();
- }
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
-
- @Override
- public void onFlushCompleted(Sensor sensor) {
- flushReceived.countDown();
- }
- };
-
- try {
- mWakeLock.acquire();
- StringBuilder registeredSensors = new StringBuilder(30);
- for (Sensor sensor : mSensorList) {
- // Skip all non-continuous sensors.
- if (sensor.getReportingMode() != Sensor.REPORTING_MODE_CONTINUOUS) {
- continue;
- }
- rateUs = Math.max(sensor.getMinDelay(), rateUs);
- boolean result = mSensorManager.registerListener(listener, sensor,
- SensorManager.SENSOR_DELAY_FASTEST, maxBatchReportLatencyUs);
- assertTrue("registerListener failed for " + sensor.getName(), result);
- registeredSensors.append(sensor.getName());
- registeredSensors.append(" ");
- if (--numSensors == 0) {
- break;
- }
- }
- if (registeredSensors.toString().isEmpty()) {
- return;
- }
-
- Log.i(TAG, "testBatchAndFlushWithMutipleSensors " + registeredSensors);
- long timeToWaitUs =
- numEvents*(long)(rateUs/MIN_SAMPLING_FREQUENCY_MULTIPLIER_TOLERANCE) +
- maxBatchReportLatencyUs + TIMEOUT_TOLERANCE_US;
- long totalTimeWaitedUs = waitToCollectAllEvents(timeToWaitUs, maxBatchReportLatencyUs,
- eventsRemaining);
- if (eventsRemaining.getCount() > 0) {
- failTimedOut(registeredSensors.toString(), (double)totalTimeWaitedUs/1000,
- numEvents, (double)rateUs/1000, eventsRemaining.getCount(),
- numEvents - eventsRemaining.getCount());
- }
- boolean result = mSensorManager.flush(listener);
- assertTrue("flush failed " + registeredSensors.toString(), result);
- boolean collectedFlushEvent =
- flushReceived.await(TIMEOUT_TOLERANCE_US, TimeUnit.MICROSECONDS);
- if (!collectedFlushEvent) {
- fail("Timed out waiting for flushCompleteEvent from " +
- registeredSensors.toString() + " waited for=" + timeToWaitUs/1000 + "ms");
- }
- Log.i(TAG, "testBatchAndFlushWithMutipleSensors PASS'd");
- } finally {
- mSensorManager.unregisterListener(listener);
- mWakeLock.release();
- }
+ Log.i(TAG, "Testing batch/flush for sensors: " + builder);
+ parallelSensorOperation.execute();
}
private void assertSensorValues(Sensor sensor) {
@@ -583,8 +375,8 @@
assertTrue("Max resolution must be positive. Resolution=" + sensor.getResolution() +
" " + sensor.getName(), sensor.getResolution() >= 0);
assertNotNull("Vendor name must not be null " + sensor.getName(), sensor.getVendor());
- assertTrue("Version must be positive version=" + sensor.getVersion() + " " +
- sensor.getName(), sensor.getVersion() > 0);
+ assertTrue("Version must be positive version=" + sensor.getVersion() + " " +
+ sensor.getName(), sensor.getVersion() > 0);
int fifoMaxEventCount = sensor.getFifoMaxEventCount();
int fifoReservedEventCount = sensor.getFifoReservedEventCount();
assertTrue(fifoMaxEventCount >= 0);
@@ -617,19 +409,142 @@
assertEquals(sensors, mSensorManager.getSensors());
}
- class TriggerListener extends TriggerEventListener {
- @Override
- public void onTrigger(TriggerEvent event) {
+ /**
+ * Verifies that a continuous sensor produces events that have timestamps synchronized with
+ * {@link SystemClock#elapsedRealtimeNanos()}.
+ */
+ private void verifyLongActivation(
+ Sensor sensor,
+ int maxReportLatencyUs,
+ ArrayList<Throwable> errorsFound) throws InterruptedException {
+ if (sensor.getReportingMode() != Sensor.REPORTING_MODE_CONTINUOUS) {
+ return;
+ }
+
+ try {
+ TestSensorEnvironment environment = new TestSensorEnvironment(
+ getContext(),
+ sensor,
+ shouldEmulateSensorUnderLoad(),
+ SensorManager.SENSOR_DELAY_FASTEST,
+ maxReportLatencyUs);
+ TestSensorOperation operation =
+ TestSensorOperation.createOperation(environment, 20, TimeUnit.SECONDS);
+ operation.addVerification(EventGapVerification.getDefault(environment));
+ operation.addVerification(EventOrderingVerification.getDefault(environment));
+ operation.addVerification(
+ EventTimestampSynchronizationVerification.getDefault(environment));
+
+ Log.i(TAG, "Running timestamp test on: " + sensor.getName());
+ operation.execute();
+ } catch (InterruptedException e) {
+ // propagate so the test can stop
+ throw e;
+ } catch (Throwable e) {
+ errorsFound.add(e);
+ Log.e(TAG, e.getMessage());
}
}
- class SensorListener implements SensorEventListener {
- @Override
- public void onSensorChanged(SensorEvent event) {
+ /**
+ * Verifies that a client can listen for events, and that
+ * {@link SensorManager#flush(SensorEventListener)} will trigger the appropriate notification
+ * for {@link SensorEventListener2#onFlushCompleted(Sensor)}.
+ */
+ private void verifyRegisterListenerCallFlush(
+ Sensor sensor,
+ Handler handler,
+ ArrayList<Throwable> errorsFound)
+ throws InterruptedException {
+ if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
+ return;
}
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ try {
+ TestSensorEnvironment environment = new TestSensorEnvironment(
+ getContext(),
+ sensor,
+ shouldEmulateSensorUnderLoad(),
+ SensorManager.SENSOR_DELAY_FASTEST,
+ (int) TimeUnit.SECONDS.toMicros(10));
+ FlushExecutor executor = new FlushExecutor(environment, 500 /* eventCount */);
+ TestSensorOperation operation = new TestSensorOperation(environment, executor, handler);
+
+ Log.i(TAG, "Running flush test on: " + sensor.getName());
+ operation.execute();
+ } catch (InterruptedException e) {
+ // propagate so the test can stop
+ throw e;
+ } catch (Throwable e) {
+ errorsFound.add(e);
+ Log.e(TAG, e.getMessage());
}
}
+
+ private void assertOnErrors(List<Throwable> errorsFound) {
+ if (!errorsFound.isEmpty()) {
+ StringBuilder builder = new StringBuilder();
+ for (Throwable error : errorsFound) {
+ builder.append(error.getMessage()).append("\n");
+ }
+ Assert.fail(builder.toString());
+ }
+ }
+
+ /**
+ * A delegate that drives the execution of Batch/Flush tests.
+ * It performs several operations in order:
+ * - registration
+ * - for continuous sensors it first ensures that the FIFO is filled
+ * - if events do not arrive on time, an assert will be triggered
+ * - requests flush of sensor data
+ * - waits for {@link SensorEventListener2#onFlushCompleted(Sensor)}
+ * - if the event does not arrive, an assert will be triggered
+ */
+ private class FlushExecutor implements TestSensorOperation.Executor {
+ private final TestSensorEnvironment mEnvironment;
+ private final int mEventCount;
+
+ public FlushExecutor(TestSensorEnvironment environment, int eventCount) {
+ mEnvironment = environment;
+ mEventCount = eventCount;
+ }
+
+ /**
+ * Consider only continuous mode sensors for testing register listener.
+ *
+ * For on-change sensors, we only use
+ * {@link TestSensorManager#registerListener(TestSensorEventListener)} to associate the
+ * listener with the sensor. So that {@link TestSensorManager#requestFlush()} can be
+ * invoked on it.
+ */
+ @Override
+ public void execute(TestSensorManager sensorManager, TestSensorEventListener listener)
+ throws InterruptedException {
+ int sensorReportingMode = mEnvironment.getSensor().getReportingMode();
+ try {
+ sensorManager.registerListener(listener);
+ if (sensorReportingMode == Sensor.REPORTING_MODE_CONTINUOUS) {
+ listener.waitForEvents(mEventCount);
+ }
+ sensorManager.requestFlush();
+ listener.waitForFlushComplete();
+ } finally {
+ sensorManager.unregisterListener();
+ }
+ }
+ }
+
+ private class NullTriggerEventListener extends TriggerEventListener {
+ @Override
+ public void onTrigger(TriggerEvent event) {}
+ }
+
+ private class NullSensorEventListener implements SensorEventListener {
+ @Override
+ public void onSensorChanged(SensorEvent event) {}
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {}
+ }
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
index 3bd4a03..a98dc59 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
@@ -541,7 +541,8 @@
sensorType,
shouldEmulateSensorUnderLoad(),
rateUs);
- TestSensorOperation op = new TestSensorOperation(environment, 5, TimeUnit.SECONDS);
+ TestSensorOperation op =
+ TestSensorOperation.createOperation(environment, 5, TimeUnit.SECONDS);
op.addDefaultVerifications();
op.setLogEvents(true);
try {
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java
index ca7d133..3bedc05 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java
@@ -17,7 +17,6 @@
package android.hardware.cts.helpers;
import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener2;
import java.util.ArrayList;
import java.util.Collections;
@@ -32,21 +31,6 @@
private final ArrayList<TestSensorEvent> mSensorEventsList = new ArrayList<TestSensorEvent>();
/**
- * Constructs a {@link CollectingSensorEventListener} with an additional
- * {@link SensorEventListener2}.
- */
- public CollectingSensorEventListener(SensorEventListener2 listener) {
- super(listener);
- }
-
- /**
- * Constructs a {@link CollectingSensorEventListener}.
- */
- public CollectingSensorEventListener() {
- this(null);
- }
-
- /**
* {@inheritDoc}
*/
@Override
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCalibratedUncalibratedVerifier.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCalibratedUncalibratedVerifier.java
index b3b8559..0f84ee6 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCalibratedUncalibratedVerifier.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCalibratedUncalibratedVerifier.java
@@ -51,7 +51,8 @@
*/
public void execute() throws Throwable {
CollectingSensorEventListener calibratedTestListener = new CollectingSensorEventListener();
- CollectingSensorEventListener uncalibratedTestListener = new CollectingSensorEventListener();
+ CollectingSensorEventListener uncalibratedTestListener =
+ new CollectingSensorEventListener();
mCalibratedSensorManager.registerListener(calibratedTestListener);
mUncalibratedSensorManager.registerListener(uncalibratedTestListener);
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
index a79e5b1b..e89b473 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
@@ -192,7 +192,7 @@
TestSensorEnvironment environment,
String extras) {
return String.format(
- "%s | sensor='%s', samplingPeriodUs=%d, maxReportLatencyUs=%d | %s",
+ "%s | sensor='%s', samplingPeriod=%dus, maxReportLatency=%dus | %s",
label,
environment.getSensor().getName(),
environment.getRequestedSamplingPeriodUs(),
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
index 7be6c0c..6f98e86 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
@@ -40,14 +40,15 @@
public class SensorStats {
public static final String DELIMITER = "__";
- public static final String FIRST_TIMESTAMP_KEY = "first_timestamp";
- public static final String LAST_TIMESTAMP_KEY = "last_timestamp";
public static final String ERROR = "error";
- public static final String EVENT_COUNT_KEY = "event_count";
public static final String EVENT_GAP_COUNT_KEY = "event_gap_count";
public static final String EVENT_GAP_POSITIONS_KEY = "event_gap_positions";
public static final String EVENT_OUT_OF_ORDER_COUNT_KEY = "event_out_of_order_count";
public static final String EVENT_OUT_OF_ORDER_POSITIONS_KEY = "event_out_of_order_positions";
+ public static final String EVENT_TIME_SYNCHRONIZATION_COUNT_KEY =
+ "event_time_synchronization_count";
+ public static final String EVENT_TIME_SYNCHRONIZATION_POSITIONS_KEY =
+ "event_time_synchronization_positions";
public static final String FREQUENCY_KEY = "frequency";
public static final String JITTER_95_PERCENTILE_PERCENT_KEY = "jitter_95_percentile_percent";
public static final String MEAN_KEY = "mean";
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
index 8f33f92..5be30a4 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
@@ -28,6 +28,13 @@
* The environment is self contained and carries its state around all the sensor test framework.
*/
public class TestSensorEnvironment {
+
+ /**
+ * It represents the fraction of the expected sampling frequency, at which the sensor can
+ * actually produce events.
+ */
+ private static final float MAXIMUM_EXPECTED_SAMPLING_FREQUENCY_MULTIPLIER = 0.9f;
+
private final Context mContext;
private final Sensor mSensor;
private final boolean mSensorMightHaveMoreListeners;
@@ -40,7 +47,10 @@
* @param context The context for the test
* @param sensorType The type of the sensor under test
* @param samplingPeriodUs The requested collection period for the sensor under test
+ *
+ * @deprecated Use variants with {@link Sensor} objects.
*/
+ @Deprecated
public TestSensorEnvironment(Context context, int sensorType, int samplingPeriodUs) {
this(context, sensorType, false /* sensorMightHaveMoreListeners */, samplingPeriodUs);
}
@@ -52,7 +62,10 @@
* @param sensorType The type of the sensor under test
* @param samplingPeriodUs The requested collection period for the sensor under test
* @param maxReportLatencyUs The requested collection report latency for the sensor under test
+ *
+ * @deprecated Use variants with {@link Sensor} objects.
*/
+ @Deprecated
public TestSensorEnvironment(
Context context,
int sensorType,
@@ -72,7 +85,10 @@
* @param sensorType The type of the sensor under test
* @param sensorMightHaveMoreListeners Whether the sensor under test is acting under load
* @param samplingPeriodUs The requested collection period for the sensor under test
+ *
+ * @deprecated Use variants with {@link Sensor} objects.
*/
+ @Deprecated
public TestSensorEnvironment(
Context context,
int sensorType,
@@ -93,7 +109,10 @@
* @param sensorMightHaveMoreListeners Whether the sensor under test is acting under load
* @param samplingPeriodUs The requested collection period for the sensor under test
* @param maxReportLatencyUs The requested collection report latency for the sensor under test
+ *
+ * @deprecated Use variants with {@link Sensor} objects.
*/
+ @Deprecated
public TestSensorEnvironment(
Context context,
int sensorType,
@@ -112,6 +131,26 @@
*
* @param context The context for the test
* @param sensor The sensor under test
+ * @param samplingPeriodUs The requested collection period for the sensor under test
+ * @param maxReportLatencyUs The requested collection report latency for the sensor under test
+ */
+ public TestSensorEnvironment(
+ Context context,
+ Sensor sensor,
+ int samplingPeriodUs,
+ int maxReportLatencyUs) {
+ this(context,
+ sensor,
+ false /* sensorMightHaveMoreListeners */,
+ samplingPeriodUs,
+ maxReportLatencyUs);
+ }
+
+ /**
+ * Constructs an environment for sensor testing.
+ *
+ * @param context The context for the test
+ * @param sensor The sensor under test
* @param sensorMightHaveMoreListeners Whether the sensor under test is acting under load (this
* usually implies that there are several listeners
* requesting different sampling periods)
@@ -171,7 +210,8 @@
* data at different sampling rates (the rates are unknown); false otherwise.
*/
public boolean isSensorSamplingRateOverloaded() {
- return mSensorMightHaveMoreListeners && mSamplingPeriodUs != SensorManager.SENSOR_DELAY_FASTEST;
+ return mSensorMightHaveMoreListeners
+ && mSamplingPeriodUs != SensorManager.SENSOR_DELAY_FASTEST;
}
/**
@@ -197,6 +237,15 @@
}
/**
+ * @return The actual sampling period at which a sensor can sample data. This value is a
+ * fraction of {@link #getExpectedSamplingPeriodUs()}.
+ */
+ public int getMaximumExpectedSamplingPeriodUs() {
+ int expectedSamplingPeriodUs = getExpectedSamplingPeriodUs();
+ return (int) (expectedSamplingPeriodUs / MAXIMUM_EXPECTED_SAMPLING_FREQUENCY_MULTIPLIER);
+ }
+
+ /**
* @return The number of axes in the coordinate system of the sensor under test.
*/
public int getSensorAxesCount() {
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
index 9b3a5e4..ae36e6a 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
@@ -21,9 +21,12 @@
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener2;
+import android.os.Handler;
+import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -36,13 +39,16 @@
*/
public class TestSensorEventListener implements SensorEventListener2 {
public static final String LOG_TAG = "TestSensorEventListener";
- private static final long EVENT_TIMEOUT_US = TimeUnit.MICROSECONDS.convert(5, TimeUnit.SECONDS);
- private static final long FLUSH_TIMEOUT_US = TimeUnit.MICROSECONDS.convert(5, TimeUnit.SECONDS);
+ private static final long EVENT_TIMEOUT_US = TimeUnit.SECONDS.toMicros(5);
+ private static final long FLUSH_TIMEOUT_US = TimeUnit.SECONDS.toMicros(10);
+
+ private final ArrayList<CountDownLatch> mEventLatches = new ArrayList<CountDownLatch>();
+ private final ArrayList<CountDownLatch> mFlushLatches = new ArrayList<CountDownLatch>();
private final SensorEventListener2 mListener;
+ private final Handler mHandler;
- private volatile CountDownLatch mEventLatch;
- private volatile CountDownLatch mFlushLatch = new CountDownLatch(1);
+ private volatile boolean mEventsReceivedInHandler = true;
private volatile TestSensorEnvironment mEnvironment;
private volatile boolean mLogEvents;
@@ -50,13 +56,28 @@
* Construct a {@link TestSensorEventListener}.
*/
public TestSensorEventListener() {
- this(null);
+ this(null /* listener */, null /* handler */);
+ }
+
+ /**
+ * Construct a {@link TestSensorEventListener} with a {@link Handler}.
+ */
+ public TestSensorEventListener(Handler handler) {
+ this(null /* listener */, handler);
}
/**
* Construct a {@link TestSensorEventListener} that wraps a {@link SensorEventListener2}.
*/
public TestSensorEventListener(SensorEventListener2 listener) {
+ this(listener, null /* handler */);
+ }
+
+ /**
+ * Construct a {@link TestSensorEventListener} that wraps a {@link SensorEventListener2}, and it
+ * has a {@link Handler}.
+ */
+ public TestSensorEventListener(SensorEventListener2 listener, Handler handler) {
if (listener != null) {
mListener = listener;
} else {
@@ -67,6 +88,14 @@
public void onAccuracyChanged(Sensor sensor, int i) {}
};
}
+ mHandler = handler;
+ }
+
+ /**
+ * @return The handler (if any) associated with the instance.
+ */
+ public Handler getHandler() {
+ return mHandler;
}
/**
@@ -88,6 +117,7 @@
*/
@Override
public void onSensorChanged(SensorEvent event) {
+ checkHandler();
mListener.onSensorChanged(event);
if (mLogEvents) {
Log.v(LOG_TAG, String.format(
@@ -98,9 +128,10 @@
Arrays.toString(event.values)));
}
- CountDownLatch eventLatch = mEventLatch;
- if(eventLatch != null) {
- eventLatch.countDown();
+ synchronized (mEventLatches) {
+ for (CountDownLatch latch : mEventLatches) {
+ latch.countDown();
+ }
}
}
@@ -109,6 +140,7 @@
*/
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ checkHandler();
mListener.onAccuracyChanged(sensor, accuracy);
}
@@ -117,12 +149,14 @@
*/
@Override
public void onFlushCompleted(Sensor sensor) {
- CountDownLatch latch = mFlushLatch;
- mFlushLatch = new CountDownLatch(1);
- if(latch != null) {
- latch.countDown();
- }
+ checkHandler();
mListener.onFlushCompleted(sensor);
+
+ synchronized (mFlushLatches) {
+ for (CountDownLatch latch : mFlushLatches) {
+ latch.countDown();
+ }
+ }
}
/**
@@ -131,13 +165,23 @@
* @throws AssertionError if there was a timeout after {@link #FLUSH_TIMEOUT_US} µs
*/
public void waitForFlushComplete() throws InterruptedException {
- CountDownLatch latch = mFlushLatch;
- if(latch == null) {
- return;
+ CountDownLatch latch = new CountDownLatch(1);
+ synchronized (mFlushLatches) {
+ mFlushLatches.add(latch);
}
- Assert.assertTrue(
- SensorCtsHelper.formatAssertionMessage("WaitForFlush", mEnvironment),
- latch.await(FLUSH_TIMEOUT_US, TimeUnit.MICROSECONDS));
+
+ try {
+ String message = SensorCtsHelper.formatAssertionMessage(
+ "WaitForFlush",
+ mEnvironment,
+ "timeout=%dus",
+ FLUSH_TIMEOUT_US);
+ Assert.assertTrue(message, latch.await(FLUSH_TIMEOUT_US, TimeUnit.MICROSECONDS));
+ } finally {
+ synchronized (mFlushLatches) {
+ mFlushLatches.remove(latch);
+ }
+ }
}
/**
@@ -146,22 +190,34 @@
* @throws AssertionError if there was a timeout after {@link #FLUSH_TIMEOUT_US} µs
*/
public void waitForEvents(int eventCount) throws InterruptedException {
- mEventLatch = new CountDownLatch(eventCount);
+ CountDownLatch eventLatch = new CountDownLatch(eventCount);
+ synchronized (mEventLatches) {
+ mEventLatches.add(eventLatch);
+ }
try {
- int rateUs = mEnvironment.getExpectedSamplingPeriodUs();
- // Timeout is 2 * event count * expected period + batch timeout + default wait
- long timeoutUs = (2 * eventCount * rateUs)
+ long samplingPeriodUs = mEnvironment.getMaximumExpectedSamplingPeriodUs();
+ // timeout is 2 * event count * expected period + batch timeout + default wait
+ // we multiply by two as not to raise an error in this function even if the events are
+ // streaming at a lower rate than expected, as long as it's not streaming twice as slow
+ // as expected
+ long timeoutUs = (2 * eventCount * samplingPeriodUs)
+ mEnvironment.getMaxReportLatencyUs()
+ EVENT_TIMEOUT_US;
- String message = SensorCtsHelper.formatAssertionMessage(
- "WaitForEvents",
- mEnvironment,
- "requested:%d, received:%d",
- eventCount,
- eventCount - mEventLatch.getCount());
- Assert.assertTrue(message, mEventLatch.await(timeoutUs, TimeUnit.MICROSECONDS));
+ boolean success = eventLatch.await(timeoutUs, TimeUnit.MICROSECONDS);
+ if (!success) {
+ String message = SensorCtsHelper.formatAssertionMessage(
+ "WaitForEvents",
+ mEnvironment,
+ "requested=%d, received=%d, timeout=%dus",
+ eventCount,
+ eventCount - eventLatch.getCount(),
+ timeoutUs);
+ Assert.fail(message);
+ }
} finally {
- mEventLatch = null;
+ synchronized (mEventLatches) {
+ mEventLatches.remove(eventLatch);
+ }
}
}
@@ -171,4 +227,22 @@
public void waitForEvents(long duration, TimeUnit timeUnit) throws InterruptedException {
SensorCtsHelper.sleep(duration, timeUnit);
}
+
+ /**
+ * Asserts that sensor events arrived in the proper thread if a {@link Handler} was associated
+ * with the current instance.
+ *
+ * If no events were received this assertion will be evaluated to {@code true}.
+ */
+ public void assertEventsReceivedInHandler() {
+ Assert.assertTrue(
+ "Events did not arrive in the Looper associated with the given Handler.",
+ mEventsReceivedInHandler);
+ }
+
+ private void checkHandler() {
+ if (mHandler != null) {
+ mEventsReceivedInHandler &= (mHandler.getLooper() == Looper.myLooper());
+ }
+ }
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
index dc40ff4..a611bfc 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
@@ -19,35 +19,18 @@
import junit.framework.Assert;
import android.content.Context;
-import android.hardware.Sensor;
import android.hardware.SensorEventListener;
-import android.hardware.SensorEventListener2;
import android.hardware.SensorManager;
import android.util.Log;
-import java.util.concurrent.TimeUnit;
-
/**
- * A test class that performs the actions of {@link SensorManager} on a single sensor. This
- * class allows for a single sensor to be registered and unregistered as well as performing
- * operations such as flushing the sensor events and gathering events. This class also manages
- * performing the test verifications for the sensor manager.
- * <p>
- * This class requires that operations are performed in the following order:
- * <p><ul>
- * <li>{@link #registerListener(TestSensorEventListener)}</li>
- * <li>{@link #startFlush()}, {@link #waitForFlushCompleted()}, or {@link #flush()}.
- * <li>{@link #unregisterListener()}</li>
- * </ul><p>Or:</p><ul>
- * <li>{@link #runSensor(TestSensorEventListener, int)}</li>
- * </ul><p>Or:</p><ul>
- * <li>{@link #runSensor(TestSensorEventListener, long, TimeUnit)}</li>
- * </ul><p>
- * If methods are called outside of this order, they will print a warning to the log and then
- * return. Both {@link #runSensor(TestSensorEventListener, int)}} and
- * {@link #runSensor(TestSensorEventListener, long, TimeUnit)} will perform the appropriate
- * set up and tear down.
- * <p>
+ * A test class that performs the actions of {@link SensorManager} on a single sensor.
+ * This class allows for a single sensor to be registered and unregistered as well as performing
+ * operations such as flushing the sensor events and gathering events.
+ * This class also manages performing the test verifications for the sensor manager.
+ *
+ * NOTE: this class is expected to mirror {@link SensorManager} operations, and perform the
+ * required test verifications along with them.
*/
public class TestSensorManager {
private static final String LOG_TAG = "TestSensorManager";
@@ -55,7 +38,7 @@
private final SensorManager mSensorManager;
private final TestSensorEnvironment mEnvironment;
- private TestSensorEventListener mTestSensorEventListener;
+ private volatile TestSensorEventListener mTestSensorEventListener;
/**
* @deprecated Use {@link #TestSensorManager(TestSensorEnvironment)} instead.
@@ -90,7 +73,7 @@
return;
}
- mTestSensorEventListener = listener != null ? listener : new TestSensorEventListener();
+ mTestSensorEventListener = listener;
mTestSensorEventListener.setEnvironment(mEnvironment);
String message = SensorCtsHelper.formatAssertionMessage("registerListener", mEnvironment);
@@ -98,7 +81,8 @@
mTestSensorEventListener,
mEnvironment.getSensor(),
mEnvironment.getRequestedSamplingPeriodUs(),
- mEnvironment.getMaxReportLatencyUs());
+ mEnvironment.getMaxReportLatencyUs(),
+ listener.getHandler());
Assert.assertTrue(message, result);
}
@@ -110,136 +94,24 @@
Log.w(LOG_TAG, "No listener registered, returning.");
return;
}
-
- mSensorManager.unregisterListener(
- mTestSensorEventListener,
- mEnvironment.getSensor());
+ mSensorManager.unregisterListener(mTestSensorEventListener, mEnvironment.getSensor());
+ mTestSensorEventListener.assertEventsReceivedInHandler();
mTestSensorEventListener = null;
}
/**
- * Wait for a specific number of events.
- */
- public void waitForEvents(int eventCount) throws InterruptedException {
- if (mTestSensorEventListener == null) {
- Log.w(LOG_TAG, "No listener registered, returning.");
- return;
- }
- mTestSensorEventListener.waitForEvents(eventCount);
- }
-
- /**
- * Wait for a specific duration.
- */
- public void waitForEvents(long duration, TimeUnit timeUnit) throws InterruptedException {
- if (mTestSensorEventListener == null) {
- Log.w(LOG_TAG, "No listener registered, returning.");
- return;
- }
- mTestSensorEventListener.waitForEvents(duration, timeUnit);
- }
-
- /**
* Call {@link SensorManager#flush(SensorEventListener)}. This method will perform a no-op if
* the sensor is not registered.
*
- * @throws AssertionError if {@link SensorManager#flush(SensorEventListener)} returns false
+ * @throws AssertionError if {@link SensorManager#flush(SensorEventListener)} fails.
*/
- public void startFlush() {
+ public void requestFlush() {
if (mTestSensorEventListener == null) {
+ Log.w(LOG_TAG, "No listener registered, returning.");
return;
}
-
Assert.assertTrue(
SensorCtsHelper.formatAssertionMessage("Flush", mEnvironment),
mSensorManager.flush(mTestSensorEventListener));
}
-
- /**
- * Wait for {@link SensorEventListener2#onFlushCompleted(Sensor)} to be called. This method will
- * perform a no-op if the sensor is not registered.
- *
- * @throws AssertionError if there is a time out
- * @throws InterruptedException if the thread was interrupted
- */
- public void waitForFlushCompleted() throws InterruptedException {
- if (mTestSensorEventListener == null) {
- return;
- }
- mTestSensorEventListener.waitForFlushComplete();
- }
-
- /**
- * Call {@link SensorManager#flush(SensorEventListener)} and wait for
- * {@link SensorEventListener2#onFlushCompleted(Sensor)} to be called. This method will perform
- * a no-op if the sensor is not registered.
- *
- * @throws AssertionError if {@link SensorManager#flush(SensorEventListener)} returns false or
- * if there is a time out
- * @throws InterruptedException if the thread was interrupted
- */
- public void flush() throws InterruptedException {
- if (mTestSensorEventListener == null) {
- return;
- }
- startFlush();
- waitForFlushCompleted();
- }
-
- /**
- * Register a listener, wait for a specific number of events, and then unregister the listener.
- */
- public void runSensor(TestSensorEventListener listener, int eventCount)
- throws InterruptedException {
- if (mTestSensorEventListener != null) {
- Log.w(LOG_TAG, "Listener already registered, returning.");
- return;
- }
- try {
- registerListener(listener);
- waitForEvents(eventCount);
- } finally {
- unregisterListener();
- }
- }
-
- /**
- * Register a listener, wait for a specific duration, and then unregister the listener.
- */
- public void runSensor(TestSensorEventListener listener, long duration, TimeUnit timeUnit)
- throws InterruptedException {
- if (mTestSensorEventListener != null) {
- Log.w(LOG_TAG, "Listener already registered, returning.");
- return;
- }
- try {
- registerListener(listener);
- waitForEvents(duration, timeUnit);
- } finally {
- unregisterListener();
- }
- }
-
- /**
- * Registers a listener, waits for a specific duration, calls flush, and waits for flush to
- * complete.
- */
- public void runSensorAndFlush(
- TestSensorEventListener listener,
- long duration,
- TimeUnit timeUnit) throws InterruptedException {
- if (mTestSensorEventListener != null) {
- Log.w(LOG_TAG, "Listener already registered, returning.");
- return;
- }
-
- try {
- registerListener(listener);
- SensorCtsHelper.sleep(duration, timeUnit);
- startFlush();
- listener.waitForFlushComplete();
- } finally {
- unregisterListener();
- }
- }
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java
index 299f470..7572dc7 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java
@@ -17,11 +17,11 @@
package android.hardware.cts.helpers;
import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener2;
import android.hardware.cts.helpers.sensorverification.ISensorVerification;
+import android.os.Handler;
+import java.util.ArrayList;
import java.util.Collection;
-import java.util.LinkedList;
/**
* A {@link TestSensorEventListener} which performs validations on the received events on the fly.
@@ -30,42 +30,17 @@
*/
public class ValidatingSensorEventListener extends TestSensorEventListener {
- private final Collection<ISensorVerification> mVerifications =
- new LinkedList<ISensorVerification>();
-
- /**
- * Construct a {@link ValidatingSensorEventListener} with an additional
- * {@link SensorEventListener2}.
- */
- public ValidatingSensorEventListener(SensorEventListener2 listener,
- ISensorVerification ... verifications) {
- super(listener);
- for (ISensorVerification verification : verifications) {
- mVerifications.add(verification);
- }
- }
-
- /**
- * Construct a {@link ValidatingSensorEventListener} with an additional
- * {@link SensorEventListener2}.
- */
- public ValidatingSensorEventListener(SensorEventListener2 listener,
- Collection<ISensorVerification> verifications) {
- this(listener, verifications.toArray(new ISensorVerification[0]));
- }
+ private final ArrayList<ISensorVerification> mVerifications =
+ new ArrayList<ISensorVerification>();
/**
* Construct a {@link ValidatingSensorEventListener}.
*/
- public ValidatingSensorEventListener(ISensorVerification ... verifications) {
- this(null, verifications);
- }
-
- /**
- * Construct a {@link ValidatingSensorEventListener}.
- */
- public ValidatingSensorEventListener(Collection<ISensorVerification> verifications) {
- this(null, verifications);
+ public ValidatingSensorEventListener(
+ Collection<ISensorVerification> verifications,
+ Handler handler) {
+ super(handler);
+ mVerifications.addAll(verifications);
}
/**
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorFlushOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorFlushOperation.java
deleted file mode 100644
index d5aa4b9..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorFlushOperation.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2014 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.hardware.cts.helpers.sensoroperations;
-
-import android.hardware.cts.helpers.TestSensorEnvironment;
-import android.hardware.cts.helpers.TestSensorEventListener;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * A {@link ISensorOperation} used to verify that sensor events and sensor values are correct.
- * <p>
- * Provides methods to set test expectations as well as providing a set of default expectations
- * depending on sensor type. When {{@link #execute()} is called, the sensor will collect the
- * events, call flush, and then run all the tests.
- * </p>
- */
-public class TestSensorFlushOperation extends VerifiableSensorOperation {
- private final Long mDuration;
- private final TimeUnit mTimeUnit;
-
- /**
- * Create a {@link TestSensorOperation}.
- *
- * @param environment the test environment
- * @param duration the duration to gather events before calling {@code SensorManager.flush()}
- * @param timeUnit the time unit of the duration
- */
- public TestSensorFlushOperation(
- TestSensorEnvironment environment,
- long duration,
- TimeUnit timeUnit) {
- super(environment);
- mDuration = duration;
- mTimeUnit = timeUnit;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void doExecute(TestSensorEventListener listener) throws InterruptedException {
- mSensorManager.runSensorAndFlush(listener, mDuration, mTimeUnit);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected VerifiableSensorOperation doClone() {
- return new TestSensorFlushOperation(mEnvironment, mDuration,mTimeUnit);
- }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
index 695e1a7..6e53dbb 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
@@ -16,9 +16,27 @@
package android.hardware.cts.helpers.sensoroperations;
+import junit.framework.Assert;
+
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorStats;
import android.hardware.cts.helpers.TestSensorEnvironment;
import android.hardware.cts.helpers.TestSensorEventListener;
+import android.hardware.cts.helpers.TestSensorManager;
+import android.hardware.cts.helpers.ValidatingSensorEventListener;
+import android.hardware.cts.helpers.sensorverification.EventGapVerification;
+import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
+import android.hardware.cts.helpers.sensorverification.EventTimestampSynchronizationVerification;
+import android.hardware.cts.helpers.sensorverification.FrequencyVerification;
+import android.hardware.cts.helpers.sensorverification.ISensorVerification;
+import android.hardware.cts.helpers.sensorverification.JitterVerification;
+import android.hardware.cts.helpers.sensorverification.MagnitudeVerification;
+import android.hardware.cts.helpers.sensorverification.MeanVerification;
+import android.hardware.cts.helpers.sensorverification.StandardDeviationVerification;
+import android.os.Handler;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.concurrent.TimeUnit;
/**
@@ -29,70 +47,204 @@
* events and then run all the tests.
* </p>
*/
-public class TestSensorOperation extends VerifiableSensorOperation {
- private final Integer mEventCount;
- private final Long mDuration;
- private final TimeUnit mTimeUnit;
+public class TestSensorOperation extends AbstractSensorOperation {
+ private final Collection<ISensorVerification> mVerifications =
+ new HashSet<ISensorVerification>();
+
+ private final TestSensorManager mSensorManager;
+ private final TestSensorEnvironment mEnvironment;
+ private final Executor mExecutor;
+ private final Handler mHandler;
+
+ private boolean mLogEvents;
/**
- * Create a {@link TestSensorOperation}.
- *
- * @param environment the test environment
- * @param eventCount the number of events to gather
+ * An interface that defines an abstraction for operations to be performed by the
+ * {@link TestSensorOperation}.
*/
- public TestSensorOperation(TestSensorEnvironment environment, int eventCount) {
- this(environment, eventCount, null /* duration */, null /* timeUnit */);
+ public interface Executor {
+ void execute(TestSensorManager sensorManager, TestSensorEventListener listener)
+ throws InterruptedException;
}
/**
* Create a {@link TestSensorOperation}.
- *
- * @param environment the test environment
- * @param duration the duration to gather events for
- * @param timeUnit the time unit of the duration
+ */
+ public TestSensorOperation(TestSensorEnvironment environment, Executor executor) {
+ this(environment, executor, null /* handler */);
+ }
+
+ /**
+ * Create a {@link TestSensorOperation}.
*/
public TestSensorOperation(
TestSensorEnvironment environment,
- long duration,
- TimeUnit timeUnit) {
- this(environment, null /* eventCount */, duration, timeUnit);
+ Executor executor,
+ Handler handler) {
+ mEnvironment = environment;
+ mExecutor = executor;
+ mHandler = handler;
+ mSensorManager = new TestSensorManager(mEnvironment);
}
/**
- * Private helper constructor.
+ * Set whether to log events.
*/
- private TestSensorOperation(
+ public void setLogEvents(boolean logEvents) {
+ mLogEvents = logEvents;
+ }
+
+ /**
+ * Set all of the default test expectations.
+ */
+ public void addDefaultVerifications() {
+ addVerification(EventGapVerification.getDefault(mEnvironment));
+ addVerification(EventOrderingVerification.getDefault(mEnvironment));
+ addVerification(FrequencyVerification.getDefault(mEnvironment));
+ addVerification(JitterVerification.getDefault(mEnvironment));
+ addVerification(MagnitudeVerification.getDefault(mEnvironment));
+ addVerification(MeanVerification.getDefault(mEnvironment));
+ addVerification(StandardDeviationVerification.getDefault(mEnvironment));
+ addVerification(EventTimestampSynchronizationVerification.getDefault(mEnvironment));
+ }
+
+ public void addVerification(ISensorVerification verification) {
+ if (verification != null) {
+ mVerifications.add(verification);
+ }
+ }
+
+ /**
+ * Collect the specified number of events from the sensor and run all enabled verifications.
+ */
+ @Override
+ public void execute() throws InterruptedException {
+ getStats().addValue("sensor_name", mEnvironment.getSensor().getName());
+
+ ValidatingSensorEventListener listener =
+ new ValidatingSensorEventListener(mVerifications, mHandler);
+ listener.setLogEvents(mLogEvents);
+
+ mExecutor.execute(mSensorManager, listener);
+
+ boolean failed = false;
+ StringBuilder sb = new StringBuilder();
+ for (ISensorVerification verification : mVerifications) {
+ failed |= evaluateResults(verification, sb);
+ }
+
+ if (failed) {
+ String msg = SensorCtsHelper
+ .formatAssertionMessage("VerifySensorOperation", mEnvironment, sb.toString());
+ getStats().addValue(SensorStats.ERROR, msg);
+ Assert.fail(msg);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public TestSensorOperation clone() {
+ TestSensorOperation operation = new TestSensorOperation(mEnvironment, mExecutor);
+ for (ISensorVerification verification : mVerifications) {
+ operation.addVerification(verification.clone());
+ }
+ return operation;
+ }
+
+ /**
+ * Evaluate the results of a test, aggregate the stats, and build the error message.
+ */
+ private boolean evaluateResults(ISensorVerification verification, StringBuilder sb) {
+ try {
+ verification.verify(mEnvironment, getStats());
+ } catch (AssertionError e) {
+ if (sb.length() > 0) {
+ sb.append(", ");
+ }
+ sb.append(e.getMessage());
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Creates an operation that will wait for a given amount of events to arrive.
+ *
+ * @param environment The test environment.
+ * @param eventCount The number of events to wait for.
+ */
+ public static TestSensorOperation createOperation(
TestSensorEnvironment environment,
- Integer eventCount,
- Long duration,
- TimeUnit timeUnit) {
- super(environment);
- mEventCount = eventCount;
- mDuration = duration;
- mTimeUnit = timeUnit;
+ final int eventCount) {
+ Executor executor = new Executor() {
+ @Override
+ public void execute(TestSensorManager sensorManager, TestSensorEventListener listener)
+ throws InterruptedException {
+ try {
+ sensorManager.registerListener(listener);
+ listener.waitForEvents(eventCount);
+ } finally {
+ sensorManager.unregisterListener();
+ }
+ }
+ };
+ return new TestSensorOperation(environment, executor);
}
/**
- * {@inheritDoc}
+ * Creates an operation that will wait for a given amount of time to collect events.
+ *
+ * @param environment The test environment.
+ * @param duration The duration to wait for events.
+ * @param timeUnit The time unit for {@code duration}.
*/
- @Override
- protected void doExecute(TestSensorEventListener listener) throws InterruptedException {
- if (mEventCount != null) {
- mSensorManager.runSensor(listener, mEventCount);
- } else {
- mSensorManager.runSensor(listener, mDuration, mTimeUnit);
- }
+ public static TestSensorOperation createOperation(
+ TestSensorEnvironment environment,
+ final long duration,
+ final TimeUnit timeUnit) {
+ Executor executor = new Executor() {
+ @Override
+ public void execute(TestSensorManager sensorManager, TestSensorEventListener listener)
+ throws InterruptedException {
+ try {
+ sensorManager.registerListener(listener);
+ listener.waitForEvents(duration, timeUnit);
+ } finally {
+ sensorManager.unregisterListener();
+ }
+ }
+ };
+ return new TestSensorOperation(environment, executor);
}
/**
- * {@inheritDoc}
+ * Creates an operation that will wait for a given amount of time before calling
+ * {@link TestSensorManager#requestFlush()}.
+ *
+ * @param environment The test environment.
+ * @param duration The duration to wait before calling {@link TestSensorManager#requestFlush()}.
+ * @param timeUnit The time unit for {@code duration}.
*/
- @Override
- protected VerifiableSensorOperation doClone() {
- if (mEventCount != null) {
- return new TestSensorOperation(mEnvironment, mEventCount);
- } else {
- return new TestSensorOperation(mEnvironment, mDuration, mTimeUnit);
- }
+ public static TestSensorOperation createFlushOperation(
+ TestSensorEnvironment environment,
+ final long duration,
+ final TimeUnit timeUnit) {
+ Executor executor = new Executor() {
+ @Override
+ public void execute(TestSensorManager sensorManager, TestSensorEventListener listener)
+ throws InterruptedException {
+ try {
+ sensorManager.registerListener(listener);
+ SensorCtsHelper.sleep(duration, timeUnit);
+ sensorManager.requestFlush();
+ listener.waitForFlushComplete();
+ } finally {
+ sensorManager.unregisterListener();
+ }
+ }
+ };
+ return new TestSensorOperation(environment, executor);
}
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/VerifiableSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/VerifiableSensorOperation.java
deleted file mode 100644
index 57018eb..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/VerifiableSensorOperation.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2014 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.hardware.cts.helpers.sensoroperations;
-
-import junit.framework.Assert;
-
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorStats;
-import android.hardware.cts.helpers.TestSensorEnvironment;
-import android.hardware.cts.helpers.TestSensorEventListener;
-import android.hardware.cts.helpers.TestSensorManager;
-import android.hardware.cts.helpers.ValidatingSensorEventListener;
-import android.hardware.cts.helpers.sensorverification.EventGapVerification;
-import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
-import android.hardware.cts.helpers.sensorverification.FrequencyVerification;
-import android.hardware.cts.helpers.sensorverification.ISensorVerification;
-import android.hardware.cts.helpers.sensorverification.JitterVerification;
-import android.hardware.cts.helpers.sensorverification.MagnitudeVerification;
-import android.hardware.cts.helpers.sensorverification.MeanVerification;
-import android.hardware.cts.helpers.sensorverification.StandardDeviationVerification;
-
-import java.util.Collection;
-import java.util.HashSet;
-
-/**
- * A {@link ISensorOperation} used to verify that sensor events and sensor values are correct.
- * <p>
- * Provides methods to set test expectations as well as providing a set of default expectations
- * depending on sensor type. When {{@link #execute()} is called, the sensor will collect the
- * events and then run all the tests.
- * </p>
- */
-public abstract class VerifiableSensorOperation extends AbstractSensorOperation {
- protected final TestSensorManager mSensorManager;
- protected final TestSensorEnvironment mEnvironment;
-
- private final Collection<ISensorVerification> mVerifications =
- new HashSet<ISensorVerification>();
-
- private boolean mLogEvents = false;
-
- /**
- * Create a {@link TestSensorOperation}.
- *
- * @param environment the test environment
- */
- public VerifiableSensorOperation(TestSensorEnvironment environment) {
- mEnvironment = environment;
- mSensorManager = new TestSensorManager(mEnvironment);
- }
-
- /**
- * Set whether to log events.
- */
- public void setLogEvents(boolean logEvents) {
- mLogEvents = logEvents;
- }
-
- /**
- * Set all of the default test expectations.
- */
- public void addDefaultVerifications() {
- addVerification(EventGapVerification.getDefault(mEnvironment));
- addVerification(EventOrderingVerification.getDefault(mEnvironment));
- addVerification(FrequencyVerification.getDefault(mEnvironment));
- addVerification(JitterVerification.getDefault(mEnvironment));
- addVerification(MagnitudeVerification.getDefault(mEnvironment));
- addVerification(MeanVerification.getDefault(mEnvironment));
- // Skip SigNumVerification since it has no default
- addVerification(StandardDeviationVerification.getDefault(mEnvironment));
- }
-
- public void addVerification(ISensorVerification verification) {
- if (verification != null) {
- mVerifications.add(verification);
- }
- }
-
- /**
- * Collect the specified number of events from the sensor and run all enabled verifications.
- */
- @Override
- public void execute() throws InterruptedException {
- getStats().addValue("sensor_name", mEnvironment.getSensor().getName());
-
- ValidatingSensorEventListener listener = new ValidatingSensorEventListener(mVerifications);
- listener.setLogEvents(mLogEvents);
-
- doExecute(listener);
-
- boolean failed = false;
- StringBuilder sb = new StringBuilder();
- for (ISensorVerification verification : mVerifications) {
- failed |= evaluateResults(verification, sb);
- }
-
- if (failed) {
- String msg = SensorCtsHelper
- .formatAssertionMessage("VerifySensorOperation", mEnvironment, sb.toString());
- getStats().addValue(SensorStats.ERROR, msg);
- Assert.fail(msg);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public VerifiableSensorOperation clone() {
- VerifiableSensorOperation operation = doClone();
- for (ISensorVerification verification : mVerifications) {
- operation.addVerification(verification.clone());
- }
- return operation;
- }
-
- /**
- * Execute operations in a {@link TestSensorManager}.
- */
- protected abstract void doExecute(TestSensorEventListener listener) throws InterruptedException;
-
- /**
- * Clone the subclass operation.
- */
- protected abstract VerifiableSensorOperation doClone();
-
- /**
- * Evaluate the results of a test, aggregate the stats, and build the error message.
- */
- private boolean evaluateResults(ISensorVerification verification, StringBuilder sb) {
- try {
- verification.verify(mEnvironment, getStats());
- } catch (AssertionError e) {
- if (sb.length() > 0) {
- sb.append(", ");
- }
- sb.append(e.getMessage());
- return true;
- }
- return false;
- }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
index 911ae3a..acf71bb 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
@@ -18,6 +18,8 @@
import android.hardware.cts.helpers.TestSensorEvent;
+import java.util.List;
+
/**
* Abstract class that deals with the synchronization of the sensor verifications.
*/
@@ -52,18 +54,38 @@
*/
protected abstract void addSensorEventInternal(TestSensorEvent event);
+ protected <TEvent extends IndexedEvent> int[] getIndexArray(List<TEvent> indexedEvents) {
+ int eventsCount = indexedEvents.size();
+ int[] indices = new int[eventsCount];
+ for (int i = 0; i < eventsCount; i++) {
+ indices[i] = indexedEvents.get(i).index;
+ }
+ return indices;
+ }
+
+ /**
+ * Helper class to store the index and current event.
+ * Events are added to the verification in the order they are generated, the index represents
+ * the position of the given event, in the list of added events.
+ */
+ protected class IndexedEvent {
+ public final int index;
+ public final TestSensorEvent event;
+
+ public IndexedEvent(int index, TestSensorEvent event) {
+ this.index = index;
+ this.event = event;
+ }
+ }
+
/**
* Helper class to store the index, previous event, and current event.
*/
- protected class IndexedEventPair {
- public final int index;
- public final TestSensorEvent event;
+ protected class IndexedEventPair extends IndexedEvent {
public final TestSensorEvent previousEvent;
- public IndexedEventPair(int index, TestSensorEvent event,
- TestSensorEvent previousEvent) {
- this.index = index;
- this.event = event;
+ public IndexedEventPair(int index, TestSensorEvent event, TestSensorEvent previousEvent) {
+ super(index, event);
this.previousEvent = previousEvent;
}
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
index 156afa8..b692f0f 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
@@ -63,19 +63,14 @@
public void verify(TestSensorEnvironment environment, SensorStats stats) {
if (environment.isSensorSamplingRateOverloaded()) {
// the verification is not reliable on environments under load
- stats.addValue(PASSED_KEY, true);
+ stats.addValue(PASSED_KEY, "skipped (under load)");
return;
}
final int count = mEventGaps.size();
stats.addValue(PASSED_KEY, count == 0);
stats.addValue(SensorStats.EVENT_GAP_COUNT_KEY, count);
-
- final int[] indices = new int[count];
- for (int i = 0; i < indices.length; i++) {
- indices[i] = mEventGaps.get(i).index;
- }
- stats.addValue(SensorStats.EVENT_GAP_POSITIONS_KEY, indices);
+ stats.addValue(SensorStats.EVENT_GAP_POSITIONS_KEY, getIndexArray(mEventGaps));
if (count > 0) {
StringBuilder sb = new StringBuilder();
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
index 6598725..7b77ead 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
@@ -75,12 +75,9 @@
final int count = mOutOfOrderEvents.size();
stats.addValue(PASSED_KEY, count == 0);
stats.addValue(SensorStats.EVENT_OUT_OF_ORDER_COUNT_KEY, count);
-
- final int[] indices = new int[count];
- for (int i = 0; i < indices.length; i++) {
- indices[i] = mOutOfOrderEvents.get(i).index;
- }
- stats.addValue(SensorStats.EVENT_OUT_OF_ORDER_POSITIONS_KEY, indices);
+ stats.addValue(
+ SensorStats.EVENT_OUT_OF_ORDER_POSITIONS_KEY,
+ getIndexArray(mOutOfOrderEvents));
if (count > 0) {
StringBuilder sb = new StringBuilder();
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventTimestampSynchronizationVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventTimestampSynchronizationVerification.java
new file mode 100644
index 0000000..d4a1f38
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventTimestampSynchronizationVerification.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2014 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.hardware.cts.helpers.sensorverification;
+
+import junit.framework.Assert;
+
+import android.hardware.SensorEvent;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEvent;
+import android.os.SystemClock;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorVerification} which verifies that the timestamp of the {@link SensorEvent} is
+ * synchronized with {@link SystemClock#elapsedRealtimeNanos()}, based on a given threshold.
+ */
+public class EventTimestampSynchronizationVerification extends AbstractSensorVerification {
+ public static final String PASSED_KEY = "timestamp_synchronization_passed";
+
+ // number of indices to print in assertion message before truncating
+ private static final int TRUNCATE_MESSAGE_LENGTH = 3;
+
+ private static final long DEFAULT_THRESHOLD_NS = TimeUnit.MILLISECONDS.toNanos(500);
+
+ private final ArrayList<TestSensorEvent> mCollectedEvents = new ArrayList<TestSensorEvent>();
+
+ private final long mMaximumSynchronizationErrorNs;
+ private final long mReportLatencyNs;
+
+ /**
+ * Constructs an instance of {@link EventTimestampSynchronizationVerification}.
+ *
+ * @param maximumSynchronizationErrorNs The valid threshold for timestamp synchronization.
+ * @param reportLatencyNs The latency on which batching events are received
+ */
+ public EventTimestampSynchronizationVerification(
+ long maximumSynchronizationErrorNs,
+ long reportLatencyNs) {
+ mMaximumSynchronizationErrorNs = maximumSynchronizationErrorNs;
+ mReportLatencyNs = reportLatencyNs;
+ }
+
+ /**
+ * Gets a default {@link EventTimestampSynchronizationVerification}.
+ *
+ * @param environment The test environment
+ * @return The verification or null if the verification is not supported in the given
+ * environment.
+ */
+ public static EventTimestampSynchronizationVerification getDefault(
+ TestSensorEnvironment environment) {
+ int reportLatencyUs = environment.getMaxReportLatencyUs();
+ int fifoMaxEventCount = environment.getSensor().getFifoMaxEventCount();
+ if (fifoMaxEventCount > 0) {
+ int fifoBasedReportLatencyUs =
+ fifoMaxEventCount * environment.getMaximumExpectedSamplingPeriodUs();
+ reportLatencyUs = Math.min(reportLatencyUs, fifoBasedReportLatencyUs);
+
+ }
+ long reportLatencyNs = TimeUnit.MICROSECONDS.toNanos(reportLatencyUs);
+ return new EventTimestampSynchronizationVerification(DEFAULT_THRESHOLD_NS, reportLatencyNs);
+ }
+
+ @Override
+ public void verify(TestSensorEnvironment environment, SensorStats stats) {
+ StringBuilder errorMessageBuilder =
+ new StringBuilder(" event timestamp synchronization failures: ");
+ List<IndexedEvent> failures = verifyTimestampSynchronization(errorMessageBuilder);
+
+ int failuresCount = failures.size();
+ stats.addValue(SensorStats.EVENT_TIME_SYNCHRONIZATION_COUNT_KEY, failuresCount);
+ stats.addValue(
+ SensorStats.EVENT_TIME_SYNCHRONIZATION_POSITIONS_KEY,
+ getIndexArray(failures));
+
+ boolean success = failures.isEmpty();
+ stats.addValue(PASSED_KEY, success);
+ errorMessageBuilder.insert(0, failuresCount);
+ Assert.assertTrue(errorMessageBuilder.toString(), success);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public EventTimestampSynchronizationVerification clone() {
+ return new EventTimestampSynchronizationVerification(
+ mMaximumSynchronizationErrorNs,
+ mReportLatencyNs);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void addSensorEventInternal(TestSensorEvent event) {
+ mCollectedEvents.add(event);
+ }
+
+ /**
+ * Verifies timestamp synchronization for all sensor events.
+ * The verification accounts for a lower and upper threshold, such thresholds are adjusted for
+ * batching cases.
+ *
+ * @param builder A string builder to store error messaged found in the collected sensor events.
+ * @return A list of events tha failed the verification.
+ */
+ private List<IndexedEvent> verifyTimestampSynchronization(StringBuilder builder) {
+ int collectedEventsCount = mCollectedEvents.size();
+ ArrayList<IndexedEvent> failures = new ArrayList<IndexedEvent>();
+
+ for (int i = 0; i < collectedEventsCount; ++i) {
+ TestSensorEvent event = mCollectedEvents.get(i);
+ long eventTimestampNs = event.timestamp;
+ long receivedTimestampNs = event.receivedTimestamp;
+ long upperThresholdNs = receivedTimestampNs;
+ long lowerThresholdNs = receivedTimestampNs - mMaximumSynchronizationErrorNs
+ - mReportLatencyNs;
+
+ if (eventTimestampNs < lowerThresholdNs || eventTimestampNs > upperThresholdNs) {
+ if (failures.size() < TRUNCATE_MESSAGE_LENGTH) {
+ builder.append("position=").append(i);
+ builder.append(", timestamp=").append(eventTimestampNs).append("ns");
+ builder.append(", expected=[").append(lowerThresholdNs);
+ builder.append(", ").append(upperThresholdNs).append("]ns; ");
+ }
+ failures.add(new IndexedEvent(i, event));
+ }
+ }
+ if (failures.size() >= TRUNCATE_MESSAGE_LENGTH) {
+ builder.append("more; ");
+ }
+ return failures;
+ }
+}
diff --git a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
index 3765809..b298b97 100644
--- a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
+++ b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
@@ -26,6 +26,7 @@
import android.location.Criteria;
import android.location.GpsStatus;
import android.location.GpsStatus.Listener;
+import android.location.GpsStatus.NmeaListener;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
@@ -227,18 +228,32 @@
@UiThreadTest
public void testGpsStatusListener() {
try {
- // .addGpsStatusListener returns true if the listener added successfully
- if (mManager.addGpsStatusListener(new MockGpsStatusListener())) {
- fail("Should have failed to add a gps status listener");
- }
+ mManager.addGpsStatusListener(new MockGpsStatusListener());
+ fail("Should have failed to add a gps status listener");
} catch (SecurityException e) {
// expected
}
try {
- if (mManager.addGpsStatusListener(null)) {
- fail("Should have failed to add null as a gps status listener");
- }
+ mManager.addGpsStatusListener(null);
+ fail("Should have failed to add null as a gps status listener");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @UiThreadTest
+ public void testGpsStatusNmeaListener() {
+ try {
+ mManager.addNmeaListener(new MockGpsStatusNmeaListener());
+ fail("Should have failed to add a gps status nmea listener");
+ } catch (SecurityException e) {
+ // expected
+ }
+
+ try {
+ mManager.addNmeaListener(null);
+ fail("Should have failed to add null as a gps status nmea listener");
} catch (SecurityException e) {
// expected
}
@@ -478,4 +493,20 @@
mHasCallOnGpsStatusChanged = true;
}
}
+
+ private static class MockGpsStatusNmeaListener implements NmeaListener {
+ private boolean mHasCallOnNmeaReceived;
+
+ public boolean hasCallOnNmeaReceived() {
+ return mHasCallOnNmeaReceived;
+ }
+
+ public void reset(){
+ mHasCallOnNmeaReceived = false;
+ }
+
+ public void onNmeaReceived(long timestamp, String nmea) {
+ mHasCallOnNmeaReceived = true;
+ }
+ }
}
diff --git a/tests/tests/media/libmediandkjni/Android.mk b/tests/tests/media/libmediandkjni/Android.mk
index 2d2033f..59ff7bb 100644
--- a/tests/tests/media/libmediandkjni/Android.mk
+++ b/tests/tests/media/libmediandkjni/Android.mk
@@ -20,7 +20,9 @@
LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := native-media-jni.cpp
+LOCAL_SRC_FILES := \
+ native-media-jni.cpp \
+ codec-utils-jni.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
diff --git a/tests/tests/media/libmediandkjni/codec-utils-jni.cpp b/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
new file mode 100644
index 0000000..f99f1c8
--- /dev/null
+++ b/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2014 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.
+ */
+
+/* Original code copied from NDK Native-media sample code */
+
+#undef NDEBUG
+//#define LOG_NDEBUG 0
+#include <stdint.h>
+#include <sys/types.h>
+#include <jni.h>
+
+#include <ScopedLocalRef.h>
+#include <JNIHelp.h>
+
+typedef ssize_t offs_t;
+
+// for __android_log_print(ANDROID_LOG_INFO, "YourApp", "formatted message");
+#include <android/log.h>
+#define TAG "CodecUtilsJNI"
+#define __ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
+#if LOG_NDEBUG
+#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0)
+#else
+#define ALOGV(...) __ALOGV(__VA_ARGS__)
+#endif
+#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
+#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
+#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
+
+struct NativeImage {
+ struct crop {
+ int left;
+ int top;
+ int right;
+ int bottom;
+ } crop;
+ struct plane {
+ const uint8_t *buffer;
+ size_t size;
+ ssize_t colInc;
+ ssize_t rowInc;
+ offs_t cropOffs;
+ size_t cropWidth;
+ size_t cropHeight;
+ } plane[3];
+ int width;
+ int height;
+ int format;
+ long timestamp;
+ size_t numPlanes;
+};
+
+struct ChecksumAlg {
+ virtual void init() = 0;
+ virtual void update(uint8_t c) = 0;
+ virtual uint32_t checksum() = 0;
+ virtual size_t length() = 0;
+protected:
+ virtual ~ChecksumAlg() {}
+};
+
+struct Adler32 : ChecksumAlg {
+ Adler32() {
+ init();
+ }
+ void init() {
+ a = 1;
+ len = b = 0;
+ }
+ void update(uint8_t c) {
+ a += c;
+ b += a;
+ ++len;
+ }
+ uint32_t checksum() {
+ return (a % 65521) + ((b % 65521) << 16);
+ }
+ size_t length() {
+ return len;
+ }
+private:
+ uint32_t a, b;
+ size_t len;
+};
+
+static struct ImageFieldsAndMethods {
+ // android.graphics.ImageFormat
+ int YUV_420_888;
+ // android.media.Image
+ jmethodID methodWidth;
+ jmethodID methodHeight;
+ jmethodID methodFormat;
+ jmethodID methodTimestamp;
+ jmethodID methodPlanes;
+ jmethodID methodCrop;
+ // android.media.Image.Plane
+ jmethodID methodBuffer;
+ jmethodID methodPixelStride;
+ jmethodID methodRowStride;
+ // android.graphics.Rect
+ jfieldID fieldLeft;
+ jfieldID fieldTop;
+ jfieldID fieldRight;
+ jfieldID fieldBottom;
+} gFields;
+static bool gFieldsInitialized = false;
+
+void initializeGlobalFields(JNIEnv *env) {
+ if (gFieldsInitialized) {
+ return;
+ }
+ { // ImageFormat
+ jclass imageFormatClazz = env->FindClass("android/graphics/ImageFormat");
+ const jfieldID fieldYUV420888 = env->GetStaticFieldID(imageFormatClazz, "YUV_420_888", "I");
+ gFields.YUV_420_888 = env->GetStaticIntField(imageFormatClazz, fieldYUV420888);
+ env->DeleteLocalRef(imageFormatClazz);
+ imageFormatClazz = NULL;
+ }
+
+ { // Image
+ jclass imageClazz = env->FindClass("android/media/Image");
+ gFields.methodWidth = env->GetMethodID(imageClazz, "getWidth", "()I");
+ gFields.methodHeight = env->GetMethodID(imageClazz, "getHeight", "()I");
+ gFields.methodFormat = env->GetMethodID(imageClazz, "getFormat", "()I");
+ gFields.methodTimestamp = env->GetMethodID(imageClazz, "getTimestamp", "()J");
+ gFields.methodPlanes = env->GetMethodID(
+ imageClazz, "getPlanes", "()[Landroid/media/Image$Plane;");
+ gFields.methodCrop = env->GetMethodID(
+ imageClazz, "getCropRect", "()Landroid/graphics/Rect;");
+ env->DeleteLocalRef(imageClazz);
+ imageClazz = NULL;
+ }
+
+ { // Image.Plane
+ jclass planeClazz = env->FindClass("android/media/Image$Plane");
+ gFields.methodBuffer = env->GetMethodID(planeClazz, "getBuffer", "()Ljava/nio/ByteBuffer;");
+ gFields.methodPixelStride = env->GetMethodID(planeClazz, "getPixelStride", "()I");
+ gFields.methodRowStride = env->GetMethodID(planeClazz, "getRowStride", "()I");
+ env->DeleteLocalRef(planeClazz);
+ planeClazz = NULL;
+ }
+
+ { // Rect
+ jclass rectClazz = env->FindClass("android/graphics/Rect");
+ gFields.fieldLeft = env->GetFieldID(rectClazz, "left", "I");
+ gFields.fieldTop = env->GetFieldID(rectClazz, "top", "I");
+ gFields.fieldRight = env->GetFieldID(rectClazz, "right", "I");
+ gFields.fieldBottom = env->GetFieldID(rectClazz, "bottom", "I");
+ env->DeleteLocalRef(rectClazz);
+ rectClazz = NULL;
+ }
+ gFieldsInitialized = true;
+}
+
+NativeImage *getNativeImage(JNIEnv *env, jobject image) {
+ if (image == NULL) {
+ jniThrowNullPointerException(env, "image is null");
+ return NULL;
+ }
+
+ initializeGlobalFields(env);
+
+ NativeImage *img = new NativeImage;
+ img->format = env->CallIntMethod(image, gFields.methodFormat);
+ img->width = env->CallIntMethod(image, gFields.methodWidth);
+ img->height = env->CallIntMethod(image, gFields.methodHeight);
+ img->timestamp = env->CallLongMethod(image, gFields.methodTimestamp);
+
+ jobject cropRect = env->CallObjectMethod(image, gFields.methodCrop);
+ img->crop.left = env->GetIntField(cropRect, gFields.fieldLeft);
+ img->crop.top = env->GetIntField(cropRect, gFields.fieldTop);
+ img->crop.right = env->GetIntField(cropRect, gFields.fieldRight);
+ img->crop.bottom = env->GetIntField(cropRect, gFields.fieldBottom);
+ if (img->crop.right == 0 && img->crop.bottom == 0) {
+ img->crop.right = img->width;
+ img->crop.bottom = img->height;
+ }
+ env->DeleteLocalRef(cropRect);
+ cropRect = NULL;
+
+ if (img->format != gFields.YUV_420_888) {
+ jniThrowException(
+ env, "java/lang/UnsupportedOperationException",
+ "only support YUV_420_888 images");
+ delete img;
+ img = NULL;
+ return NULL;
+ }
+ img->numPlanes = 3;
+
+ ScopedLocalRef<jobjectArray> planesArray(
+ env, (jobjectArray)env->CallObjectMethod(image, gFields.methodPlanes));
+ int xDecim = 0;
+ int yDecim = 0;
+ for (size_t ix = 0; ix < img->numPlanes; ++ix) {
+ ScopedLocalRef<jobject> plane(
+ env, env->GetObjectArrayElement(planesArray.get(), (jsize)ix));
+ img->plane[ix].colInc = env->CallIntMethod(plane.get(), gFields.methodPixelStride);
+ img->plane[ix].rowInc = env->CallIntMethod(plane.get(), gFields.methodRowStride);
+ ScopedLocalRef<jobject> buffer(
+ env, env->CallObjectMethod(plane.get(), gFields.methodBuffer));
+
+ img->plane[ix].buffer = (const uint8_t *)env->GetDirectBufferAddress(buffer.get());
+ img->plane[ix].size = env->GetDirectBufferCapacity(buffer.get());
+
+ img->plane[ix].cropOffs =
+ (img->crop.left >> xDecim) * img->plane[ix].colInc
+ + (img->crop.top >> yDecim) * img->plane[ix].rowInc;
+ img->plane[ix].cropHeight =
+ ((img->crop.bottom + (1 << yDecim) - 1) >> yDecim) - (img->crop.top >> yDecim);
+ img->plane[ix].cropWidth =
+ ((img->crop.right + (1 << xDecim) - 1) >> xDecim) - (img->crop.left >> xDecim);
+
+ // sanity check on increments
+ ssize_t widthOffs =
+ (((img->width + (1 << xDecim) - 1) >> xDecim) - 1) * img->plane[ix].colInc;
+ ssize_t heightOffs =
+ (((img->height + (1 << yDecim) - 1) >> yDecim) - 1) * img->plane[ix].rowInc;
+ if (widthOffs < 0 || heightOffs < 0
+ || widthOffs + heightOffs >= (ssize_t)img->plane[ix].size) {
+ jniThrowException(
+ env, "java/lang/IndexOutOfBoundsException", "plane exceeds bytearray");
+ delete img;
+ img = NULL;
+ return NULL;
+ }
+ xDecim = yDecim = 1;
+ }
+ return img;
+}
+
+extern "C" jint Java_android_media_cts_CodecUtils_getImageChecksum(JNIEnv *env,
+ jclass /*clazz*/, jobject image)
+{
+ NativeImage *img = getNativeImage(env, image);
+ if (img == NULL) {
+ return 0;
+ }
+
+ Adler32 adler;
+ for (size_t ix = 0; ix < img->numPlanes; ++ix) {
+ const uint8_t *row = img->plane[ix].buffer + img->plane[ix].cropOffs;
+ for (size_t y = img->plane[ix].cropHeight; y > 0; --y) {
+ const uint8_t *col = row;
+ ssize_t colInc = img->plane[ix].colInc;
+ for (size_t x = img->plane[ix].cropWidth; x > 0; --x) {
+ adler.update(*col);
+ col += colInc;
+ }
+ row += img->plane[ix].rowInc;
+ }
+ }
+ ALOGV("adler %zu/%u", adler.length(), adler.checksum());
+ return adler.checksum();
+}
+
+/* tiled copy that loops around source image boundary */
+extern "C" void Java_android_media_cts_CodecUtils_copyFlexYUVImage(JNIEnv *env,
+ jclass /*clazz*/, jobject target, jobject source)
+{
+ NativeImage *tgt = getNativeImage(env, target);
+ NativeImage *src = getNativeImage(env, source);
+ if (tgt != NULL && src != NULL) {
+ ALOGV("copyFlexYUVImage %dx%d (%d,%d..%d,%d) (%zux%zu) %+zd%+zd %+zd%+zd %+zd%+zd <= "
+ "%dx%d (%d, %d..%d, %d) (%zux%zu) %+zd%+zd %+zd%+zd %+zd%+zd",
+ tgt->width, tgt->height,
+ tgt->crop.left, tgt->crop.top, tgt->crop.right, tgt->crop.bottom,
+ tgt->plane[0].cropWidth, tgt->plane[0].cropHeight,
+ tgt->plane[0].rowInc, tgt->plane[0].colInc,
+ tgt->plane[1].rowInc, tgt->plane[1].colInc,
+ tgt->plane[2].rowInc, tgt->plane[2].colInc,
+ src->width, src->height,
+ src->crop.left, src->crop.top, src->crop.right, src->crop.bottom,
+ src->plane[0].cropWidth, src->plane[0].cropHeight,
+ src->plane[0].rowInc, src->plane[0].colInc,
+ src->plane[1].rowInc, src->plane[1].colInc,
+ src->plane[2].rowInc, src->plane[2].colInc);
+ for (size_t ix = 0; ix < tgt->numPlanes; ++ix) {
+ uint8_t *row = const_cast<uint8_t *>(tgt->plane[ix].buffer) + tgt->plane[ix].cropOffs;
+ for (size_t y = 0; y < tgt->plane[ix].cropHeight; ++y) {
+ uint8_t *col = row;
+ ssize_t colInc = tgt->plane[ix].colInc;
+ const uint8_t *srcRow = (src->plane[ix].buffer + src->plane[ix].cropOffs
+ + src->plane[ix].rowInc * (y % src->plane[ix].cropHeight));
+ for (size_t x = 0; x < tgt->plane[ix].cropWidth; ++x) {
+ *col = srcRow[src->plane[ix].colInc * (x % src->plane[ix].cropWidth)];
+ col += colInc;
+ }
+ row += tgt->plane[ix].rowInc;
+ }
+ }
+ }
+}
diff --git a/tests/tests/media/res/raw/sine1khzm40db.wav b/tests/tests/media/res/raw/sine1khzm40db.wav
new file mode 100644
index 0000000..ba541c4
--- /dev/null
+++ b/tests/tests/media/res/raw/sine1khzm40db.wav
Binary files differ
diff --git a/tests/tests/media/res/raw/sine1khzs40dblong.mp3 b/tests/tests/media/res/raw/sine1khzs40dblong.mp3
new file mode 100644
index 0000000..29bc683
--- /dev/null
+++ b/tests/tests/media/res/raw/sine1khzs40dblong.mp3
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..2c9c3d3
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_60fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_60fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..71150af
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_60fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..18d53e6
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..9c91510
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_60fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_60fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..8d9ab8e
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_60fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..a5eddd3
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..35ab7a0
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..b837dc2
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..631ea04
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..051a6c0
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_60fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_60fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..d6f0f3b
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_60fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..d34d03f
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
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_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..12e07ce
--- /dev/null
+++ b/tests/tests/media/res/raw/video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..15c34b9
--- /dev/null
+++ b/tests/tests/media/res/raw/video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..b9c1134
--- /dev/null
+++ b/tests/tests/media/res/raw/video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..4404877
--- /dev/null
+++ b/tests/tests/media/res/raw/video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..e5a58e6
--- /dev/null
+++ b/tests/tests/media/res/raw/video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_480x360_mp4_h264_871kbps_30fps.mp4 b/tests/tests/media/res/raw/video_480x360_mp4_h264_871kbps_30fps.mp4
new file mode 100644
index 0000000..55a83e7
--- /dev/null
+++ b/tests/tests/media/res/raw/video_480x360_mp4_h264_871kbps_30fps.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..d0df713
--- /dev/null
+++ b/tests/tests/media/res/raw/video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_640x360_webm_vp9_1638kbps_30fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_640x360_webm_vp9_1638kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
new file mode 100644
index 0000000..dbe2f1b
--- /dev/null
+++ b/tests/tests/media/res/raw/video_640x360_webm_vp9_1638kbps_30fps_vorbis_stereo_128kbps_44100hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..055e217
--- /dev/null
+++ b/tests/tests/media/res/raw/video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..87c6897
--- /dev/null
+++ b/tests/tests/media/res/raw/video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz.mp4
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 dbe2c92..223438f 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -50,7 +50,7 @@
public Iterable<Codec> H264(CodecFactory factory) {
return factory.createCodecList(
mContext,
- "video/avc",
+ MediaFormat.MIMETYPE_VIDEO_AVC,
"OMX.google.h264.decoder",
R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz,
R.raw.video_1280x720_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz);
@@ -59,7 +59,7 @@
public Iterable<Codec> HEVC(CodecFactory factory) {
return factory.createCodecList(
mContext,
- "video/hevc",
+ MediaFormat.MIMETYPE_VIDEO_HEVC,
"OMX.google.hevc.decoder",
R.raw.video_640x360_mp4_hevc_450kbps_30fps_aac_stereo_128kbps_48000hz,
R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz);
@@ -68,7 +68,7 @@
public Iterable<Codec> H263(CodecFactory factory) {
return factory.createCodecList(
mContext,
- "video/3gpp",
+ MediaFormat.MIMETYPE_VIDEO_H263,
"OMX.google.h263.decoder",
R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
R.raw.video_352x288_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz);
@@ -77,7 +77,7 @@
public Iterable<Codec> Mpeg4(CodecFactory factory) {
return factory.createCodecList(
mContext,
- "video/mp4v-es",
+ MediaFormat.MIMETYPE_VIDEO_MPEG4,
"OMX.google.mpeg4.decoder",
R.raw.video_1280x720_mp4_mpeg4_1000kbps_25fps_aac_stereo_128kbps_44100hz,
@@ -87,7 +87,7 @@
public Iterable<Codec> VP8(CodecFactory factory) {
return factory.createCodecList(
mContext,
- "video/x-vnd.on2.vp8",
+ MediaFormat.MIMETYPE_VIDEO_VP8,
"OMX.google.vp8.decoder",
R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
R.raw.video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz);
@@ -96,7 +96,7 @@
public Iterable<Codec> VP9(CodecFactory factory) {
return factory.createCodecList(
mContext,
- "video/x-vnd.on2.vp9",
+ MediaFormat.MIMETYPE_VIDEO_VP9,
"OMX.google.vp9.decoder",
R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
R.raw.video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_44100hz);
@@ -1288,9 +1288,8 @@
}
/* enumerate codecs */
- int codecCount = MediaCodecList.getCodecCount();
- for (int codecIx = 0; codecIx < codecCount; codecIx++) {
- MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(codecIx);
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ for (MediaCodecInfo codecInfo : mcl.getCodecInfos()) {
if (codecInfo.isEncoder()) {
continue;
}
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index e65fb0b..3f6d200 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -38,7 +38,6 @@
import com.android.cts.media.R;
-
import android.content.Context;
import android.content.res.Resources;
import android.media.AudioManager;
@@ -49,6 +48,8 @@
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;
@@ -56,6 +57,8 @@
private AudioManager mAudioManager;
private boolean mHasVibrator;
private boolean mUseFixedVolume;
+ private int[] mMasterVolumeRamp;
+ private TreeMap<Integer, Integer> mMasterVolumeMap = new TreeMap<Integer, Integer>();
@Override
protected void setUp() throws Exception {
@@ -65,6 +68,12 @@
mHasVibrator = (vibrator != null) && vibrator.hasVibrator();
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]);
+ }
}
public void testMicrophoneMute() throws Exception {
@@ -314,6 +323,7 @@
}
public void testVolume() throws Exception {
+ int volume, volumeDelta;
int[] streams = { AudioManager.STREAM_ALARM,
AudioManager.STREAM_MUSIC,
AudioManager.STREAM_VOICE_CALL,
@@ -356,22 +366,32 @@
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 - 1, mAudioManager.getStreamVolume(streams[i]));
+ assertEquals(maxVolume - volumeDelta, mAudioManager.getStreamVolume(streams[i]));
// volume lower
mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
- for (int k = maxVolume; k > 0; k--) {
+ volume = mAudioManager.getStreamVolume(streams[i]);
+ while (volume > 0) {
+ volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
mAudioManager.adjustStreamVolume(streams[i], ADJUST_LOWER, 0);
- assertEquals(k - 1, mAudioManager.getStreamVolume(streams[i]));
+ assertEquals(Math.max(0, volume - volumeDelta),
+ mAudioManager.getStreamVolume(streams[i]));
+ volume = mAudioManager.getStreamVolume(streams[i]);
}
mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
+
// volume raise
mAudioManager.setStreamVolume(streams[i], 1, 0);
- for (int k = 1; k < maxVolume; k++) {
+ volume = mAudioManager.getStreamVolume(streams[i]);
+ while (volume < maxVolume) {
+ volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
- assertEquals(1 + k, mAudioManager.getStreamVolume(streams[i]));
+ assertEquals(Math.min(volume + volumeDelta, maxVolume),
+ mAudioManager.getStreamVolume(streams[i]));
+ volume = mAudioManager.getStreamVolume(streams[i]);
}
// volume same
@@ -406,18 +426,20 @@
}
// adjust volume as ADJUST_RAISE
- 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));
- }
+ 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));
// 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(maxMusicVolume - 1, mAudioManager.getStreamVolume(STREAM_MUSIC));
+ assertEquals(Math.max(0, maxMusicVolume - volumeDelta),
+ mAudioManager.getStreamVolume(STREAM_MUSIC));
+
mp.stop();
mp.release();
Thread.sleep(TIME_TO_PLAY);
@@ -432,4 +454,10 @@
mAudioManager.setRingerMode(-3007);
assertEquals(ringerMode, mAudioManager.getRingerMode());
}
+
+ private int getVolumeDelta(int volume) {
+ int volumeDelta = mMasterVolumeMap.floorEntry(volume).getValue();
+ assertTrue(volumeDelta > 0);
+ return volumeDelta;
+ }
}
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index a342c37..4f6d27f 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -1310,36 +1310,160 @@
}
public static byte[] createSoundDataInByteArray(int bufferSamples, final int sampleRate,
- final double frequency) {
+ final double frequency, double sweep) {
final double rad = 2 * Math.PI * frequency / sampleRate;
byte[] vai = new byte[bufferSamples];
+ sweep = Math.PI * sweep / ((double)sampleRate * vai.length);
for (int j = 0; j < vai.length; j++) {
- int unsigned = (int)(Math.sin(j * rad) * Byte.MAX_VALUE) + Byte.MAX_VALUE & 0xFF;
+ int unsigned = (int)(Math.sin(j * (rad + j * sweep)) * Byte.MAX_VALUE)
+ + Byte.MAX_VALUE & 0xFF;
vai[j] = (byte) unsigned;
}
return vai;
}
public static short[] createSoundDataInShortArray(int bufferSamples, final int sampleRate,
- final double frequency) {
+ final double frequency, double sweep) {
final double rad = 2 * Math.PI * frequency / sampleRate;
short[] vai = new short[bufferSamples];
+ sweep = Math.PI * sweep / ((double)sampleRate * vai.length);
for (int j = 0; j < vai.length; j++) {
- vai[j] = (short)(Math.sin(j * rad) * Short.MAX_VALUE);
+ vai[j] = (short)(Math.sin(j * (rad + j * sweep)) * Short.MAX_VALUE);
}
return vai;
}
public static float[] createSoundDataInFloatArray(int bufferSamples, final int sampleRate,
- final double frequency) {
+ final double frequency, double sweep) {
final double rad = 2 * Math.PI * frequency / sampleRate;
float[] vaf = new float[bufferSamples];
+ sweep = Math.PI * sweep / ((double)sampleRate * vaf.length);
for (int j = 0; j < vaf.length; j++) {
- vaf[j] = (float)(Math.sin(j * rad));
+ vaf[j] = (float)(Math.sin(j * (rad + j * sweep)));
}
return vaf;
}
+ public static byte[] createSoundDataInByteArray(int bufferSamples, final int sampleRate,
+ final double frequency) {
+ return createSoundDataInByteArray(bufferSamples, sampleRate, frequency, 0 /*sweep*/);
+ }
+
+ public static short[] createSoundDataInShortArray(int bufferSamples, final int sampleRate,
+ final double frequency) {
+ return createSoundDataInShortArray(bufferSamples, sampleRate, frequency, 0 /*sweep*/);
+ }
+
+ public static float[] createSoundDataInFloatArray(int bufferSamples, final int sampleRate,
+ final double frequency) {
+ return createSoundDataInFloatArray(bufferSamples, sampleRate, frequency, 0 /*sweep*/);
+ }
+
+ public void testPlayStaticData() throws Exception {
+ // constants for test
+ final String TEST_NAME = "testPlayStaticData";
+ final int TEST_FORMAT_ARRAY[] = { // 6 chirps repeated (TEST_LOOPS+1) times, 3 times
+ AudioFormat.ENCODING_PCM_8BIT,
+ AudioFormat.ENCODING_PCM_16BIT,
+ AudioFormat.ENCODING_PCM_FLOAT,
+ };
+ final int TEST_SR_ARRAY[] = {
+ 12055, // Note multichannel tracks will sound very short at low sample rates
+ 48000,
+ };
+ final int TEST_CONF_ARRAY[] = {
+ AudioFormat.CHANNEL_OUT_MONO, // 1.0
+ AudioFormat.CHANNEL_OUT_STEREO, // 2.0
+ AudioFormat.CHANNEL_OUT_7POINT1_SURROUND, // 7.1
+ };
+ final int TEST_MODE = AudioTrack.MODE_STATIC;
+ final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
+ final double TEST_SWEEP = 100;
+ final int TEST_LOOPS = 1;
+
+ for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
+ double frequency = 400; // frequency changes for each test
+ for (int TEST_SR : TEST_SR_ARRAY) {
+ for (int TEST_CONF : TEST_CONF_ARRAY) {
+ // -------- initialization --------------
+ final int seconds = 1;
+ final int channelCount = Integer.bitCount(TEST_CONF);
+ final int bufferFrames = seconds * TEST_SR;
+ final int bufferSamples = bufferFrames * channelCount;
+ final int bufferSize = bufferSamples
+ * AudioFormat.getBytesPerSample(TEST_FORMAT);
+ final double testFrequency = frequency / channelCount;
+ final long MILLISECONDS_PER_SECOND = 1000;
+ AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR,
+ TEST_CONF, TEST_FORMAT, bufferSize, TEST_MODE);
+ assertEquals(TEST_NAME, track.getState(), AudioTrack.STATE_NO_STATIC_DATA);
+
+ // -------- test --------------
+
+ // test setLoopPoints and setPosition can be called here.
+ assertEquals(TEST_NAME,
+ track.setPlaybackHeadPosition(bufferFrames/2),
+ android.media.AudioTrack.SUCCESS);
+ assertEquals(TEST_NAME,
+ track.setLoopPoints(
+ 0 /*startInFrames*/, bufferFrames, 10 /*loopCount*/),
+ android.media.AudioTrack.SUCCESS);
+ // only need to write once to the static track
+ switch (TEST_FORMAT) {
+ case AudioFormat.ENCODING_PCM_8BIT: {
+ byte data[] = createSoundDataInByteArray(
+ bufferSamples, TEST_SR,
+ testFrequency, TEST_SWEEP);
+ assertEquals(TEST_NAME,
+ track.write(data, 0 /*offsetInBytes*/, data.length),
+ bufferSamples);
+ } break;
+ case AudioFormat.ENCODING_PCM_16BIT: {
+ short data[] = createSoundDataInShortArray(
+ bufferSamples, TEST_SR,
+ testFrequency, TEST_SWEEP);
+ assertEquals(TEST_NAME,
+ track.write(data, 0 /*offsetInBytes*/, data.length),
+ bufferSamples);
+ } break;
+ case AudioFormat.ENCODING_PCM_FLOAT: {
+ float data[] = createSoundDataInFloatArray(
+ bufferSamples, TEST_SR,
+ testFrequency, TEST_SWEEP);
+ assertEquals(TEST_NAME,
+ track.write(data, 0 /*offsetInBytes*/, data.length,
+ AudioTrack.WRITE_BLOCKING),
+ bufferSamples);
+ } break;
+ }
+ assertEquals(TEST_NAME, track.getState(), AudioTrack.STATE_INITIALIZED);
+ // test setLoopPoints and setPosition can be called here.
+ assertEquals(TEST_NAME,
+ track.setPlaybackHeadPosition(0 /*positionInFrames*/),
+ android.media.AudioTrack.SUCCESS);
+ assertEquals(TEST_NAME,
+ track.setLoopPoints(0 /*startInFrames*/, bufferFrames, TEST_LOOPS),
+ android.media.AudioTrack.SUCCESS);
+
+ track.play();
+ Thread.sleep(seconds * MILLISECONDS_PER_SECOND * (TEST_LOOPS + 1));
+ Thread.sleep(WAIT_MSEC);
+
+ // Check position after looping. AudioTrack.getPlaybackHeadPosition() returns
+ // the running count of frames played, not the actual static buffer position.
+ int position = track.getPlaybackHeadPosition();
+ assertEquals(TEST_NAME, position, bufferFrames * (TEST_LOOPS + 1));
+
+ track.stop();
+ Thread.sleep(WAIT_MSEC);
+ // -------- tear down --------------
+ track.release();
+ frequency += 70; // increment test tone frequency
+ }
+ }
+ }
+ }
+
public void testPlayStreamData() throws Exception {
// constants for test
final String TEST_NAME = "testPlayStreamData";
diff --git a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
index ff05246..c837d0a 100644
--- a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
+++ b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
@@ -24,6 +24,7 @@
import android.media.MediaCodecList;
import android.media.MediaDrm;
import android.media.MediaDrmException;
+import android.media.MediaFormat;
import android.media.CamcorderProfile;
import android.net.Uri;
import android.os.Environment;
@@ -63,7 +64,7 @@
private static final int VIDEO_WIDTH = 1280;
private static final int VIDEO_HEIGHT = 720;
private static final long PLAY_TIME_MS = TimeUnit.MILLISECONDS.convert(1, TimeUnit.MINUTES);
- private static final String MIME_VIDEO_AVC = "video/avc";
+ private static final String MIME_VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
private static final Uri AUDIO_URL = Uri.parse(
"http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car_cenc-20120827-8c.mp4");
@@ -303,104 +304,16 @@
}
}
- CodecCapabilities cap;
- int highestProfileLevel = 0;
- MediaCodecInfo codecInfo;
-
- for (int i = 0; i < MediaCodecList.getCodecCount(); i++) {
- codecInfo = MediaCodecList.getCodecInfoAt(i);
- if (codecInfo.isEncoder()) {
- continue;
- }
-
- String[] types = codecInfo.getSupportedTypes();
- for (int j = 0; j < types.length; ++j) {
- if (!types[j].equalsIgnoreCase(MIME_VIDEO_AVC)) {
- continue;
- }
-
- Log.d(TAG, "codec: " + codecInfo.getName() + "types: " + types[j]);
- cap = codecInfo.getCapabilitiesForType(types[j]);
- for (CodecProfileLevel profileLevel : cap.profileLevels) {
- Log.i(TAG, "codec " + codecInfo.getName() + ", level " + profileLevel.level);
- if (profileLevel.level > highestProfileLevel) {
- highestProfileLevel = profileLevel.level;
- }
- }
- Log.i(TAG, "codec " + codecInfo.getName() + ", highest level " + highestProfileLevel);
- }
+ MediaFormat format = MediaFormat.createVideoFormat(
+ MIME_VIDEO_AVC, videoWidth, videoHeight);
+ // using secure codec even though it is clear key DRM
+ format.setFeatureEnabled(CodecCapabilities.FEATURE_SecurePlayback, true);
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.ALL_CODECS);
+ if (mcl.findDecoderForFormat(format) == null) {
+ Log.i(TAG, "could not find codec for " + format);
+ return false;
}
-
- // AVCLevel and its resolution is taken from http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC
- switch(highestProfileLevel) {
- case CodecProfileLevel.AVCLevel1:
- case CodecProfileLevel.AVCLevel1b:
- return (videoWidth <= 176 && videoHeight <= 144);
- case CodecProfileLevel.AVCLevel11:
- case CodecProfileLevel.AVCLevel12:
- case CodecProfileLevel.AVCLevel13:
- case CodecProfileLevel.AVCLevel2:
- return (videoWidth <= 352 && videoHeight <= 288);
- case CodecProfileLevel.AVCLevel21:
- return (videoWidth <= 352 && videoHeight <= 576);
- case CodecProfileLevel.AVCLevel22:
- case CodecProfileLevel.AVCLevel3:
- return (videoWidth <= 720 && videoHeight <= 576);
- case CodecProfileLevel.AVCLevel31:
- return (videoWidth <= 1280 && videoHeight <= 720);
- case CodecProfileLevel.AVCLevel32:
- return (videoWidth <= 1280 && videoHeight <= 1024);
- case CodecProfileLevel.AVCLevel4:
- case CodecProfileLevel.AVCLevel41:
- // 1280 x 720
- // 1920 x 1080
- // 2048 x 1024
- if (videoWidth <= 1920) {
- return (videoHeight <= 1080);
- } else if (videoWidth <= 2048) {
- return (videoHeight <= 1024);
- } else {
- return false;
- }
- case CodecProfileLevel.AVCLevel42:
- return (videoWidth <= 2048 && videoHeight <= 1080);
- case CodecProfileLevel.AVCLevel5:
- // 1920 x 1080
- // 2048 x 1024
- // 2048 x 1080
- // 2560 x 1920
- // 3672 x 1536
- if (videoWidth <= 1920) {
- return (videoHeight <= 1080);
- } else if (videoWidth <= 2048) {
- return (videoHeight <= 1080);
- } else if (videoWidth <= 2560) {
- return (videoHeight <= 1920);
- } else if (videoWidth <= 3672) {
- return (videoHeight <= 1536);
- } else {
- return false;
- }
- case CodecProfileLevel.AVCLevel51:
- default: // any future extension will cap at level 5.1
- // 1920 x 1080
- // 2560 x 1920
- // 3840 x 2160
- // 4096 x 2048
- // 4096 x 2160
- // 4096 x 2304
- if (videoWidth <= 1920) {
- return (videoHeight <= 1080);
- } else if (videoWidth <= 2560) {
- return (videoHeight <= 1920);
- } else if (videoWidth <= 3840) {
- return (videoHeight <= 2160);
- } else if (videoWidth <= 4096) {
- return (videoHeight <= 2304);
- } else {
- return false;
- }
- }
+ return true;
}
/**
@@ -410,7 +323,7 @@
if (!hasAudioOutput()) {
return;
}
-
+
MediaDrm drm = startDrm();
if (null == drm) {
throw new Error("Failed to create drm.");
diff --git a/tests/tests/media/src/android/media/cts/CodecUtils.java b/tests/tests/media/src/android/media/cts/CodecUtils.java
new file mode 100644
index 0000000..3c3576f
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/CodecUtils.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2014 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.media.cts;
+
+import android.media.Image;
+import android.util.Log;
+
+public class CodecUtils {
+ private static final String TAG = "CodecUtils";
+
+ /** Load jni on initialization */
+ static {
+ Log.i(TAG, "before loadlibrary");
+ System.loadLibrary("ctsmediacodec_jni");
+ Log.i(TAG, "after loadlibrary");
+ }
+
+ public native static int getImageChecksum(Image image);
+ public native static void copyFlexYUVImage(Image target, Image source);
+}
+
diff --git a/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java b/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
index 9ee3118..1ceb025 100644
--- a/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
@@ -53,7 +53,8 @@
private static final boolean DEBUG_SAVE_FILE = false; // save copy of encoded movie
// parameters for the encoder
- private static final String MIME_TYPE = "video/avc"; // H.264 Advanced Video Coding
+ // H.264 Advanced Video Coding
+ private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
private static final int FRAME_RATE = 15; // 15fps
private static final int IFRAME_INTERVAL = 10; // 10 seconds between I-frames
@@ -806,7 +807,7 @@
/**
- * The elementary stream coming out of the "video/avc" encoder needs to be fed back into
+ * The elementary stream coming out of the encoder needs to be fed back into
* the decoder one chunk at a time. If we just wrote the data to a file, we would lose
* the information about chunk boundaries. This class stores the encoded data in memory,
* retaining the chunk organization.
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index d71d38a..70cb10f 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -18,6 +18,8 @@
import com.android.cts.media.R;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.graphics.ImageFormat;
@@ -81,14 +83,15 @@
// TODO: add similar tests for other audio and video formats
public void testBug11696552() throws Exception {
- MediaCodec mMediaCodec = MediaCodec.createDecoderByType("audio/mp4a-latm");
- MediaFormat mFormat = MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 2);
+ MediaCodec mMediaCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);
+ MediaFormat mFormat = MediaFormat.createAudioFormat(
+ MediaFormat.MIMETYPE_AUDIO_AAC, 48000 /* frequency */, 2 /* channels */);
mFormat.setByteBuffer("csd-0", ByteBuffer.wrap( new byte [] {0x13, 0x10} ));
mFormat.setInteger(MediaFormat.KEY_IS_ADTS, 1);
mMediaCodec.configure(mFormat, null, null, 0);
mMediaCodec.start();
int index = mMediaCodec.dequeueInputBuffer(250000);
- mMediaCodec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM );
+ mMediaCodec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
mMediaCodec.dequeueOutputBuffer(info, 250000);
}
@@ -844,21 +847,23 @@
return numsamples;
}
+ private void testDecode(int testVideo, int frameNum) throws Exception {
+ // Decode to Surface.
+ Surface s = getActivity().getSurfaceHolder().getSurface();
+ int frames1 = countFrames(testVideo, RESET_MODE_NONE, -1 /* eosframe */, s);
+ assertEquals("wrong number of frames decoded", frameNum, frames1);
+
+ // Decode to buffer.
+ int frames2 = countFrames(testVideo, RESET_MODE_NONE, -1 /* eosframe */, null);
+ assertEquals("different number of frames when using Surface", frames1, frames2);
+ }
+
public void testCodecBasicH264() throws Exception {
if (!hasH264(false)) {
Log.i(TAG, "SKIPPING testCodecBasicH264(): No codec found.");
return;
}
- Surface s = getActivity().getSurfaceHolder().getSurface();
- int frames1 = countFrames(
- R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz,
- RESET_MODE_NONE, -1 /* eosframe */, s);
- assertEquals("wrong number of frames decoded", 240, frames1);
-
- int frames2 = countFrames(
- R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz,
- RESET_MODE_NONE, -1 /* eosframe */, null);
- assertEquals("different number of frames when using Surface", frames1, frames2);
+ testDecode(R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz, 240);
}
public void testCodecBasicHEVC() throws Exception {
@@ -866,16 +871,7 @@
Log.i(TAG, "SKIPPING testCodecBasicHEVC(): No codec found.");
return;
}
- Surface s = getActivity().getSurfaceHolder().getSurface();
- int frames1 = countFrames(
- R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz,
- RESET_MODE_NONE, -1 /* eosframe */, s);
- assertEquals("wrong number of frames decoded", 300, frames1);
-
- int frames2 = countFrames(
- R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz,
- RESET_MODE_NONE, -1 /* eosframe */, null);
- assertEquals("different number of frames when using Surface", frames1, frames2);
+ testDecode(R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz, 300);
}
public void testCodecBasicH263() throws Exception {
@@ -883,16 +879,7 @@
Log.i(TAG, "SKIPPING testCodecBasicH263(): No codec found.");
return;
}
- Surface s = getActivity().getSurfaceHolder().getSurface();
- int frames1 = countFrames(
- R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
- RESET_MODE_NONE, -1 /* eosframe */, s);
- assertEquals("wrong number of frames decoded", 122, frames1);
-
- int frames2 = countFrames(
- R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
- RESET_MODE_NONE, -1 /* eosframe */, null);
- assertEquals("different number of frames when using Surface", frames1, frames2);
+ testDecode(R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz, 122);
}
public void testCodecBasicMpeg4() throws Exception {
@@ -900,16 +887,7 @@
Log.i(TAG, "SKIPPING testCodecBasicMpeg4(): No codec found.");
return;
}
- Surface s = getActivity().getSurfaceHolder().getSurface();
- int frames1 = countFrames(
- R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
- RESET_MODE_NONE, -1 /* eosframe */, s);
- assertEquals("wrong number of frames decoded", 249, frames1);
-
- int frames2 = countFrames(
- R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
- RESET_MODE_NONE, -1 /* eosframe */, null);
- assertEquals("different number of frames when using Surface", frames1, frames2);
+ testDecode(R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz, 249);
}
public void testCodecBasicVP8() throws Exception {
@@ -917,16 +895,7 @@
Log.i(TAG, "SKIPPING testCodecBasicVP8(): No codec found.");
return;
}
- Surface s = getActivity().getSurfaceHolder().getSurface();
- int frames1 = countFrames(
- R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
- RESET_MODE_NONE, -1 /* eosframe */, s);
- assertEquals("wrong number of frames decoded", 240, frames1);
-
- int frames2 = countFrames(
- R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
- RESET_MODE_NONE, -1 /* eosframe */, null);
- assertEquals("different number of frames when using Surface", frames1, frames2);
+ testDecode(R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz, 240);
}
public void testCodecBasicVP9() throws Exception {
@@ -934,16 +903,256 @@
Log.i(TAG, "SKIPPING testCodecBasicVP9(): No codec found.");
return;
}
- Surface s = getActivity().getSurfaceHolder().getSurface();
- int frames1 = countFrames(
- R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
- RESET_MODE_NONE, -1 /* eosframe */, s);
- assertEquals("wrong number of frames decoded", 240, frames1);
+ testDecode(R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz, 240);
+ }
- int frames2 = countFrames(
- R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
- RESET_MODE_NONE, -1 /* eosframe */, null);
- assertEquals("different number of frames when using Surface", frames1, frames2);
+ public void testH264Decode320x240() throws Exception {
+ if (!hasH264(false)) {
+ Log.i(TAG, "SKIPPING testH264Decode320x240(): No codec found.");
+ return;
+ }
+ testDecode(R.raw.video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+ }
+
+ public void testH264Decode720x480() throws Exception {
+ if (!hasH264(false)) {
+ Log.i(TAG, "SKIPPING testH264Decode720x480(): No codec found.");
+ return;
+ }
+ testDecode(R.raw.video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+ }
+
+ public void testH264Decode30fps1280x720Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 30)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testH264Decode30fps1280x720() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 30)) {
+ Log.i(TAG, "SKIPPING testH264Decode30fps1280x720(): Unsupported profile.");
+ return;
+ }
+
+ testDecode(R.raw.video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+ }
+
+ public void testH264Decode60fps1280x720Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 60)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testH264Decode60fps1280x720() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 60)) {
+ Log.i(TAG, "SKIPPING testH264Decode60fps1280x720(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1280x720_mp4_h264_8192kbps_60fps_aac_stereo_128kbps_44100hz, 596);
+ }
+
+ public void testH264Decode30fps1920x1080Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 30)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testH264Decode30fps1920x1080() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 30)) {
+ Log.i(TAG, "SKIPPING testH264Decode30fps1920x1080(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+ }
+
+ public void testH264Decode60fps1920x1080Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 60)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testH264Decode60fps1920x1080() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 60)) {
+ Log.i(TAG, "SKIPPING testH264Decode60fps1920x1080(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz, 596);
+ }
+
+ public void testVP8Decode320x240() throws Exception {
+ if (!hasVP8(false)) {
+ Log.i(TAG, "SKIPPING testVP8Decode320x240(): No codec found.");
+ return;
+ }
+ testDecode(R.raw.video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
+ }
+
+ public void testVP8Decode640x360() throws Exception {
+ if (!hasVP8(false)) {
+ Log.i(TAG, "SKIPPING testVP8Decode640x360(): No codec found.");
+ return;
+ }
+ testDecode(R.raw.video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
+ }
+
+ public void testVP8Decode30fps1280x720Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 30)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testVP8Decode30fps1280x720() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 30)) {
+ Log.i(TAG, "SKIPPING testVP8Decode30fps1280x720(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
+ }
+
+ public void testVP8Decode60fps1280x720Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 60)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testVP8Decode60fps1280x720() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 60)) {
+ Log.i(TAG, "SKIPPING testVP8Decode60fps1280x720(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1280x720_webm_vp8_8192kbps_60fps_vorbis_stereo_128kbps_44100hz, 249);
+ }
+
+ public void testVP8Decode30fps1920x1080Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 30)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testVP8Decode30fps1920x1080() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 30)) {
+ Log.i(TAG, "SKIPPING testVP8Decode30fps1920x1080(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_44100hz,
+ 249);
+ }
+
+ public void testVP8Decode60fps1920x1080Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 60)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testVP8Decode60fps1920x1080() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 60)) {
+ Log.i(TAG, "SKIPPING testVP8Decode60fps1920x1080(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1920x1080_webm_vp8_20480kbps_60fps_vorbis_stereo_128kbps_44100hz,
+ 249);
+ }
+
+ public void testVP9Decode320x240() throws Exception {
+ if (!hasVP9(false)) {
+ Log.i(TAG, "SKIPPING testVP9Decode320x240(): No codec found.");
+ return;
+ }
+ testDecode(R.raw.video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
+ }
+
+ public void testVP9Decode640x360() throws Exception {
+ if (!hasVP9(false)) {
+ Log.i(TAG, "SKIPPING testVP9Decode640x360(): No codec found.");
+ return;
+ }
+ testDecode(R.raw.video_640x360_webm_vp9_1638kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
+ }
+
+ public void testVP9Decode30fps1280x720Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP9, 1280, 720, 30)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testVP9Decode30fps1280x720() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP9, 1280, 720, 30)) {
+ Log.i(TAG, "SKIPPING testVP8Decode30fps1920x1080(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
+ }
+
+ public void testVP9Decode30fps1920x1080() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP9, 1920, 1080, 30)) {
+ Log.d(TAG, "SKIPPING testVP9Decode30fps1920x1080(): Unsupported optional profile.");
+ return;
+ }
+
+ testDecode(R.raw.video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_44100hz,
+ 249);
+ }
+
+ public void testVP9Decode30fps3840x2160() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP9, 3840, 2160, 30)) {
+ Log.d(TAG, "SKIPPING testVP9Decode30fps3840x2160(): Unsupported optional profile.");
+ return;
+ }
+
+ testDecode(R.raw.video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_44100hz,
+ 249);
+ }
+
+ public void testHEVCDecode352x288() throws Exception {
+ if (!hasHEVC(false)) {
+ Log.i(TAG, "SKIPPING testHEVCDecode352x288(): No codec found.");
+ return;
+ }
+ testDecode(R.raw.video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+ }
+
+ public void testHEVCDecode720x480() throws Exception {
+ if (!hasHEVC(false)) {
+ Log.i(TAG, "SKIPPING testHEVCDecode720x480(): No codec found.");
+ return;
+ }
+ testDecode(R.raw.video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+ }
+
+ public void testHEVCDecode30fps1280x720Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 1280, 720, 30)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testHEVCDecode30fps1280x720() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 1280, 720, 30)) {
+ Log.i(TAG, "SKIPPING testHEVCDecode30fps1280x720(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+ }
+
+ public void testHEVCDecode30fps1920x1080Tv() throws Exception {
+ if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 1920, 1080, 30)) {
+ fail("Profile is required for TV device.");
+ }
+ }
+
+ public void testHEVCDecode30fps1920x1080() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 1920, 1080, 30)) {
+ Log.i(TAG, "SKIPPING testHEVCDecode30fps1920x1080(): Unsupported profile.");
+ return;
+ }
+ testDecode(R.raw.video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+ }
+
+ public void testHEVCDecode30fps2840x2160() throws Exception {
+ if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 2840, 2160, 30)) {
+ Log.i(TAG, "SKIPPING testHEVCDecode30fps2840x2160(): Unsupported optional profile.");
+ return;
+ }
+ testDecode(R.raw.video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz, 299);
}
public void testCodecEarlyEOSH263() throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
index a480d97..0796515 100644
--- a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
@@ -51,8 +51,9 @@
private static final String DEBUG_FILE_NAME_BASE = "/sdcard/test.";
// parameters for the encoder
- private static final String MIME_TYPE_AVC = "video/avc"; // H.264 Advanced Video Coding
- private static final String MIME_TYPE_VP8 = "video/x-vnd.on2.vp8";
+ // H.264 Advanced Video Coding
+ private static final String MIME_TYPE_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
+ private static final String MIME_TYPE_VP8 = MediaFormat.MIMETYPE_VIDEO_VP8;
private static final int FRAME_RATE = 15; // 15fps
private static final int IFRAME_INTERVAL = 10; // 10 seconds between I-frames
@@ -297,20 +298,24 @@
mLargestColorDelta = -1;
try {
- MediaCodecInfo codecInfo = selectCodec(mMimeType);
- if (codecInfo == null) {
- // Don't fail CTS if they don't have an AVC codec (not here, anyway).
- Log.e(TAG, "Unable to find an appropriate codec for " + mMimeType);
- return;
- }
- if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
-
- int colorFormat = selectColorFormat(codecInfo, mMimeType);
- if (VERBOSE) Log.d(TAG, "found colorFormat: " + colorFormat);
-
// We avoid the device-specific limitations on width and height by using values that
// are multiples of 16, which all tested devices seem to be able to handle.
MediaFormat format = MediaFormat.createVideoFormat(mMimeType, mWidth, mHeight);
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ String codec = mcl.findEncoderForFormat(format);
+ if (codec == null) {
+ // Don't fail CTS if they don't have an AVC codec (not here, anyway).
+ Log.e(TAG, "Unable to find an appropriate codec for " + format);
+ return;
+ }
+ if (VERBOSE) Log.d(TAG, "found codec: " + codec);
+
+ // Create a MediaCodec for the desired codec, then configure it as an encoder with
+ // our desired properties.
+ encoder = MediaCodec.createByCodecName(codec);
+
+ int colorFormat = selectColorFormat(encoder.getCodecInfo(), mMimeType);
+ if (VERBOSE) Log.d(TAG, "found colorFormat: " + colorFormat);
// Set some properties. Failing to specify some of these can cause the MediaCodec
// configure() call to throw an unhelpful exception.
@@ -320,9 +325,6 @@
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
if (VERBOSE) Log.d(TAG, "format: " + format);
- // Create a MediaCodec for the desired codec, then configure it as an encoder with
- // our desired properties.
- encoder = MediaCodec.createByCodecName(codecInfo.getName());
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
@@ -362,19 +364,19 @@
mLargestColorDelta = -1;
try {
- MediaCodecInfo codecInfo = selectCodec(mMimeType);
- if (codecInfo == null) {
- // Don't fail CTS if they don't have an AVC codec (not here, anyway).
- Log.e(TAG, "Unable to find an appropriate codec for " + mMimeType);
- return;
- }
- if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
-
- int colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
-
// We avoid the device-specific limitations on width and height by using values that
// are multiples of 16, which all tested devices seem to be able to handle.
MediaFormat format = MediaFormat.createVideoFormat(mMimeType, mWidth, mHeight);
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ String codec = mcl.findEncoderForFormat(format);
+ if (codec == null) {
+ // Don't fail CTS if they don't have an AVC codec (not here, anyway).
+ Log.e(TAG, "Unable to find an appropriate codec for " + format);
+ return;
+ }
+ if (VERBOSE) Log.d(TAG, "found codec: " + codec);
+
+ int colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
// Set some properties. Failing to specify some of these can cause the MediaCodec
// configure() call to throw an unhelpful exception.
@@ -396,7 +398,7 @@
// Create a MediaCodec for the desired codec, then configure it as an encoder with
// our desired properties. Request a Surface to use for input.
- encoder = MediaCodec.createByCodecName(codecInfo.getName());
+ encoder = MediaCodec.createByCodecName(codec);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
inputSurface = new InputSurface(encoder.createInputSurface());
encoder.start();
@@ -424,29 +426,6 @@
}
/**
- * 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;
- }
-
- /**
* Returns a color format that is supported by the codec and by this test code. If no
* match is found, this throws a test failure -- the set of formats known to the test
* should be expanded for new platforms.
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
index 89b06dc..ba67a42ca 100755
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
@@ -67,24 +67,24 @@
// Encoder parameters table, sort by encoder level from high to low.
private static final int[][] ENCODER_PARAM_TABLE = {
- // encoder level, width, height, bitrate, framerate
- {MediaCodecInfo.CodecProfileLevel.AVCLevel31, 1280, 720, 14000000, 30},
- {MediaCodecInfo.CodecProfileLevel.AVCLevel3, 720, 480, 10000000, 30},
- {MediaCodecInfo.CodecProfileLevel.AVCLevel22, 720, 480, 4000000, 15},
- {MediaCodecInfo.CodecProfileLevel.AVCLevel21, 352, 576, 4000000, 25},
+ // width, height, bitrate, framerate /* level */
+ { 1280, 720, 14000000, 30 }, /* AVCLevel31 */
+ { 720, 480, 10000000, 30 }, /* AVCLevel3 */
+ { 720, 480, 4000000, 15 }, /* AVCLevel22 */
+ { 352, 576, 4000000, 25 }, /* AVCLevel21 */
};
// Virtual display characteristics. Scaled down from full display size because not all
// devices can encode at the resolution of their own display.
private static final String NAME = TAG;
- private static int sWidth = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][1];
- private static int sHeight = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][2];
+ private static int sWidth = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][0];
+ private static int sHeight = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][1];
private static final int DENSITY = DisplayMetrics.DENSITY_HIGH;
private static final int UI_TIMEOUT_MS = 2000;
private static final int UI_RENDER_PAUSE_MS = 400;
// Encoder parameters. We use the same width/height as the virtual display.
- private static final String MIME_TYPE = "video/avc";
+ private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
private static int sFrameRate = 15; // 15fps
private static final int IFRAME_INTERVAL = 10; // 10 seconds between I-frames
private static int sBitRate = 6000000; // 6Mbps
@@ -161,56 +161,16 @@
}
}
- private static boolean hasCodec(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 true;
- }
- }
- }
- return false;
- }
-
/**
* Returns true if the encoder level, specified in the ENCODER_PARAM_TABLE, can be supported.
*/
- private static boolean verifySupportForEncoderLevel(int index) {
- 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 (false == types[j].equalsIgnoreCase(MIME_TYPE)) {
- continue;
- }
-
- MediaCodecInfo.CodecCapabilities caps = codecInfo.getCapabilitiesForType(types[j]);
- for (int k = 0; k < caps.profileLevels.length; k++) {
- int profile = caps.profileLevels[k].profile;
- int level = caps.profileLevels[k].level;
- //Log.d(TAG, "[" + k + "] supported profile = " + profile + ", level = " + level);
- if (caps.profileLevels[k].level >= ENCODER_PARAM_TABLE[index][0]) {
- return true;
- }
- }
- }
- }
- return false;
+ private static boolean verifySupportForEncoderLevel(int i) {
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ MediaFormat format = MediaFormat.createVideoFormat(
+ MIME_TYPE, ENCODER_PARAM_TABLE[i][0], ENCODER_PARAM_TABLE[i][1]);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, ENCODER_PARAM_TABLE[i][2]);
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, ENCODER_PARAM_TABLE[i][3]);
+ return mcl.findEncoderForFormat(format) != null;
}
/**
@@ -224,10 +184,10 @@
// Check if we can support it?
if (verifySupportForEncoderLevel(i)) {
- sWidth = ENCODER_PARAM_TABLE[i][1];
- sHeight = ENCODER_PARAM_TABLE[i][2];
- sBitRate = ENCODER_PARAM_TABLE[i][3];
- sFrameRate = ENCODER_PARAM_TABLE[i][4];
+ sWidth = ENCODER_PARAM_TABLE[i][0];
+ sHeight = ENCODER_PARAM_TABLE[i][1];
+ sBitRate = ENCODER_PARAM_TABLE[i][2];
+ sFrameRate = ENCODER_PARAM_TABLE[i][3];
Log.d(TAG, "encoder parameters changed: width = " + sWidth + ", height = " + sHeight
+ ", bitrate = " + sBitRate + ", framerate = " + sFrameRate);
@@ -245,11 +205,6 @@
OutputSurface outputSurface = null;
VirtualDisplay virtualDisplay = null;
- // Don't run the test of the codec isn't present.
- if (!hasCodec(MIME_TYPE)) {
- return;
- }
-
try {
// Encoded video resolution matches virtual display.
MediaFormat encoderFormat = MediaFormat.createVideoFormat(MIME_TYPE, sWidth, sHeight);
@@ -259,7 +214,15 @@
encoderFormat.setInteger(MediaFormat.KEY_FRAME_RATE, sFrameRate);
encoderFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
- encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ String codec = mcl.findEncoderForFormat(encoderFormat);
+ if (codec == null) {
+ // Don't run the test if the codec isn't present.
+ Log.i(TAG, "SKIPPING test: no support for " + encoderFormat);
+ return;
+ }
+
+ encoder = MediaCodec.createByCodecName(codec);
encoder.configure(encoderFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Surface inputSurface = encoder.createInputSurface();
encoder.start();
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
index 9c99c2d..89d6efa 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
@@ -46,7 +46,7 @@
import android.test.AndroidTestCase;
import android.util.AttributeSet;
import android.util.Log;
-import android.util.Pair;
+import android.util.Size;
import android.view.Display;
import android.view.Surface;
import android.view.TextureView;
@@ -79,7 +79,7 @@
public class EncodeVirtualDisplayWithCompositionTest extends AndroidTestCase {
private static final String TAG = "EncodeVirtualDisplayWithCompositionTest";
private static final boolean DBG = true;
- private static final String MIME_TYPE = "video/avc";
+ private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
private static final long DEFAULT_WAIT_TIMEOUT_MS = 3000;
private static final long DEFAULT_WAIT_TIMEOUT_US = 3000000;
@@ -92,6 +92,8 @@
private static final int BITRATE_1080p = 20000000;
private static final int BITRATE_720p = 14000000;
private static final int BITRATE_800x480 = 14000000;
+ private static final int BITRATE_DEFAULT = 10000000;
+
private static final int IFRAME_INTERVAL = 10;
private static final int MAX_NUM_WINDOWS = 3;
@@ -138,79 +140,59 @@
public void testRendering800x480Locally() throws Throwable {
Log.i(TAG, "testRendering800x480Locally");
- Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
- if (maxRes == null) {
- Log.i(TAG, "SKIPPING testRendering800x480Locally(): codec not supported");
- return;
- }
- if (maxRes.first >= 800 && maxRes.second >= 480) {
+ if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
runTestRenderingInSeparateThread(800, 480, false, false);
} else {
- Log.w(TAG, "This H/W does not support 800x480");
+ Log.i(TAG, "SKIPPING testRendering800x480Locally(): codec not supported");
}
}
public void testRenderingMaxResolutionLocally() throws Throwable {
Log.i(TAG, "testRenderingMaxResolutionLocally");
- Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
+ Size maxRes = checkMaxConcurrentEncodingDecodingResolution();
if (maxRes == null) {
Log.i(TAG, "SKIPPING testRenderingMaxResolutionLocally(): codec not supported");
- return;
+ } else {
+ Log.w(TAG, "Trying resolution " + maxRes);
+ runTestRenderingInSeparateThread(maxRes.getWidth(), maxRes.getHeight(), false, false);
}
- Log.w(TAG, "Trying resolution w:" + maxRes.first + " h:" + maxRes.second);
- runTestRenderingInSeparateThread(maxRes.first, maxRes.second, false, false);
}
public void testRendering800x480Remotely() throws Throwable {
Log.i(TAG, "testRendering800x480Remotely");
- Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
- if (maxRes == null) {
- Log.i(TAG, "SKIPPING testRendering800x480Remotely(): codec not supported");
- return;
- }
- if (maxRes.first >= 800 && maxRes.second >= 480) {
+ if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
runTestRenderingInSeparateThread(800, 480, true, false);
} else {
- Log.w(TAG, "This H/W does not support 800x480");
+ Log.i(TAG, "SKIPPING testRendering800x480Remotely(): codec not supported");
}
}
public void testRenderingMaxResolutionRemotely() throws Throwable {
Log.i(TAG, "testRenderingMaxResolutionRemotely");
- Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
+ Size maxRes = checkMaxConcurrentEncodingDecodingResolution();
if (maxRes == null) {
Log.i(TAG, "SKIPPING testRenderingMaxResolutionRemotely(): codec not supported");
- return;
+ } else {
+ Log.w(TAG, "Trying resolution " + maxRes);
+ runTestRenderingInSeparateThread(maxRes.getWidth(), maxRes.getHeight(), true, false);
}
- Log.w(TAG, "Trying resolution w:" + maxRes.first + " h:" + maxRes.second);
- runTestRenderingInSeparateThread(maxRes.first, maxRes.second, true, false);
}
public void testRendering800x480RemotelyWith3Windows() throws Throwable {
Log.i(TAG, "testRendering800x480RemotelyWith3Windows");
- Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
- if (maxRes == null) {
- Log.i(TAG, "SKIPPING testRendering800x480RemotelyWith3Windows(): codec not supported");
- return;
- }
- if (maxRes.first >= 800 && maxRes.second >= 480) {
+ if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
runTestRenderingInSeparateThread(800, 480, true, true);
} else {
- Log.w(TAG, "This H/W does not support 800x480");
+ Log.i(TAG, "SKIPPING testRendering800x480RemotelyWith3Windows(): codec not supported");
}
}
public void testRendering800x480LocallyWith3Windows() throws Throwable {
Log.i(TAG, "testRendering800x480LocallyWith3Windows");
- Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
- if (maxRes == null) {
- Log.i(TAG, "SKIPPING testRendering800x480LocallyWith3Windows(): codec not supported");
- return;
- }
- if (maxRes.first >= 800 && maxRes.second >= 480) {
+ if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
runTestRenderingInSeparateThread(800, 480, false, true);
} else {
- Log.w(TAG, "This H/W does not support 800x480");
+ Log.i(TAG, "SKIPPING testRendering800x480LocallyWith3Windows(): codec not supported");
}
}
@@ -424,8 +406,8 @@
private static final int NUM_DISPLAY_CREATION = 10;
private static final int NUM_RENDERING = 10;
private void doTestVirtualDisplayRecycles(int numDisplays) throws Exception {
- CodecInfo codecInfo = getAvcSupportedFormatInfo();
- if (codecInfo == null) {
+ Size maxSize = getMaxSupportedEncoderSize();
+ if (maxSize == null) {
Log.i(TAG, "no codec found, skipping");
return;
}
@@ -437,13 +419,13 @@
Log.i(TAG, "start encoding");
}
EncodingHelper encodingHelper = new EncodingHelper();
- mEncodingSurface = encodingHelper.startEncoding(codecInfo.mMaxW, codecInfo.mMaxH,
+ mEncodingSurface = encodingHelper.startEncoding(maxSize.getWidth(), maxSize.getHeight(),
mEncoderEventListener);
GlCompositor compositor = new GlCompositor();
if (DBG) {
Log.i(TAG, "start composition");
}
- compositor.startComposition(mEncodingSurface, codecInfo.mMaxW, codecInfo.mMaxH,
+ compositor.startComposition(mEncodingSurface, maxSize.getWidth(), maxSize.getHeight(),
numDisplays);
for (int j = 0; j < NUM_DISPLAY_CREATION; j++) {
if (DBG) {
@@ -453,7 +435,7 @@
virtualDisplays[k] =
new VirtualDisplayPresentation(getContext(),
compositor.getWindowSurface(k),
- codecInfo.mMaxW/numDisplays, codecInfo.mMaxH);
+ maxSize.getWidth()/numDisplays, maxSize.getHeight());
virtualDisplays[k].createVirtualDisplay();
virtualDisplays[k].createPresentation();
}
@@ -549,7 +531,7 @@
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mW, mH);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
- int bitRate = 10000000;
+ int bitRate = BITRATE_DEFAULT;
if (mW == 1920 && mH == 1080) {
bitRate = BITRATE_1080p;
} else if (mW == 1280 && mH == 720) {
@@ -1335,152 +1317,56 @@
}
}
- private static class CodecInfo {
- public int mMaxW;
- public int mMaxH;
- public int mFps;
- public int mBitRate;
- public String mCodecName;
- };
+ private static Size getMaxSupportedEncoderSize() {
+ final Size[] standardSizes = new Size[] {
+ new Size(1920, 1080),
+ new Size(1280, 720),
+ new Size(720, 480),
+ new Size(352, 576)
+ };
- /**
- * 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;
- }
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ for (Size sz : standardSizes) {
+ MediaFormat format = MediaFormat.createVideoFormat(
+ MIME_TYPE, sz.getWidth(), sz.getHeight());
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, 15); // require at least 15fps
+ if (mcl.findEncoderForFormat(format) != null) {
+ return sz;
}
}
return null;
}
- private static CodecInfo getAvcSupportedFormatInfo() {
- MediaCodecInfo mediaCodecInfo = selectCodec(MIME_TYPE);
- if (mediaCodecInfo == null) {
- return null;
- }
- CodecCapabilities cap = mediaCodecInfo.getCapabilitiesForType(MIME_TYPE);
- if (cap == null) { // not supported
- return null;
- }
- CodecInfo info = new CodecInfo();
- 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 null;
- case CodecProfileLevel.AVCLevel21:
- maxW = 352;
- maxH = 576;
- bitRate = 4000000;
- fps = 25;
- break;
- case CodecProfileLevel.AVCLevel22:
- maxW = 720;
- maxH = 480;
- bitRate = 4000000;
- fps = 15;
- break;
- case CodecProfileLevel.AVCLevel3:
- maxW = 720;
- maxH = 480;
- bitRate = 10000000;
- fps = 30;
- break;
- case CodecProfileLevel.AVCLevel31:
- maxW = 1280;
- maxH = 720;
- bitRate = 14000000;
- fps = 30;
- break;
- case CodecProfileLevel.AVCLevel32:
- maxW = 1280;
- maxH = 720;
- bitRate = 20000000;
- fps = 60;
- break;
- case CodecProfileLevel.AVCLevel4: // only try up to 1080p
- default:
- maxW = 1920;
- maxH = 1080;
- bitRate = 20000000;
- fps = 30;
- break;
- }
- info.mMaxW = maxW;
- info.mMaxH = maxH;
- info.mFps = fps;
- info.mBitRate = bitRate;
- info.mCodecName = mediaCodecInfo.getName();
- Log.i(TAG, "AVC Level 0x" + Integer.toHexString(highestLevel) + " bit rate " + bitRate +
- " fps " + info.mFps + " w " + maxW + " h " + maxH);
-
- return info;
- }
-
/**
* Check maximum concurrent encoding / decoding resolution allowed.
* Some H/Ws cannot support maximum resolution reported in encoder if decoder is running
* at the same time.
- * Check is done for 4 different levels: 1080p, 720p, 800x480 and max of encoder if is is
- * smaller than 800x480.
+ * Check is done for 4 different levels: 1080p, 720p, 800x480, 480p
+ * (The last one is required by CDD.)
*/
- private Pair<Integer, Integer> checkMaxConcurrentEncodingDecodingResolution() {
- CodecInfo codecInfo = getAvcSupportedFormatInfo();
- if (codecInfo == null) {
- return null;
+ private Size checkMaxConcurrentEncodingDecodingResolution() {
+ if (isConcurrentEncodingDecodingSupported(1920, 1080, BITRATE_1080p)) {
+ return new Size(1920, 1080);
+ } else if (isConcurrentEncodingDecodingSupported(1280, 720, BITRATE_720p)) {
+ return new Size(1280, 720);
+ } else if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
+ return new Size(800, 480);
+ } else if (isConcurrentEncodingDecodingSupported(720, 480, BITRATE_DEFAULT)) {
+ return new Size(720, 480);
}
- int maxW = codecInfo.mMaxW;
- int maxH = codecInfo.mMaxH;
- if (maxW >= 1920 && maxH >= 1080) {
- if (isConcurrentEncodingDecodingSupported(1920, 1080, BITRATE_1080p)) {
- return new Pair<Integer, Integer>(1920, 1080);
- }
- }
- if (maxW >= 1280 && maxH >= 720) {
- if (isConcurrentEncodingDecodingSupported(1280, 720, BITRATE_720p)) {
- return new Pair<Integer, Integer>(1280, 720);
- }
- }
- if (maxW >= 800 && maxH >= 480) {
- if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
- return new Pair<Integer, Integer>(800, 480);
- }
- }
- if (!isConcurrentEncodingDecodingSupported(codecInfo.mMaxW, codecInfo.mMaxH,
- codecInfo.mBitRate)) {
- fail("should work with advertised resolution");
- }
- return new Pair<Integer, Integer>(maxW, maxH);
+ Log.i(TAG, "SKIPPING test: concurrent encoding and decoding is not supported");
+ return null;
}
private boolean isConcurrentEncodingDecodingSupported(int w, int h, int bitRate) {
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ MediaFormat testFormat = MediaFormat.createVideoFormat(MIME_TYPE, w, h);
+ testFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
+ if (mcl.findDecoderForFormat(testFormat) == null
+ || mcl.findEncoderForFormat(testFormat) == null) {
+ return false;
+ }
+
MediaCodec decoder = null;
OutputSurface decodingSurface = null;
MediaCodec encoder = null;
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index c2e59d4..4b2a168 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -50,14 +50,14 @@
for (int j = 0; j < kBitRates.length; ++j) {
MediaFormat format = new MediaFormat();
- format.setString(MediaFormat.KEY_MIME, "audio/3gpp");
+ format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AMR_NB);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 8000);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates[j]);
formats.push(format);
}
- testEncoderWithFormats("audio/3gpp", formats);
+ testEncoderWithFormats(MediaFormat.MIMETYPE_AUDIO_AMR_NB, formats);
}
public void testAMRWBEncoders() {
@@ -68,14 +68,14 @@
for (int j = 0; j < kBitRates.length; ++j) {
MediaFormat format = new MediaFormat();
- format.setString(MediaFormat.KEY_MIME, "audio/amr-wb");
+ format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AMR_WB);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 16000);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates[j]);
formats.push(format);
}
- testEncoderWithFormats("audio/amr-wb", formats);
+ testEncoderWithFormats(MediaFormat.MIMETYPE_AUDIO_AMR_WB, formats);
}
public void testAACEncoders() {
@@ -99,7 +99,7 @@
for (int j = 0; j < kBitRates.length; ++j) {
for (int ch = 1; ch <= 2; ++ch) {
MediaFormat format = new MediaFormat();
- format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
+ format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AAC);
format.setInteger(
MediaFormat.KEY_AAC_PROFILE, kAACProfiles[k]);
@@ -115,7 +115,7 @@
}
}
- testEncoderWithFormats("audio/mp4a-latm", formats);
+ testEncoderWithFormats(MediaFormat.MIMETYPE_AUDIO_AAC, formats);
}
private void testEncoderWithFormats(
@@ -135,27 +135,13 @@
private List<String> getEncoderNamesForType(String mime) {
LinkedList<String> names = new LinkedList<String>();
- int n = MediaCodecList.getCodecCount();
- for (int i = 0; i < n; ++i) {
- MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
-
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ for (MediaCodecInfo info : mcl.getCodecInfos()) {
if (!info.isEncoder()) {
continue;
}
-
- if (!info.getName().startsWith("OMX.")) {
- // Unfortunately for legacy reasons, "AACEncoder", a
- // non OMX component had to be in this list for the video
- // editor code to work... but it cannot actually be instantiated
- // using MediaCodec.
- Log.d(TAG, "skipping '" + info.getName() + "'.");
- continue;
- }
-
- String[] supportedTypes = info.getSupportedTypes();
-
- for (int j = 0; j < supportedTypes.length; ++j) {
- if (supportedTypes[j].equalsIgnoreCase(mime)) {
+ for (String type : info.getSupportedTypes()) {
+ if (type.equalsIgnoreCase(mime)) {
names.push(info.getName());
break;
}
diff --git a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
index 43b769a..029a632 100644
--- a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
+++ b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
@@ -62,16 +62,18 @@
private static final File OUTPUT_FILENAME_DIR = Environment.getExternalStorageDirectory();
// parameters for the video encoder
- private static final String OUTPUT_VIDEO_MIME_TYPE = "video/avc"; // H.264 Advanced Video Coding
- private static final int OUTPUT_VIDEO_BIT_RATE = 2000000; // 2Mbps
- private static final int OUTPUT_VIDEO_FRAME_RATE = 15; // 15fps
+ // H.264 Advanced Video Coding
+ private static final String OUTPUT_VIDEO_MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
+ private static final int OUTPUT_VIDEO_BIT_RATE = 2000000; // 2Mbps
+ private static final int OUTPUT_VIDEO_FRAME_RATE = 15; // 15fps
private static final int OUTPUT_VIDEO_IFRAME_INTERVAL = 10; // 10 seconds between I-frames
private static final int OUTPUT_VIDEO_COLOR_FORMAT =
MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
// parameters for the audio encoder
- private static final String OUTPUT_AUDIO_MIME_TYPE = "audio/mp4a-latm"; // Advanced Audio Coding
- private static final int OUTPUT_AUDIO_CHANNEL_COUNT = 2; // Must match the input stream.
+ // Advanced Audio Coding
+ private static final String OUTPUT_AUDIO_MIME_TYPE = MediaFormat.MIMETYPE_AUDIO_AAC;
+ private static final int OUTPUT_AUDIO_CHANNEL_COUNT = 2; // Must match the input stream.
private static final int OUTPUT_AUDIO_BIT_RATE = 128 * 1024;
private static final int OUTPUT_AUDIO_AAC_PROFILE =
MediaCodecInfo.CodecProfileLevel.AACObjectHE;
@@ -259,21 +261,45 @@
// Exception that may be thrown during release.
Exception exception = null;
- MediaCodecInfo videoCodecInfo = selectCodec(OUTPUT_VIDEO_MIME_TYPE);
- if (videoCodecInfo == null) {
- // Don't fail CTS if they don't have an AVC codec (not here, anyway).
- Log.e(TAG, "Unable to find an appropriate codec for " + OUTPUT_VIDEO_MIME_TYPE);
- return;
- }
- if (VERBOSE) Log.d(TAG, "video found codec: " + videoCodecInfo.getName());
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
- MediaCodecInfo audioCodecInfo = selectCodec(OUTPUT_AUDIO_MIME_TYPE);
- if (audioCodecInfo == null) {
- // Don't fail CTS if they don't have an AAC codec (not here, anyway).
- Log.e(TAG, "Unable to find an appropriate codec for " + OUTPUT_AUDIO_MIME_TYPE);
+ // We avoid the device-specific limitations on width and height by using values
+ // that are multiples of 16, which all tested devices seem to be able to handle.
+ MediaFormat outputVideoFormat =
+ MediaFormat.createVideoFormat(OUTPUT_VIDEO_MIME_TYPE, mWidth, mHeight);
+
+ // Set some properties. Failing to specify some of these can cause the MediaCodec
+ // configure() call to throw an unhelpful exception.
+ outputVideoFormat.setInteger(
+ MediaFormat.KEY_COLOR_FORMAT, OUTPUT_VIDEO_COLOR_FORMAT);
+ outputVideoFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_VIDEO_BIT_RATE);
+ outputVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, OUTPUT_VIDEO_FRAME_RATE);
+ outputVideoFormat.setInteger(
+ MediaFormat.KEY_I_FRAME_INTERVAL, OUTPUT_VIDEO_IFRAME_INTERVAL);
+ if (VERBOSE) Log.d(TAG, "video format: " + outputVideoFormat);
+
+ String videoEncoderName = mcl.findEncoderForFormat(outputVideoFormat);
+ if (videoEncoderName == null) {
+ // Don't fail CTS if they don't have an AVC codec (not here, anyway).
+ Log.e(TAG, "Unable to find an appropriate codec for " + outputVideoFormat);
return;
}
- if (VERBOSE) Log.d(TAG, "audio found codec: " + audioCodecInfo.getName());
+ if (VERBOSE) Log.d(TAG, "video found codec: " + videoEncoderName);
+
+ MediaFormat outputAudioFormat =
+ MediaFormat.createAudioFormat(
+ OUTPUT_AUDIO_MIME_TYPE, OUTPUT_AUDIO_SAMPLE_RATE_HZ,
+ OUTPUT_AUDIO_CHANNEL_COUNT);
+ outputAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_AUDIO_BIT_RATE);
+ outputAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, OUTPUT_AUDIO_AAC_PROFILE);
+
+ String audioEncoderName = mcl.findEncoderForFormat(outputAudioFormat);
+ if (audioEncoderName == null) {
+ // Don't fail CTS if they don't have an AAC codec (not here, anyway).
+ Log.e(TAG, "Unable to find an appropriate codec for " + outputAudioFormat);
+ return;
+ }
+ if (VERBOSE) Log.d(TAG, "audio found codec: " + audioEncoderName);
MediaExtractor videoExtractor = null;
MediaExtractor audioExtractor = null;
@@ -293,32 +319,17 @@
assertTrue("missing video track in test video", videoInputTrack != -1);
MediaFormat inputFormat = videoExtractor.getTrackFormat(videoInputTrack);
- // We avoid the device-specific limitations on width and height by using values
- // that are multiples of 16, which all tested devices seem to be able to handle.
- MediaFormat outputVideoFormat =
- MediaFormat.createVideoFormat(OUTPUT_VIDEO_MIME_TYPE, mWidth, mHeight);
-
- // Set some properties. Failing to specify some of these can cause the MediaCodec
- // configure() call to throw an unhelpful exception.
- outputVideoFormat.setInteger(
- MediaFormat.KEY_COLOR_FORMAT, OUTPUT_VIDEO_COLOR_FORMAT);
- outputVideoFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_VIDEO_BIT_RATE);
- outputVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, OUTPUT_VIDEO_FRAME_RATE);
- outputVideoFormat.setInteger(
- MediaFormat.KEY_I_FRAME_INTERVAL, OUTPUT_VIDEO_IFRAME_INTERVAL);
- if (VERBOSE) Log.d(TAG, "video format: " + outputVideoFormat);
-
// Create a MediaCodec for the desired codec, then configure it as an encoder with
// our desired properties. Request a Surface to use for input.
AtomicReference<Surface> inputSurfaceReference = new AtomicReference<Surface>();
videoEncoder = createVideoEncoder(
- videoCodecInfo, outputVideoFormat, inputSurfaceReference);
+ videoEncoderName, outputVideoFormat, inputSurfaceReference);
inputSurface = new InputSurface(inputSurfaceReference.get());
inputSurface.makeCurrent();
// Create a MediaCodec for the decoder, based on the extractor's format.
outputSurface = new OutputSurface();
outputSurface.changeFragmentShader(FRAGMENT_SHADER);
- videoDecoder = createVideoDecoder(inputFormat, outputSurface.getSurface());
+ videoDecoder = createVideoDecoder(mcl, inputFormat, outputSurface.getSurface());
}
if (mCopyAudio) {
@@ -327,18 +338,11 @@
assertTrue("missing audio track in test video", audioInputTrack != -1);
MediaFormat inputFormat = audioExtractor.getTrackFormat(audioInputTrack);
- MediaFormat outputAudioFormat =
- MediaFormat.createAudioFormat(
- OUTPUT_AUDIO_MIME_TYPE, OUTPUT_AUDIO_SAMPLE_RATE_HZ,
- OUTPUT_AUDIO_CHANNEL_COUNT);
- outputAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_AUDIO_BIT_RATE);
- outputAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, OUTPUT_AUDIO_AAC_PROFILE);
-
// Create a MediaCodec for the desired codec, then configure it as an encoder with
// our desired properties. Request a Surface to use for input.
- audioEncoder = createAudioEncoder(audioCodecInfo, outputAudioFormat);
+ audioEncoder = createAudioEncoder(audioEncoderName, outputAudioFormat);
// Create a MediaCodec for the decoder, based on the extractor's format.
- audioDecoder = createAudioDecoder(inputFormat);
+ audioDecoder = createAudioDecoder(mcl, inputFormat);
}
// Creates a muxer but do not start or add tracks just yet.
@@ -517,9 +521,9 @@
* @param inputFormat the format of the stream to decode
* @param surface into which to decode the frames
*/
- private MediaCodec createVideoDecoder(MediaFormat inputFormat, Surface surface)
- throws IOException {
- MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
+ private MediaCodec createVideoDecoder(
+ MediaCodecList mcl, MediaFormat inputFormat, Surface surface) throws IOException {
+ MediaCodec decoder = MediaCodec.createByCodecName(mcl.findDecoderForFormat(inputFormat));
decoder.configure(inputFormat, surface, null, 0);
decoder.start();
return decoder;
@@ -536,11 +540,11 @@
* @param surfaceReference to store the surface to use as input
*/
private MediaCodec createVideoEncoder(
- MediaCodecInfo codecInfo,
+ String codecName,
MediaFormat format,
AtomicReference<Surface> surfaceReference)
throws IOException {
- MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
+ MediaCodec encoder = MediaCodec.createByCodecName(codecName);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
// Must be called before start() is.
surfaceReference.set(encoder.createInputSurface());
@@ -553,9 +557,9 @@
*
* @param inputFormat the format of the stream to decode
*/
- private MediaCodec createAudioDecoder(MediaFormat inputFormat)
- throws IOException {
- MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
+ private MediaCodec createAudioDecoder(
+ MediaCodecList mcl, MediaFormat inputFormat) throws IOException {
+ MediaCodec decoder = MediaCodec.createByCodecName(mcl.findDecoderForFormat(inputFormat));
decoder.configure(inputFormat, null, null, 0);
decoder.start();
return decoder;
@@ -567,9 +571,9 @@
* @param codecInfo of the codec to use
* @param format of the stream to be produced
*/
- private MediaCodec createAudioEncoder(MediaCodecInfo codecInfo, MediaFormat format)
+ private MediaCodec createAudioEncoder(String codecName, MediaFormat format)
throws IOException {
- MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
+ MediaCodec encoder = MediaCodec.createByCodecName(codecName);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
return encoder;
@@ -1126,28 +1130,4 @@
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;
- }
-
}
diff --git a/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
new file mode 100644
index 0000000..9515c22
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014 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.media.cts;
+
+import com.android.cts.media.R;
+
+import android.content.Context;
+import android.media.audiofx.AudioEffect;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.media.audiofx.LoudnessEnhancer;
+import android.os.Looper;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+public class LoudnessEnhancerTest extends PostProcTestBase {
+
+ private String TAG = "LoudnessEnhancerTest";
+ private LoudnessEnhancer mLE;
+
+ //-----------------------------------------------------------------
+ // LOUDNESS ENHANCER TESTS:
+ //----------------------------------
+
+ //-----------------------------------------------------------------
+ // 0 - constructor
+ //----------------------------------
+
+ //Test case 0.0: test constructor and release
+ public void test0_0ConstructorAndRelease() throws Exception {
+ if (!hasAudioOutput()) {
+ return;
+ }
+ AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+ assertNotNull("null AudioManager", am);
+ getLoudnessEnhancer(0);
+ releaseLoudnessEnhancer();
+
+ int session = am.generateAudioSessionId();
+ assertTrue("cannot generate new session", session != AudioManager.ERROR);
+ getLoudnessEnhancer(session);
+ releaseLoudnessEnhancer();
+ }
+
+ //-----------------------------------------------------------------
+ // 1 - get/set parameters
+ //----------------------------------
+
+ //Test case 1.0: test set/get target gain
+ public void test1_0TargetGain() throws Exception {
+ if (!hasAudioOutput()) {
+ return;
+ }
+ getLoudnessEnhancer(0);
+ try {
+ mLE.setTargetGain(0);
+ assertEquals("target gain differs from value set", 0, mLE.getTargetGain());
+ mLE.setTargetGain(800);
+ assertEquals("target gain differs from value set", 800, mLE.getTargetGain());
+ } catch (IllegalArgumentException e) {
+ fail("target gain illegal argument");
+ } catch (UnsupportedOperationException e) {
+ fail("target gain unsupported operation");
+ } catch (IllegalStateException e) {
+ fail("target gain operation called in wrong state");
+ } finally {
+ releaseLoudnessEnhancer();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // private methods
+ //----------------------------------
+ private void getLoudnessEnhancer(int session) {
+ releaseLoudnessEnhancer();
+ try {
+ mLE = new LoudnessEnhancer(session);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "getLoudnessEnhancer() LoudnessEnhancer not found exception: ", e);
+ } catch (UnsupportedOperationException e) {
+ Log.e(TAG, "getLoudnessEnhancer() Effect library not loaded exception: ", e);
+ }
+ assertNotNull("could not create LoudnessEnhancer", mLE);
+ }
+
+ private void releaseLoudnessEnhancer() {
+ if (mLE != null) {
+ mLE.release();
+ mLE = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
index 723652f..f966108 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
@@ -20,6 +20,7 @@
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecInfo.CodecProfileLevel;
import android.media.MediaCodecList;
+import android.media.MediaFormat;
import android.media.MediaPlayer;
import android.os.Build;
@@ -32,14 +33,94 @@
public class MediaCodecCapabilitiesTest extends MediaPlayerTestBase {
private static final String TAG = "MediaCodecCapabilitiesTest";
- private static final String AVC_MIME = "video/avc";
- private static final String HEVC_MIME = "video/hevc";
+ private static final String AVC_MIME = MediaFormat.MIMETYPE_VIDEO_AVC;
+ private static final String HEVC_MIME = MediaFormat.MIMETYPE_VIDEO_HEVC;
private static final int PLAY_TIME_MS = 30000;
+ // Android device implementations with H.264 encoders, MUST support Baseline Profile Level 3.
+ // SHOULD support Main Profile/ Level 4, if supported the device must also support Main
+ // Profile/Level 4 decoding.
+ public void testH264EncoderProfileAndLevel() throws Exception {
+ if (!hasH264(true /* isEncoder */)) {
+ Log.d(TAG, "SKIPPING testH264EncoderProfileAndLevel: No codec found.");
+ return;
+ }
+ boolean testLevel = true;
+ if (!supports(AVC_MIME, true /* isEncoder */, CodecProfileLevel.AVCProfileBaseline,
+ CodecProfileLevel.AVCLevel3, testLevel)) {
+ fail("H.264 Baseline Profile Level 3 support is required by CDD");
+ }
+
+ if (supports(AVC_MIME, true /* isEncoder */, CodecProfileLevel.AVCProfileMain,
+ CodecProfileLevel.AVCLevel4, testLevel)) {
+ if (!supports(AVC_MIME, false, CodecProfileLevel.AVCProfileMain,
+ CodecProfileLevel.AVCLevel4, testLevel)) {
+ fail("If H.264 Main Profile Level 4 encoding is supported, " +
+ "the device must also support is the same profile and level for decoding.");
+ }
+ }
+ }
+
+ // Android device implementations with H.264 decoders, MUST support Baseline Profile Level 3.
+ // Android Television Devices MUST support High Profile Level 4.2.
+ public void testH264DecoderProfileAndLevel() throws Exception {
+ if (!hasH264(false /* isEncoder */)) {
+ Log.d(TAG, "SKIPPING testH264DecoderProfileAndLevel: No codec found.");
+ return;
+ }
+ if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
+ CodecProfileLevel.AVCLevel3)) {
+ fail("H.264 Baseline Profile Level 3 support is required by CDD");
+ }
+ if (isTv()) {
+ if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileHigh,
+ CodecProfileLevel.AVCLevel42)) {
+ fail("H.264 High Profile Level 4.2 support is required by CDD for " +
+ "television devices");
+ }
+ }
+ }
+
+ // Android device implementations, when supporting H.265 codec MUST support the Main Profile
+ // Level 3 Main tier.
+ // Android Television Devices MUST support the Main Profile Level 4.1 Main tier.
+ // When the UHD video decoding profile is supported, it MUST support Main10 Level 5 Main
+ // Tier profile.
+ public void testH265DecoderProfileAndLevel() throws Exception {
+ MediaCodecInfo info = getMediaCodecInfo(HEVC_MIME, false /* isEncoder */);
+ if (info == null) {
+ Log.d(TAG, "SKIPPING testH265DecoderProfileAndLevel: No codec found.");
+ return;
+ }
+
+ if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
+ CodecProfileLevel.HEVCMainTierLevel3)) {
+ fail("H.265 Main Profile Level 3 Main tier support is required by CDD");
+ }
+ if (isTv()) {
+ if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
+ CodecProfileLevel.HEVCMainTierLevel41)) {
+ fail("H.265 Main Profile Level 4.1 Main tier support is required by CDD for " +
+ "television devices");
+ }
+ }
+
+ MediaCodecInfo.CodecCapabilities cCaps = info.getCapabilitiesForType(HEVC_MIME);
+ MediaCodecInfo.VideoCapabilities vCaps = cCaps.getVideoCapabilities();
+ if (vCaps.areSizeAndRateSupported(3840, 2160, 30)) {
+ if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain10,
+ CodecProfileLevel.HEVCMainTierLevel5)) {
+ fail("H.265 Main10 Level 5 Main Tier support is required by CDD when " +
+ "the UHD video decoding profile is supported");
+ }
+ }
+ }
+
+
public void testAvcBaseline1() throws Exception {
if (hasCodec(AVC_MIME) && !supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
CodecProfileLevel.AVCLevel1)) {
- throw new RuntimeException("AVCLevel1 support is required by CDD");
+ fail("AVCLevel1 support is required by CDD");
}
// We don't have a test stream, but at least we're testing
// that supports() returns true for something.
@@ -125,7 +206,7 @@
public void testHevcMain1() throws Exception {
if (hasCodec(HEVC_MIME) && !supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
CodecProfileLevel.HEVCMainTierLevel1)) {
- throw new RuntimeException("HECLevel1 support is required by CDD");
+ fail("HECLevel1 support is required by CDD");
}
// We don't have a test stream, but at least we're testing
// that supports() returns true for something.
@@ -195,18 +276,19 @@
}
private boolean supports(String mimeType, int profile) {
- return supports(mimeType, profile, 0, false);
+ return supports(mimeType, false /* isEncoder */, profile, 0, false);
}
private boolean supports(String mimeType, int profile, int level) {
- return supports(mimeType, profile, level, true);
+ return supports(mimeType, false /* isEncoder */, profile, level, true);
}
- private boolean supports(String mimeType, int profile, int level, boolean testLevel) {
+ private boolean supports(String mimeType, boolean isEncoder,
+ int profile, int level, boolean testLevel) {
int numCodecs = MediaCodecList.getCodecCount();
for (int i = 0; i < numCodecs; i++) {
MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
- if (codecInfo.isEncoder()) {
+ if (isEncoder != codecInfo.isEncoder()) {
continue;
}
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
index 865780e..1019f3f 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -257,21 +257,21 @@
}
int profile = CodecProfileLevel.H263ProfileBaseline;
- assertTrue(checkProfileSupported("video/3gpp", false, profile));
- assertTrue(checkProfileSupported("video/3gpp", true, profile));
+ assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_H263, false, profile));
+ assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_H263, true, profile));
}
// AVC baseline profile must be supported
public void testIsAVCBaselineProfileSupported() {
int profile = CodecProfileLevel.AVCProfileBaseline;
- assertTrue(checkProfileSupported("video/avc", false, profile));
- assertTrue(checkProfileSupported("video/avc", true, profile));
+ assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_AVC, false, profile));
+ assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_AVC, true, profile));
}
// HEVC main profile must be supported
public void testIsHEVCMainProfileSupported() {
int profile = CodecProfileLevel.HEVCProfileMain;
- assertTrue(checkProfileSupported("video/hevc", false, profile));
+ assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, false, profile));
}
// MPEG4 simple profile must be supported
@@ -282,10 +282,10 @@
}
int profile = CodecProfileLevel.MPEG4ProfileSimple;
- assertTrue(checkProfileSupported("video/mp4v-es", false, profile));
+ assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_MPEG4, false, profile));
// FIXME: no support for M4v simple profile video encoder
- // assertTrue(checkProfileSupported("video/mp4v-es", true, profile));
+ // assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_MPEG4, true, profile));
}
/*
@@ -375,29 +375,29 @@
List<CodecType> list = new ArrayList<CodecType>(16);
// Mandatory audio codecs
- list.add(new CodecType("audio/amr-wb", false)); // amrwb decoder
- list.add(new CodecType("audio/amr-wb", true)); // amrwb encoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_WB, false)); // amrwb decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_WB, true)); // amrwb encoder
// flac decoder is not omx-based yet
- // list.add(new CodecType("audio/flac", false)); // flac decoder
- list.add(new CodecType("audio/flac", true)); // flac encoder
- list.add(new CodecType("audio/mpeg", false)); // mp3 decoder
- list.add(new CodecType("audio/mp4a-latm", false)); // aac decoder
- list.add(new CodecType("audio/mp4a-latm", true)); // aac encoder
- list.add(new CodecType("audio/vorbis", false)); // vorbis decoder
- list.add(new CodecType("audio/3gpp", false)); // amrnb decoder
- list.add(new CodecType("audio/3gpp", true)); // amrnb encoder
+ // list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_FLAC, false)); // flac decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_FLAC, true)); // flac encoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_MPEG, false)); // mp3 decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AAC, false)); // aac decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AAC, true)); // aac encoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_VORBIS, false)); // vorbis decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_NB, false)); // amrnb decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_NB, true)); // amrnb encoder
// Mandatory video codecs
- list.add(new CodecType("video/avc", false)); // avc decoder
- list.add(new CodecType("video/avc", true)); // avc encoder
- list.add(new CodecType("video/hevc", false)); // hevc decoder
- list.add(new CodecType("video/3gpp", false)); // h263 decoder
- list.add(new CodecType("video/3gpp", true)); // h263 encoder
- list.add(new CodecType("video/mp4v-es", false)); // m4v decoder
- list.add(new CodecType("video/x-vnd.on2.vp8", false)); // vp8 decoder
- list.add(new CodecType("video/x-vnd.on2.vp8", true)); // vp8 encoder
- list.add(new CodecType("video/x-vnd.on2.vp9", false)); // vp9 decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_AVC, false)); // avc decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_AVC, true)); // avc encoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_HEVC, false)); // hevc decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_H263, false)); // h263 decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_H263, true)); // h263 encoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_MPEG4, false)); // m4v decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_VP8, false)); // vp8 decoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_VP8, true)); // vp8 encoder
+ list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_VP9, false)); // vp9 decoder
return list;
}
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index 5f8885d..33a0ee4 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -50,14 +50,15 @@
private static final boolean VERBOSE = false; // lots of logging
// parameters for the video encoder
- private static final String MIME_TYPE = "video/avc"; // H.264 Advanced Video Coding
+ // H.264 Advanced Video Coding
+ private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
private static final int BIT_RATE = 2000000; // 2Mbps
private static final int FRAME_RATE = 15; // 15fps
private static final int IFRAME_INTERVAL = 10; // 10 seconds between I-frames
private static final int WIDTH = 1280;
private static final int HEIGHT = 720;
// parameters for the audio encoder
- private static final String MIME_TYPE_AUDIO = "audio/mp4a-latm";
+ private static final String MIME_TYPE_AUDIO = MediaFormat.MIMETYPE_AUDIO_AAC;
private static final int AUDIO_SAMPLE_RATE = 44100;
private static final int AUDIO_AAC_PROFILE = 2; /* OMX_AUDIO_AACObjectLC */
private static final int AUDIO_CHANNEL_COUNT = 2; // mono
@@ -79,7 +80,7 @@
* methods when called in incorrect operational states.
*/
public void testException() throws Exception {
- String mimeType = "audio/amr-wb";
+ String mimeType = MediaFormat.MIMETYPE_AUDIO_AMR_WB;
if (!supportsCodec(mimeType, false)) {
Log.i(TAG, "No decoder found for mimeType= " + mimeType);
return;
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index 6591555..67eeca0 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -97,7 +97,7 @@
// Throws exception b/c start() is not called.
muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
- muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
+ muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
try {
muxer.stop();
@@ -108,10 +108,10 @@
// Throws exception b/c 2 video tracks were added.
muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
- muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
+ muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
try {
- muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
+ muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
fail("should throw IllegalStateException.");
} catch (IllegalStateException e) {
// expected
@@ -119,9 +119,9 @@
// Throws exception b/c 2 audio tracks were added.
muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
- muxer.addTrack(MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 1));
+ muxer.addTrack(MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 48000, 1));
try {
- muxer.addTrack(MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 1));
+ muxer.addTrack(MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 48000, 1));
fail("should throw IllegalStateException.");
} catch (IllegalStateException e) {
// expected
@@ -129,11 +129,11 @@
// Throws exception b/c 3 tracks were added.
muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
- muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
- muxer.addTrack(MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 1));
+ muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
+ muxer.addTrack(MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 48000, 1));
try {
- muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
+ muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
fail("should throw IllegalStateException.");
} catch (IllegalStateException e) {
// expected
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
index 92252033..986cd08 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
@@ -209,7 +209,7 @@
protected void playVideoTest(int resid, int width, int height) throws Exception {
if (!supportsPlayback(resid)) {
- LOG.info("SKIPPING playVideoTest() for resid=" + resid
+ LOG.info("SKIPPING playVideoTest() for resid=" + resid
+ " Could not find a codec for playback.");
return;
}
@@ -332,6 +332,21 @@
return false;
}
+ public static MediaCodecInfo getMediaCodecInfo(String mimeType, boolean isEncoder) {
+ MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ for (MediaCodecInfo info : list.getCodecInfos()) {
+ if (isEncoder != info.isEncoder()) {
+ continue;
+ }
+ for (String type : info.getSupportedTypes()) {
+ if (type.equalsIgnoreCase(mimeType)) {
+ return info;
+ }
+ }
+ }
+ return null;
+ }
+
public static boolean hasH264(boolean encoder) {
return hasCodecForMimeType("video/avc", encoder);
}
@@ -360,4 +375,25 @@
return getInstrumentation().getTargetContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
}
+
+ public boolean isTv() {
+ PackageManager packageManager = getInstrumentation().getTargetContext().getPackageManager();
+ return packageManager.hasSystemFeature("android.hardware.type.television") ||
+ packageManager.hasSystemFeature("android.software.leanback");
+ }
+
+ private static boolean isFormatSupported(
+ String mimeType, int w, int h, int frameRate, boolean isEncoder) {
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ MediaFormat format = MediaFormat.createVideoFormat(mimeType, w, h);
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
+ String codec = isEncoder
+ ? mcl.findEncoderForFormat(format)
+ : mcl.findDecoderForFormat(format);
+ return (codec != null);
+ }
+
+ public static boolean isDecodeFormatSupported(String mimeType, int w, int h, int frameRate) {
+ return isFormatSupported(mimeType, w, h, frameRate, false /* isEncoder */);
+ }
}
diff --git a/tests/tests/media/src/android/media/cts/OutputSurface.java b/tests/tests/media/src/android/media/cts/OutputSurface.java
index fc8ad9c..c87326d 100644
--- a/tests/tests/media/src/android/media/cts/OutputSurface.java
+++ b/tests/tests/media/src/android/media/cts/OutputSurface.java
@@ -70,7 +70,7 @@
eglSetup(width, height);
makeCurrent();
- setup();
+ setup(this);
}
/**
@@ -78,14 +78,18 @@
* new one). Creates a Surface that can be passed to MediaCodec.configure().
*/
public OutputSurface() {
- setup();
+ setup(this);
+ }
+
+ public OutputSurface(final SurfaceTexture.OnFrameAvailableListener listener) {
+ setup(listener);
}
/**
* Creates instances of TextureRender and SurfaceTexture, and a Surface associated
* with the SurfaceTexture.
*/
- private void setup() {
+ private void setup(SurfaceTexture.OnFrameAvailableListener listener) {
mTextureRender = new TextureRender();
mTextureRender.surfaceCreated();
@@ -107,7 +111,7 @@
//
// Java language note: passing "this" out of a constructor is generally unwise,
// but we should be able to get away with it here.
- mSurfaceTexture.setOnFrameAvailableListener(this);
+ mSurfaceTexture.setOnFrameAvailableListener(listener);
mSurface = new Surface(mSurfaceTexture);
}
@@ -285,6 +289,11 @@
mTextureRender.drawFrame(mSurfaceTexture);
}
+ public void latchImage() {
+ mTextureRender.checkGlError("before updateTexImage");
+ mSurfaceTexture.updateTexImage();
+ }
+
@Override
public void onFrameAvailable(SurfaceTexture st) {
if (VERBOSE) Log.d(TAG, "new frame available");
diff --git a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
new file mode 100644
index 0000000..f78f5f8
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
@@ -0,0 +1,1247 @@
+/*
+ * Copyright 2014 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.media.cts;
+
+import com.android.cts.media.R;
+
+import android.media.cts.CodecUtils;
+
+import android.cts.util.MediaUtils;
+import android.graphics.ImageFormat;
+import android.graphics.SurfaceTexture;
+import android.media.Image;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.VideoCapabilities;
+import android.media.MediaCodecList;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.net.Uri;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Range;
+import android.util.Size;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+public class VideoEncoderTest extends MediaPlayerTestBase {
+ private static final int MAX_SAMPLE_SIZE = 256 * 1024;
+ private static final String TAG = "VideoEncoderTest";
+ private static final long FRAME_TIMEOUT_MS = 1000;
+
+ private static final String SOURCE_URL =
+ "android.resource://com.android.cts.media/raw/video_480x360_mp4_h264_871kbps_30fps";
+
+ private final boolean DEBUG = false;
+
+ abstract class VideoProcessorBase extends MediaCodec.Callback {
+ private static final String TAG = "VideoProcessorBase";
+
+ private MediaExtractor mExtractor;
+ private ByteBuffer mBuffer = ByteBuffer.allocate(MAX_SAMPLE_SIZE);
+ private int mTrackIndex = -1;
+ private boolean mSignaledDecoderEOS;
+
+ protected boolean mCompleted;
+ protected final Object mCondition = new Object();
+
+ protected MediaFormat mDecFormat;
+ protected MediaCodec mDecoder, mEncoder;
+
+ protected void open(String path) throws IOException {
+ mExtractor = new MediaExtractor();
+ if (path.startsWith("android.resource://")) {
+ mExtractor.setDataSource(mContext, Uri.parse(path), null);
+ } else {
+ mExtractor.setDataSource(path);
+ }
+
+ for (int i = 0; i < mExtractor.getTrackCount(); i++) {
+ MediaFormat fmt = mExtractor.getTrackFormat(i);
+ String mime = fmt.getString(MediaFormat.KEY_MIME).toLowerCase();
+ if (mime.startsWith("video/")) {
+ mTrackIndex = i;
+ mDecFormat = fmt;
+ mExtractor.selectTrack(i);
+ break;
+ }
+ }
+ assertTrue("file " + path + " has no video", mTrackIndex >= 0);
+ }
+
+ // returns true if encoder supports the size
+ protected boolean initCodecsAndConfigureEncoder(
+ String videoEncName, String outMime, int width, int height, int colorFormat)
+ throws IOException {
+ mDecFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
+
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ String videoDecName = mcl.findDecoderForFormat(mDecFormat);
+ Log.i(TAG, "decoder for " + mDecFormat + " is " + videoDecName);
+ mDecoder = MediaCodec.createByCodecName(videoDecName);
+ mEncoder = MediaCodec.createByCodecName(videoEncName);
+
+ mDecoder.setCallback(this);
+ mEncoder.setCallback(this);
+
+ MediaCodecInfo.VideoCapabilities encCaps =
+ mEncoder.getCodecInfo().getCapabilitiesForType(outMime).getVideoCapabilities();
+ if (!encCaps.isSizeSupported(width, height)) {
+ Log.i(TAG, videoEncName + " does not support size: " + width + "x" + height);
+ return false;
+ }
+
+ MediaFormat outFmt = MediaFormat.createVideoFormat(outMime, width, height);
+
+ {
+ int maxWidth = encCaps.getSupportedWidths().getUpper();
+ int maxHeight = encCaps.getSupportedHeightsFor(maxWidth).getUpper();
+ int maxRate =
+ encCaps.getSupportedFrameRatesFor(maxWidth, maxHeight).getUpper().intValue();
+ outFmt.setInteger(MediaFormat.KEY_FRAME_RATE, Math.min(30, maxRate));
+ int bitRate = encCaps.getBitrateRange().clamp(
+ (int)(encCaps.getBitrateRange().getUpper() /
+ Math.sqrt(maxWidth * maxHeight / width / height)));
+ Log.d(TAG, "max rate = " + maxRate + ", bit rate = " + bitRate);
+ outFmt.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
+ }
+ outFmt.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
+ outFmt.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
+ mEncoder.configure(outFmt, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+ Log.i(TAG, "encoder input format " + mEncoder.getInputFormat() + " from " + outFmt);
+ return true;
+ }
+
+ protected void close() {
+ if (mDecoder != null) {
+ mDecoder.release();
+ mDecoder = null;
+ }
+ if (mEncoder != null) {
+ mEncoder.release();
+ mEncoder = null;
+ }
+ if (mExtractor != null) {
+ mExtractor.release();
+ mExtractor = null;
+ }
+ }
+
+ // returns true if filled buffer
+ protected boolean fillDecoderInputBuffer(int ix) {
+ if (DEBUG) Log.v(TAG, "decoder received input #" + ix);
+ while (!mSignaledDecoderEOS) {
+ int track = mExtractor.getSampleTrackIndex();
+ if (track >= 0 && track != mTrackIndex) {
+ mExtractor.advance();
+ continue;
+ }
+ int size = mExtractor.readSampleData(mBuffer, 0);
+ if (size < 0) {
+ // queue decoder input EOS
+ if (DEBUG) Log.v(TAG, "queuing decoder EOS");
+ mDecoder.queueInputBuffer(
+ ix, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+ mSignaledDecoderEOS = true;
+ } else {
+ mBuffer.limit(size);
+ mBuffer.position(0);
+ BufferInfo info = new BufferInfo();
+ info.set(
+ 0, mBuffer.limit(), mExtractor.getSampleTime(),
+ mExtractor.getSampleFlags());
+ mDecoder.getInputBuffer(ix).put(mBuffer);
+ if (DEBUG) Log.v(TAG, "queing input #" + ix + " for decoder with timestamp "
+ + info.presentationTimeUs);
+ mDecoder.queueInputBuffer(
+ ix, 0, mBuffer.limit(), info.presentationTimeUs, 0);
+ }
+ mExtractor.advance();
+ return true;
+ }
+ return false;
+ }
+
+ protected void emptyEncoderOutputBuffer(int ix, BufferInfo info) {
+ if (DEBUG) Log.v(TAG, "encoder received output #" + ix
+ + " (sz=" + info.size + ", f=" + info.flags
+ + ", ts=" + info.presentationTimeUs + ")");
+ if (!mCompleted) {
+ mEncoder.releaseOutputBuffer(ix, false);
+ if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+ Log.d(TAG, "encoder received output EOS");
+ synchronized(mCondition) {
+ mCompleted = true;
+ mCondition.notifyAll(); // condition is always satisfied
+ }
+ }
+ }
+ }
+
+ public abstract boolean processLoop(
+ String path, String outMime, String videoEncName,
+ int width, int height, boolean optional);
+ };
+
+ class VideoProcessor extends VideoProcessorBase {
+ private static final String TAG = "VideoProcessor";
+ private boolean mWorkInProgress;
+ private boolean mGotDecoderEOS;
+ private boolean mSignaledEncoderEOS;
+
+ private LinkedList<Pair<Integer, BufferInfo>> mBuffersToRender =
+ new LinkedList<Pair<Integer, BufferInfo>>();
+ private LinkedList<Integer> mEncInputBuffers = new LinkedList<Integer>();
+
+ private int mEncInputBufferSize = -1;
+
+ @Override
+ public boolean processLoop(
+ String path, String outMime, String videoEncName,
+ int width, int height, boolean optional) {
+ boolean skipped = true;
+ try {
+ open(path);
+ if (!initCodecsAndConfigureEncoder(
+ videoEncName, outMime, width, height,
+ CodecCapabilities.COLOR_FormatYUV420Flexible)) {
+ assertTrue("could not configure encoder for supported size", optional);
+ return !skipped;
+ }
+ skipped = false;
+
+ mDecoder.configure(mDecFormat, null /* surface */, null /* crypto */, 0);
+
+ mDecoder.start();
+ mEncoder.start();
+
+ // main loop - process GL ops as only main thread has GL context
+ while (!mCompleted) {
+ Pair<Integer, BufferInfo> decBuffer = null;
+ int encBuffer = -1;
+ synchronized (mCondition) {
+ try {
+ // wait for an encoder input buffer and a decoder output buffer
+ // Use a timeout to avoid stalling the test if it doesn't arrive.
+ if (!haveBuffers() && !mCompleted) {
+ mCondition.wait(FRAME_TIMEOUT_MS);
+ }
+ } catch (InterruptedException ie) {
+ fail("wait interrupted"); // shouldn't happen
+ }
+ if (mCompleted) {
+ break;
+ }
+ if (!haveBuffers()) {
+ fail("timed out after " + mBuffersToRender.size()
+ + " decoder output and " + mEncInputBuffers.size()
+ + " encoder input buffers");
+ }
+
+ if (DEBUG) Log.v(TAG, "got image");
+ decBuffer = mBuffersToRender.removeFirst();
+ encBuffer = mEncInputBuffers.removeFirst();
+ if (isEOSOnlyBuffer(decBuffer)) {
+ queueEncoderEOS(decBuffer, encBuffer);
+ continue;
+ }
+ mWorkInProgress = true;
+ }
+
+ if (mWorkInProgress) {
+ renderDecodedBuffer(decBuffer, encBuffer);
+ synchronized(mCondition) {
+ mWorkInProgress = false;
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail("received exception " + e);
+ } finally {
+ close();
+ }
+ return !skipped;
+ }
+
+ @Override
+ public void onInputBufferAvailable(MediaCodec mediaCodec, int ix) {
+ if (mediaCodec == mDecoder) {
+ // fill input buffer from extractor
+ fillDecoderInputBuffer(ix);
+ } else if (mediaCodec == mEncoder) {
+ synchronized(mCondition) {
+ mEncInputBuffers.addLast(ix);
+ tryToPropagateEOS();
+ if (haveBuffers()) {
+ mCondition.notifyAll();
+ }
+ }
+ } else {
+ fail("received input buffer on " + mediaCodec.getName());
+ }
+ }
+
+ @Override
+ public void onOutputBufferAvailable(
+ MediaCodec mediaCodec, int ix, BufferInfo info) {
+ if (mediaCodec == mDecoder) {
+ if (DEBUG) Log.v(TAG, "decoder received output #" + ix
+ + " (sz=" + info.size + ", f=" + info.flags
+ + ", ts=" + info.presentationTimeUs + ")");
+ // render output buffer from decoder
+ if (!mGotDecoderEOS) {
+ boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
+ // can release empty buffers now
+ if (info.size == 0) {
+ mDecoder.releaseOutputBuffer(ix, false /* render */);
+ ix = -1; // dummy index used by render to not render
+ }
+ synchronized(mCondition) {
+ if (ix < 0 && eos && mBuffersToRender.size() > 0) {
+ // move lone EOS flag to last buffer to be rendered
+ mBuffersToRender.peekLast().second.flags |=
+ MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+ } else if (ix >= 0 || eos) {
+ mBuffersToRender.addLast(Pair.create(ix, info));
+ }
+ if (eos) {
+ tryToPropagateEOS();
+ mGotDecoderEOS = true;
+ }
+ if (haveBuffers()) {
+ mCondition.notifyAll();
+ }
+ }
+ }
+ } else if (mediaCodec == mEncoder) {
+ emptyEncoderOutputBuffer(ix, info);
+ } else {
+ fail("received output buffer on " + mediaCodec.getName());
+ }
+ }
+
+ private void renderDecodedBuffer(Pair<Integer, BufferInfo> decBuffer, int encBuffer) {
+ // process heavyweight actions under instance lock
+ Image encImage = mEncoder.getInputImage(encBuffer);
+ Image decImage = mDecoder.getOutputImage(decBuffer.first);
+ assertNotNull("could not get encoder image for " + mEncoder.getInputFormat(), encImage);
+ assertNotNull("could not get decoder image for " + mDecoder.getInputFormat(), decImage);
+ assertEquals("incorrect decoder format",decImage.getFormat(), ImageFormat.YUV_420_888);
+ assertEquals("incorrect encoder format", encImage.getFormat(), ImageFormat.YUV_420_888);
+
+ CodecUtils.copyFlexYUVImage(encImage, decImage);
+
+ // TRICKY: need this for queueBuffer
+ if (mEncInputBufferSize < 0) {
+ mEncInputBufferSize = mEncoder.getInputBuffer(encBuffer).capacity();
+ }
+ Log.d(TAG, "queuing output #" + encBuffer + " for encoder (sz="
+ + mEncInputBufferSize + ", f=" + decBuffer.second.flags
+ + ", ts=" + decBuffer.second.presentationTimeUs + ")");
+ mEncoder.queueInputBuffer(
+ encBuffer, 0, mEncInputBufferSize, decBuffer.second.presentationTimeUs,
+ decBuffer.second.flags);
+ if ((decBuffer.second.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+ mSignaledEncoderEOS = true;
+ }
+ mDecoder.releaseOutputBuffer(decBuffer.first, false /* render */);
+ }
+
+ @Override
+ public void onError(MediaCodec mediaCodec, MediaCodec.CodecException e) {
+ fail("received error on " + mediaCodec.getName() + ": " + e);
+ }
+
+ @Override
+ public void onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat) {
+ Log.i(TAG, mediaCodec.getName() + " got new output format " + mediaFormat);
+ }
+
+ // next methods are synchronized on mCondition
+ private boolean haveBuffers() {
+ return mEncInputBuffers.size() > 0 && mBuffersToRender.size() > 0
+ && !mSignaledEncoderEOS;
+ }
+
+ private boolean isEOSOnlyBuffer(Pair<Integer, BufferInfo> decBuffer) {
+ return decBuffer.first < 0 || decBuffer.second.size == 0;
+ }
+
+ protected void tryToPropagateEOS() {
+ if (!mWorkInProgress && haveBuffers() && isEOSOnlyBuffer(mBuffersToRender.getFirst())) {
+ Pair<Integer, BufferInfo> decBuffer = mBuffersToRender.removeFirst();
+ int encBuffer = mEncInputBuffers.removeFirst();
+ queueEncoderEOS(decBuffer, encBuffer);
+ }
+ }
+
+ void queueEncoderEOS(Pair<Integer, BufferInfo> decBuffer, int encBuffer) {
+ Log.d(TAG, "signaling encoder EOS");
+ mEncoder.queueInputBuffer(encBuffer, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+ mSignaledEncoderEOS = true;
+ if (decBuffer.first >= 0) {
+ mDecoder.releaseOutputBuffer(decBuffer.first, false /* render */);
+ }
+ }
+ }
+
+
+ class SurfaceVideoProcessor extends VideoProcessorBase
+ implements SurfaceTexture.OnFrameAvailableListener {
+ private static final String TAG = "SurfaceVideoProcessor";
+ private boolean mFrameAvailable;
+ private boolean mGotDecoderEOS;
+ private boolean mSignaledEncoderEOS;
+
+ private InputSurface mEncSurface;
+ private OutputSurface mDecSurface;
+ private BufferInfo mInfoOnSurface;
+
+ private LinkedList<Pair<Integer, BufferInfo>> mBuffersToRender =
+ new LinkedList<Pair<Integer, BufferInfo>>();
+
+ @Override
+ public boolean processLoop(
+ String path, String outMime, String videoEncName,
+ int width, int height, boolean optional) {
+ boolean skipped = true;
+ try {
+ open(path);
+ if (!initCodecsAndConfigureEncoder(
+ videoEncName, outMime, width, height,
+ CodecCapabilities.COLOR_FormatSurface)) {
+ assertTrue("could not configure encoder for supported size", optional);
+ return !skipped;
+ }
+ skipped = false;
+
+ mEncSurface = new InputSurface(mEncoder.createInputSurface());
+ mEncSurface.makeCurrent();
+
+ mDecSurface = new OutputSurface(this);
+ //mDecSurface.changeFragmentShader(FRAGMENT_SHADER);
+ mDecoder.configure(mDecFormat, mDecSurface.getSurface(), null /* crypto */, 0);
+
+ mDecoder.start();
+ mEncoder.start();
+
+ // main loop - process GL ops as only main thread has GL context
+ while (!mCompleted) {
+ BufferInfo info = null;
+ synchronized (mCondition) {
+ try {
+ // wait for mFrameAvailable, which is set by onFrameAvailable().
+ // Use a timeout to avoid stalling the test if it doesn't arrive.
+ if (!mFrameAvailable && !mCompleted) {
+ mCondition.wait(FRAME_TIMEOUT_MS);
+ }
+ } catch (InterruptedException ie) {
+ fail("wait interrupted"); // shouldn't happen
+ }
+ if (mCompleted) {
+ break;
+ }
+ assertTrue("still waiting for image", mFrameAvailable);
+ if (DEBUG) Log.v(TAG, "got image");
+ info = mInfoOnSurface;
+ }
+ if (info == null) {
+ continue;
+ }
+ if (info.size > 0) {
+ mDecSurface.latchImage();
+ if (DEBUG) Log.v(TAG, "latched image");
+ mFrameAvailable = false;
+
+ mDecSurface.drawImage();
+ Log.d(TAG, "encoding frame at " + info.presentationTimeUs * 1000);
+
+ mEncSurface.setPresentationTime(info.presentationTimeUs * 1000);
+ mEncSurface.swapBuffers();
+ }
+ if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+ mSignaledEncoderEOS = true;
+ Log.d(TAG, "signaling encoder EOS");
+ mEncoder.signalEndOfInputStream();
+ }
+
+ synchronized (mCondition) {
+ mInfoOnSurface = null;
+ if (mBuffersToRender.size() > 0 && mInfoOnSurface == null) {
+ if (DEBUG) Log.v(TAG, "handling postponed frame");
+ Pair<Integer, BufferInfo> nextBuffer = mBuffersToRender.removeFirst();
+ renderDecodedBuffer(nextBuffer.first, nextBuffer.second);
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail("received exception " + e);
+ } finally {
+ close();
+ if (mEncSurface != null) {
+ mEncSurface.release();
+ mEncSurface = null;
+ }
+ if (mDecSurface != null) {
+ mDecSurface.release();
+ mDecSurface = null;
+ }
+ }
+ return !skipped;
+ }
+
+ @Override
+ public void onFrameAvailable(SurfaceTexture st) {
+ if (DEBUG) Log.v(TAG, "new frame available");
+ synchronized (mCondition) {
+ assertFalse("mFrameAvailable already set, frame could be dropped", mFrameAvailable);
+ mFrameAvailable = true;
+ mCondition.notifyAll();
+ }
+ }
+
+ @Override
+ public void onInputBufferAvailable(MediaCodec mediaCodec, int ix) {
+ if (mediaCodec == mDecoder) {
+ // fill input buffer from extractor
+ fillDecoderInputBuffer(ix);
+ } else {
+ fail("received input buffer on " + mediaCodec.getName());
+ }
+ }
+
+ @Override
+ public void onOutputBufferAvailable(
+ MediaCodec mediaCodec, int ix, BufferInfo info) {
+ if (mediaCodec == mDecoder) {
+ if (DEBUG) Log.v(TAG, "decoder received output #" + ix
+ + " (sz=" + info.size + ", f=" + info.flags
+ + ", ts=" + info.presentationTimeUs + ")");
+ // render output buffer from decoder
+ if (!mGotDecoderEOS) {
+ boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
+ if (eos) {
+ mGotDecoderEOS = true;
+ }
+ // can release empty buffers now
+ if (info.size == 0) {
+ mDecoder.releaseOutputBuffer(ix, false /* render */);
+ ix = -1; // dummy index used by render to not render
+ }
+ if (eos || info.size > 0) {
+ synchronized(mCondition) {
+ if (mInfoOnSurface != null || mBuffersToRender.size() > 0) {
+ if (DEBUG) Log.v(TAG, "postponing render, surface busy");
+ mBuffersToRender.addLast(Pair.create(ix, info));
+ } else {
+ renderDecodedBuffer(ix, info);
+ }
+ }
+ }
+ }
+ } else if (mediaCodec == mEncoder) {
+ emptyEncoderOutputBuffer(ix, info);
+ } else {
+ fail("received output buffer on " + mediaCodec.getName());
+ }
+ }
+
+ private void renderDecodedBuffer(int ix, BufferInfo info) {
+ boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
+ mInfoOnSurface = info;
+ if (info.size > 0) {
+ Log.d(TAG, "rendering frame #" + ix + " at " + info.presentationTimeUs * 1000
+ + (eos ? " with EOS" : ""));
+ mDecoder.releaseOutputBuffer(ix, info.presentationTimeUs * 1000);
+ }
+
+ if (eos && info.size == 0) {
+ if (DEBUG) Log.v(TAG, "decoder output EOS available");
+ mFrameAvailable = true;
+ mCondition.notifyAll();
+ }
+ }
+
+ @Override
+ public void onError(MediaCodec mediaCodec, MediaCodec.CodecException e) {
+ fail("received error on " + mediaCodec.getName() + ": " + e);
+ }
+
+ @Override
+ public void onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat) {
+ Log.i(TAG, mediaCodec.getName() + " got new output format " + mediaFormat);
+ }
+ }
+
+ class Encoder {
+ final private String mName;
+ final private String mMime;
+ final private VideoCapabilities mCaps;
+
+ final private Map<Size, Set<Size>> mMinMax; // extreme sizes
+ final private Map<Size, Set<Size>> mNearMinMax; // sizes near extreme
+ final private Set<Size> mArbitrary; // arbitrary sizes in the middle
+ final private Set<Size> mSizes; // all non-specifically tested sizes
+
+ final private int xAlign;
+ final private int yAlign;
+
+ Encoder(String name, String mime, CodecCapabilities caps) {
+ mName = name;
+ mMime = mime;
+ mCaps = caps.getVideoCapabilities();
+
+ /* calculate min/max sizes */
+ mMinMax = new HashMap<Size, Set<Size>>();
+ mNearMinMax = new HashMap<Size, Set<Size>>();
+ mArbitrary = new HashSet<Size>();
+ mSizes = new HashSet<Size>();
+
+ xAlign = mCaps.getWidthAlignment();
+ yAlign = mCaps.getHeightAlignment();
+
+ initializeSizes();
+ }
+
+ private void initializeSizes() {
+ for (int x = 0; x < 2; ++x) {
+ for (int y = 0; y < 2; ++y) {
+ addExtremeSizesFor(x, y);
+ }
+ }
+
+ // initialize arbitrary sizes
+ for (int i = 1; i <= 7; ++i) {
+ int j = ((7 * i) % 11) + 1;
+ int width = alignedPointInRange(i * 0.125, xAlign, mCaps.getSupportedWidths());
+ int height = alignedPointInRange(
+ j * 0.077, yAlign, mCaps.getSupportedHeightsFor(width));
+ mArbitrary.add(new Size(width, height));
+
+ height = alignedPointInRange(i * 0.125, yAlign, mCaps.getSupportedHeights());
+ width = alignedPointInRange(j * 0.077, xAlign, mCaps.getSupportedWidthsFor(height));
+ mArbitrary.add(new Size(width, height));
+ }
+ mArbitrary.removeAll(mSizes);
+ mSizes.addAll(mArbitrary);
+ if (DEBUG) Log.i(TAG, "arbitrary=" + mArbitrary);
+ }
+
+ private void addExtremeSizesFor(int x, int y) {
+ Set<Size> minMax = new HashSet<Size>();
+ Set<Size> nearMinMax = new HashSet<Size>();
+
+ for (int dx = 0; dx <= xAlign; dx += xAlign) {
+ for (int dy = 0; dy <= yAlign; dy += yAlign) {
+ Set<Size> bucket = (dx + dy == 0) ? minMax : nearMinMax;
+ try {
+ int width = getExtreme(mCaps.getSupportedWidths(), x, dx);
+ int height = getExtreme(mCaps.getSupportedHeightsFor(width), y, dy);
+ bucket.add(new Size(width, height));
+
+ // try max max with more reasonable ratio if too skewed
+ if (x + y == 2 && width >= 4 * height) {
+ Size wideScreen = getLargestSizeForRatio(16, 9);
+ width = getExtreme(
+ mCaps.getSupportedWidths()
+ .intersect(0, wideScreen.getWidth()), x, dx);
+ height = getExtreme(mCaps.getSupportedHeightsFor(width), y, 0);
+ bucket.add(new Size(width, height));
+ }
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ int height = getExtreme(mCaps.getSupportedHeights(), y, dy);
+ int width = getExtreme(mCaps.getSupportedWidthsFor(height), x, dx);
+ bucket.add(new Size(width, height));
+
+ // try max max with more reasonable ratio if too skewed
+ if (x + y == 2 && height >= 4 * width) {
+ Size wideScreen = getLargestSizeForRatio(9, 16);
+ height = getExtreme(
+ mCaps.getSupportedHeights()
+ .intersect(0, wideScreen.getHeight()), y, dy);
+ width = getExtreme(mCaps.getSupportedWidthsFor(height), x, dx);
+ bucket.add(new Size(width, height));
+ }
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ }
+
+ // keep unique sizes
+ minMax.removeAll(mSizes);
+ mSizes.addAll(minMax);
+ nearMinMax.removeAll(mSizes);
+ mSizes.addAll(nearMinMax);
+
+ mMinMax.put(new Size(x, y), minMax);
+ mNearMinMax.put(new Size(x, y), nearMinMax);
+ if (DEBUG) Log.i(TAG, x + "x" + y + ": minMax=" + mMinMax + ", near=" + mNearMinMax);
+ }
+
+ private int alignInRange(double value, int align, Range<Integer> range) {
+ return range.clamp(align * (int)Math.round(value / align));
+ }
+
+ /* point should be between 0. and 1. */
+ private int alignedPointInRange(double point, int align, Range<Integer> range) {
+ return alignInRange(
+ range.getLower() + point * (range.getUpper() - range.getLower()), align, range);
+ }
+
+ private int getExtreme(Range<Integer> range, int i, int delta) {
+ int dim = i == 1 ? range.getUpper() - delta : range.getLower() + delta;
+ if (delta == 0
+ || (dim > range.getLower() && dim < range.getUpper())) {
+ return dim;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ private Size getLargestSizeForRatio(int x, int y) {
+ Range<Integer> widthRange = mCaps.getSupportedWidths();
+ Range<Integer> heightRange = mCaps.getSupportedHeightsFor(widthRange.getUpper());
+ final int xAlign = mCaps.getWidthAlignment();
+ final int yAlign = mCaps.getHeightAlignment();
+
+ // scale by alignment
+ int width = alignInRange(
+ Math.sqrt(widthRange.getUpper() * heightRange.getUpper() * (double)x / y),
+ xAlign, widthRange);
+ int height = alignInRange(
+ width * (double)y / x, yAlign, mCaps.getSupportedHeightsFor(width));
+ return new Size(width, height);
+ }
+
+
+ public boolean testExtreme(int x, int y, boolean flexYUV, boolean near) {
+ boolean skipped = true;
+ for (Size s : (near ? mNearMinMax : mMinMax).get(new Size(x, y))) {
+ if (test(s.getWidth(), s.getHeight(), false /* optional */, flexYUV)) {
+ skipped = false;
+ }
+ }
+ return !skipped;
+ }
+
+ public boolean testArbitrary(boolean flexYUV) {
+ boolean skipped = true;
+ for (Size s : mArbitrary) {
+ if (test(s.getWidth(), s.getHeight(), false /* optional */, flexYUV)) {
+ skipped = false;
+ }
+ }
+ return !skipped;
+ }
+
+ public boolean testSpecific(int width, int height, boolean flexYUV) {
+ // already tested by one of the min/max tests
+ if (mSizes.contains(new Size(width, height))) {
+ return false;
+ }
+ return test(width, height, true /* optional */, flexYUV);
+ }
+
+ private boolean test(int width, int height, boolean optional, boolean flexYUV) {
+ Log.i(TAG, "testing " + mMime + " on " + mName + " for " + width + "x" + height
+ + (flexYUV ? " flexYUV" : " surface"));
+
+ VideoProcessorBase processor =
+ flexYUV ? new VideoProcessor() : new SurfaceVideoProcessor();
+
+ // We are using a resource URL as an example
+ return processor.processLoop(
+ SOURCE_URL, mMime, mName, width, height, optional);
+ }
+
+ }
+
+ private Encoder[] googH265() { return goog(MediaFormat.MIMETYPE_VIDEO_HEVC); }
+ private Encoder[] googH264() { return goog(MediaFormat.MIMETYPE_VIDEO_AVC); }
+ private Encoder[] googH263() { return goog(MediaFormat.MIMETYPE_VIDEO_H263); }
+ private Encoder[] googMpeg4() { return goog(MediaFormat.MIMETYPE_VIDEO_MPEG4); }
+ private Encoder[] googVP8() { return goog(MediaFormat.MIMETYPE_VIDEO_VP8); }
+ private Encoder[] googVP9() { return goog(MediaFormat.MIMETYPE_VIDEO_VP9); }
+
+ private Encoder[] otherH265() { return other(MediaFormat.MIMETYPE_VIDEO_HEVC); }
+ private Encoder[] otherH264() { return other(MediaFormat.MIMETYPE_VIDEO_AVC); }
+ private Encoder[] otherH263() { return other(MediaFormat.MIMETYPE_VIDEO_H263); }
+ private Encoder[] otherMpeg4() { return other(MediaFormat.MIMETYPE_VIDEO_MPEG4); }
+ private Encoder[] otherVP8() { return other(MediaFormat.MIMETYPE_VIDEO_VP8); }
+ private Encoder[] otherVP9() { return other(MediaFormat.MIMETYPE_VIDEO_VP9); }
+
+ private Encoder[] goog(String mime) {
+ return encoders(mime, true /* goog */);
+ }
+
+ private Encoder[] other(String mime) {
+ return encoders(mime, false /* goog */);
+ }
+
+ private Encoder[] encoders(String mime, boolean goog) {
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ ArrayList<Encoder> result = new ArrayList<Encoder>();
+
+ for (MediaCodecInfo info : mcl.getCodecInfos()) {
+ if (!info.isEncoder()
+ || info.getName().toLowerCase().startsWith("omx.google.") != goog) {
+ continue;
+ }
+ try {
+ CodecCapabilities caps = info.getCapabilitiesForType(mime);
+ result.add(new Encoder(info.getName(), mime, caps));
+ } catch (IllegalArgumentException e) { // mime is not supported
+ }
+ }
+ return result.toArray(new Encoder[result.size()]);
+ }
+
+ public void testGoogH265FlexMinMin() { minmin(googH265(), true /* flex */); }
+ public void testGoogH265SurfMinMin() { minmin(googH265(), false /* flex */); }
+ public void testGoogH264FlexMinMin() { minmin(googH264(), true /* flex */); }
+ public void testGoogH264SurfMinMin() { minmin(googH264(), false /* flex */); }
+ public void testGoogH263FlexMinMin() { minmin(googH263(), true /* flex */); }
+ public void testGoogH263SurfMinMin() { minmin(googH263(), false /* flex */); }
+ public void testGoogMpeg4FlexMinMin() { minmin(googMpeg4(), true /* flex */); }
+ public void testGoogMpeg4SurfMinMin() { minmin(googMpeg4(), false /* flex */); }
+ public void testGoogVP8FlexMinMin() { minmin(googVP8(), true /* flex */); }
+ public void testGoogVP8SurfMinMin() { minmin(googVP8(), false /* flex */); }
+ public void testGoogVP9FlexMinMin() { minmin(googVP9(), true /* flex */); }
+ public void testGoogVP9SurfMinMin() { minmin(googVP9(), false /* flex */); }
+
+ public void testOtherH265FlexMinMin() { minmin(otherH265(), true /* flex */); }
+ public void testOtherH265SurfMinMin() { minmin(otherH265(), false /* flex */); }
+ public void testOtherH264FlexMinMin() { minmin(otherH264(), true /* flex */); }
+ public void testOtherH264SurfMinMin() { minmin(otherH264(), false /* flex */); }
+ public void testOtherH263FlexMinMin() { minmin(otherH263(), true /* flex */); }
+ public void testOtherH263SurfMinMin() { minmin(otherH263(), false /* flex */); }
+ public void testOtherMpeg4FlexMinMin() { minmin(otherMpeg4(), true /* flex */); }
+ public void testOtherMpeg4SurfMinMin() { minmin(otherMpeg4(), false /* flex */); }
+ public void testOtherVP8FlexMinMin() { minmin(otherVP8(), true /* flex */); }
+ public void testOtherVP8SurfMinMin() { minmin(otherVP8(), false /* flex */); }
+ public void testOtherVP9FlexMinMin() { minmin(otherVP9(), true /* flex */); }
+ public void testOtherVP9SurfMinMin() { minmin(otherVP9(), false /* flex */); }
+
+ public void testGoogH265FlexMinMax() { minmax(googH265(), true /* flex */); }
+ public void testGoogH265SurfMinMax() { minmax(googH265(), false /* flex */); }
+ public void testGoogH264FlexMinMax() { minmax(googH264(), true /* flex */); }
+ public void testGoogH264SurfMinMax() { minmax(googH264(), false /* flex */); }
+ public void testGoogH263FlexMinMax() { minmax(googH263(), true /* flex */); }
+ public void testGoogH263SurfMinMax() { minmax(googH263(), false /* flex */); }
+ public void testGoogMpeg4FlexMinMax() { minmax(googMpeg4(), true /* flex */); }
+ public void testGoogMpeg4SurfMinMax() { minmax(googMpeg4(), false /* flex */); }
+ public void testGoogVP8FlexMinMax() { minmax(googVP8(), true /* flex */); }
+ public void testGoogVP8SurfMinMax() { minmax(googVP8(), false /* flex */); }
+ public void testGoogVP9FlexMinMax() { minmax(googVP9(), true /* flex */); }
+ public void testGoogVP9SurfMinMax() { minmax(googVP9(), false /* flex */); }
+
+ public void testOtherH265FlexMinMax() { minmax(otherH265(), true /* flex */); }
+ public void testOtherH265SurfMinMax() { minmax(otherH265(), false /* flex */); }
+ public void testOtherH264FlexMinMax() { minmax(otherH264(), true /* flex */); }
+ public void testOtherH264SurfMinMax() { minmax(otherH264(), false /* flex */); }
+ public void testOtherH263FlexMinMax() { minmax(otherH263(), true /* flex */); }
+ public void testOtherH263SurfMinMax() { minmax(otherH263(), false /* flex */); }
+ public void testOtherMpeg4FlexMinMax() { minmax(otherMpeg4(), true /* flex */); }
+ public void testOtherMpeg4SurfMinMax() { minmax(otherMpeg4(), false /* flex */); }
+ public void testOtherVP8FlexMinMax() { minmax(otherVP8(), true /* flex */); }
+ public void testOtherVP8SurfMinMax() { minmax(otherVP8(), false /* flex */); }
+ public void testOtherVP9FlexMinMax() { minmax(otherVP9(), true /* flex */); }
+ public void testOtherVP9SurfMinMax() { minmax(otherVP9(), false /* flex */); }
+
+ public void testGoogH265FlexMaxMin() { maxmin(googH265(), true /* flex */); }
+ public void testGoogH265SurfMaxMin() { maxmin(googH265(), false /* flex */); }
+ public void testGoogH264FlexMaxMin() { maxmin(googH264(), true /* flex */); }
+ public void testGoogH264SurfMaxMin() { maxmin(googH264(), false /* flex */); }
+ public void testGoogH263FlexMaxMin() { maxmin(googH263(), true /* flex */); }
+ public void testGoogH263SurfMaxMin() { maxmin(googH263(), false /* flex */); }
+ public void testGoogMpeg4FlexMaxMin() { maxmin(googMpeg4(), true /* flex */); }
+ public void testGoogMpeg4SurfMaxMin() { maxmin(googMpeg4(), false /* flex */); }
+ public void testGoogVP8FlexMaxMin() { maxmin(googVP8(), true /* flex */); }
+ public void testGoogVP8SurfMaxMin() { maxmin(googVP8(), false /* flex */); }
+ public void testGoogVP9FlexMaxMin() { maxmin(googVP9(), true /* flex */); }
+ public void testGoogVP9SurfMaxMin() { maxmin(googVP9(), false /* flex */); }
+
+ public void testOtherH265FlexMaxMin() { maxmin(otherH265(), true /* flex */); }
+ public void testOtherH265SurfMaxMin() { maxmin(otherH265(), false /* flex */); }
+ public void testOtherH264FlexMaxMin() { maxmin(otherH264(), true /* flex */); }
+ public void testOtherH264SurfMaxMin() { maxmin(otherH264(), false /* flex */); }
+ public void testOtherH263FlexMaxMin() { maxmin(otherH263(), true /* flex */); }
+ public void testOtherH263SurfMaxMin() { maxmin(otherH263(), false /* flex */); }
+ public void testOtherMpeg4FlexMaxMin() { maxmin(otherMpeg4(), true /* flex */); }
+ public void testOtherMpeg4SurfMaxMin() { maxmin(otherMpeg4(), false /* flex */); }
+ public void testOtherVP8FlexMaxMin() { maxmin(otherVP8(), true /* flex */); }
+ public void testOtherVP8SurfMaxMin() { maxmin(otherVP8(), false /* flex */); }
+ public void testOtherVP9FlexMaxMin() { maxmin(otherVP9(), true /* flex */); }
+ public void testOtherVP9SurfMaxMin() { maxmin(otherVP9(), false /* flex */); }
+
+ public void testGoogH265FlexMaxMax() { maxmax(googH265(), true /* flex */); }
+ public void testGoogH265SurfMaxMax() { maxmax(googH265(), false /* flex */); }
+ public void testGoogH264FlexMaxMax() { maxmax(googH264(), true /* flex */); }
+ public void testGoogH264SurfMaxMax() { maxmax(googH264(), false /* flex */); }
+ public void testGoogH263FlexMaxMax() { maxmax(googH263(), true /* flex */); }
+ public void testGoogH263SurfMaxMax() { maxmax(googH263(), false /* flex */); }
+ public void testGoogMpeg4FlexMaxMax() { maxmax(googMpeg4(), true /* flex */); }
+ public void testGoogMpeg4SurfMaxMax() { maxmax(googMpeg4(), false /* flex */); }
+ public void testGoogVP8FlexMaxMax() { maxmax(googVP8(), true /* flex */); }
+ public void testGoogVP8SurfMaxMax() { maxmax(googVP8(), false /* flex */); }
+ public void testGoogVP9FlexMaxMax() { maxmax(googVP9(), true /* flex */); }
+ public void testGoogVP9SurfMaxMax() { maxmax(googVP9(), false /* flex */); }
+
+ public void testOtherH265FlexMaxMax() { maxmax(otherH265(), true /* flex */); }
+ public void testOtherH265SurfMaxMax() { maxmax(otherH265(), false /* flex */); }
+ public void testOtherH264FlexMaxMax() { maxmax(otherH264(), true /* flex */); }
+ public void testOtherH264SurfMaxMax() { maxmax(otherH264(), false /* flex */); }
+ public void testOtherH263FlexMaxMax() { maxmax(otherH263(), true /* flex */); }
+ public void testOtherH263SurfMaxMax() { maxmax(otherH263(), false /* flex */); }
+ public void testOtherMpeg4FlexMaxMax() { maxmax(otherMpeg4(), true /* flex */); }
+ public void testOtherMpeg4SurfMaxMax() { maxmax(otherMpeg4(), false /* flex */); }
+ public void testOtherVP8FlexMaxMax() { maxmax(otherVP8(), true /* flex */); }
+ public void testOtherVP8SurfMaxMax() { maxmax(otherVP8(), false /* flex */); }
+ public void testOtherVP9FlexMaxMax() { maxmax(otherVP9(), true /* flex */); }
+ public void testOtherVP9SurfMaxMax() { maxmax(otherVP9(), false /* flex */); }
+
+ public void testGoogH265FlexNearMinMin() { nearminmin(googH265(), true /* flex */); }
+ public void testGoogH265SurfNearMinMin() { nearminmin(googH265(), false /* flex */); }
+ public void testGoogH264FlexNearMinMin() { nearminmin(googH264(), true /* flex */); }
+ public void testGoogH264SurfNearMinMin() { nearminmin(googH264(), false /* flex */); }
+ public void testGoogH263FlexNearMinMin() { nearminmin(googH263(), true /* flex */); }
+ public void testGoogH263SurfNearMinMin() { nearminmin(googH263(), false /* flex */); }
+ public void testGoogMpeg4FlexNearMinMin() { nearminmin(googMpeg4(), true /* flex */); }
+ public void testGoogMpeg4SurfNearMinMin() { nearminmin(googMpeg4(), false /* flex */); }
+ public void testGoogVP8FlexNearMinMin() { nearminmin(googVP8(), true /* flex */); }
+ public void testGoogVP8SurfNearMinMin() { nearminmin(googVP8(), false /* flex */); }
+ public void testGoogVP9FlexNearMinMin() { nearminmin(googVP9(), true /* flex */); }
+ public void testGoogVP9SurfNearMinMin() { nearminmin(googVP9(), false /* flex */); }
+
+ public void testOtherH265FlexNearMinMin() { nearminmin(otherH265(), true /* flex */); }
+ public void testOtherH265SurfNearMinMin() { nearminmin(otherH265(), false /* flex */); }
+ public void testOtherH264FlexNearMinMin() { nearminmin(otherH264(), true /* flex */); }
+ public void testOtherH264SurfNearMinMin() { nearminmin(otherH264(), false /* flex */); }
+ public void testOtherH263FlexNearMinMin() { nearminmin(otherH263(), true /* flex */); }
+ public void testOtherH263SurfNearMinMin() { nearminmin(otherH263(), false /* flex */); }
+ public void testOtherMpeg4FlexNearMinMin() { nearminmin(otherMpeg4(), true /* flex */); }
+ public void testOtherMpeg4SurfNearMinMin() { nearminmin(otherMpeg4(), false /* flex */); }
+ public void testOtherVP8FlexNearMinMin() { nearminmin(otherVP8(), true /* flex */); }
+ public void testOtherVP8SurfNearMinMin() { nearminmin(otherVP8(), false /* flex */); }
+ public void testOtherVP9FlexNearMinMin() { nearminmin(otherVP9(), true /* flex */); }
+ public void testOtherVP9SurfNearMinMin() { nearminmin(otherVP9(), false /* flex */); }
+
+ public void testGoogH265FlexNearMinMax() { nearminmax(googH265(), true /* flex */); }
+ public void testGoogH265SurfNearMinMax() { nearminmax(googH265(), false /* flex */); }
+ public void testGoogH264FlexNearMinMax() { nearminmax(googH264(), true /* flex */); }
+ public void testGoogH264SurfNearMinMax() { nearminmax(googH264(), false /* flex */); }
+ public void testGoogH263FlexNearMinMax() { nearminmax(googH263(), true /* flex */); }
+ public void testGoogH263SurfNearMinMax() { nearminmax(googH263(), false /* flex */); }
+ public void testGoogMpeg4FlexNearMinMax() { nearminmax(googMpeg4(), true /* flex */); }
+ public void testGoogMpeg4SurfNearMinMax() { nearminmax(googMpeg4(), false /* flex */); }
+ public void testGoogVP8FlexNearMinMax() { nearminmax(googVP8(), true /* flex */); }
+ public void testGoogVP8SurfNearMinMax() { nearminmax(googVP8(), false /* flex */); }
+ public void testGoogVP9FlexNearMinMax() { nearminmax(googVP9(), true /* flex */); }
+ public void testGoogVP9SurfNearMinMax() { nearminmax(googVP9(), false /* flex */); }
+
+ public void testOtherH265FlexNearMinMax() { nearminmax(otherH265(), true /* flex */); }
+ public void testOtherH265SurfNearMinMax() { nearminmax(otherH265(), false /* flex */); }
+ public void testOtherH264FlexNearMinMax() { nearminmax(otherH264(), true /* flex */); }
+ public void testOtherH264SurfNearMinMax() { nearminmax(otherH264(), false /* flex */); }
+ public void testOtherH263FlexNearMinMax() { nearminmax(otherH263(), true /* flex */); }
+ public void testOtherH263SurfNearMinMax() { nearminmax(otherH263(), false /* flex */); }
+ public void testOtherMpeg4FlexNearMinMax() { nearminmax(otherMpeg4(), true /* flex */); }
+ public void testOtherMpeg4SurfNearMinMax() { nearminmax(otherMpeg4(), false /* flex */); }
+ public void testOtherVP8FlexNearMinMax() { nearminmax(otherVP8(), true /* flex */); }
+ public void testOtherVP8SurfNearMinMax() { nearminmax(otherVP8(), false /* flex */); }
+ public void testOtherVP9FlexNearMinMax() { nearminmax(otherVP9(), true /* flex */); }
+ public void testOtherVP9SurfNearMinMax() { nearminmax(otherVP9(), false /* flex */); }
+
+ public void testGoogH265FlexNearMaxMin() { nearmaxmin(googH265(), true /* flex */); }
+ public void testGoogH265SurfNearMaxMin() { nearmaxmin(googH265(), false /* flex */); }
+ public void testGoogH264FlexNearMaxMin() { nearmaxmin(googH264(), true /* flex */); }
+ public void testGoogH264SurfNearMaxMin() { nearmaxmin(googH264(), false /* flex */); }
+ public void testGoogH263FlexNearMaxMin() { nearmaxmin(googH263(), true /* flex */); }
+ public void testGoogH263SurfNearMaxMin() { nearmaxmin(googH263(), false /* flex */); }
+ public void testGoogMpeg4FlexNearMaxMin() { nearmaxmin(googMpeg4(), true /* flex */); }
+ public void testGoogMpeg4SurfNearMaxMin() { nearmaxmin(googMpeg4(), false /* flex */); }
+ public void testGoogVP8FlexNearMaxMin() { nearmaxmin(googVP8(), true /* flex */); }
+ public void testGoogVP8SurfNearMaxMin() { nearmaxmin(googVP8(), false /* flex */); }
+ public void testGoogVP9FlexNearMaxMin() { nearmaxmin(googVP9(), true /* flex */); }
+ public void testGoogVP9SurfNearMaxMin() { nearmaxmin(googVP9(), false /* flex */); }
+
+ public void testOtherH265FlexNearMaxMin() { nearmaxmin(otherH265(), true /* flex */); }
+ public void testOtherH265SurfNearMaxMin() { nearmaxmin(otherH265(), false /* flex */); }
+ public void testOtherH264FlexNearMaxMin() { nearmaxmin(otherH264(), true /* flex */); }
+ public void testOtherH264SurfNearMaxMin() { nearmaxmin(otherH264(), false /* flex */); }
+ public void testOtherH263FlexNearMaxMin() { nearmaxmin(otherH263(), true /* flex */); }
+ public void testOtherH263SurfNearMaxMin() { nearmaxmin(otherH263(), false /* flex */); }
+ public void testOtherMpeg4FlexNearMaxMin() { nearmaxmin(otherMpeg4(), true /* flex */); }
+ public void testOtherMpeg4SurfNearMaxMin() { nearmaxmin(otherMpeg4(), false /* flex */); }
+ public void testOtherVP8FlexNearMaxMin() { nearmaxmin(otherVP8(), true /* flex */); }
+ public void testOtherVP8SurfNearMaxMin() { nearmaxmin(otherVP8(), false /* flex */); }
+ public void testOtherVP9FlexNearMaxMin() { nearmaxmin(otherVP9(), true /* flex */); }
+ public void testOtherVP9SurfNearMaxMin() { nearmaxmin(otherVP9(), false /* flex */); }
+
+ public void testGoogH265FlexNearMaxMax() { nearmaxmax(googH265(), true /* flex */); }
+ public void testGoogH265SurfNearMaxMax() { nearmaxmax(googH265(), false /* flex */); }
+ public void testGoogH264FlexNearMaxMax() { nearmaxmax(googH264(), true /* flex */); }
+ public void testGoogH264SurfNearMaxMax() { nearmaxmax(googH264(), false /* flex */); }
+ public void testGoogH263FlexNearMaxMax() { nearmaxmax(googH263(), true /* flex */); }
+ public void testGoogH263SurfNearMaxMax() { nearmaxmax(googH263(), false /* flex */); }
+ public void testGoogMpeg4FlexNearMaxMax() { nearmaxmax(googMpeg4(), true /* flex */); }
+ public void testGoogMpeg4SurfNearMaxMax() { nearmaxmax(googMpeg4(), false /* flex */); }
+ public void testGoogVP8FlexNearMaxMax() { nearmaxmax(googVP8(), true /* flex */); }
+ public void testGoogVP8SurfNearMaxMax() { nearmaxmax(googVP8(), false /* flex */); }
+ public void testGoogVP9FlexNearMaxMax() { nearmaxmax(googVP9(), true /* flex */); }
+ public void testGoogVP9SurfNearMaxMax() { nearmaxmax(googVP9(), false /* flex */); }
+
+ public void testOtherH265FlexNearMaxMax() { nearmaxmax(otherH265(), true /* flex */); }
+ public void testOtherH265SurfNearMaxMax() { nearmaxmax(otherH265(), false /* flex */); }
+ public void testOtherH264FlexNearMaxMax() { nearmaxmax(otherH264(), true /* flex */); }
+ public void testOtherH264SurfNearMaxMax() { nearmaxmax(otherH264(), false /* flex */); }
+ public void testOtherH263FlexNearMaxMax() { nearmaxmax(otherH263(), true /* flex */); }
+ public void testOtherH263SurfNearMaxMax() { nearmaxmax(otherH263(), false /* flex */); }
+ public void testOtherMpeg4FlexNearMaxMax() { nearmaxmax(otherMpeg4(), true /* flex */); }
+ public void testOtherMpeg4SurfNearMaxMax() { nearmaxmax(otherMpeg4(), false /* flex */); }
+ public void testOtherVP8FlexNearMaxMax() { nearmaxmax(otherVP8(), true /* flex */); }
+ public void testOtherVP8SurfNearMaxMax() { nearmaxmax(otherVP8(), false /* flex */); }
+ public void testOtherVP9FlexNearMaxMax() { nearmaxmax(otherVP9(), true /* flex */); }
+ public void testOtherVP9SurfNearMaxMax() { nearmaxmax(otherVP9(), false /* flex */); }
+
+ public void testGoogH265FlexArbitrary() { arbitrary(googH265(), true /* flex */); }
+ public void testGoogH265SurfArbitrary() { arbitrary(googH265(), false /* flex */); }
+ public void testGoogH264FlexArbitrary() { arbitrary(googH264(), true /* flex */); }
+ public void testGoogH264SurfArbitrary() { arbitrary(googH264(), false /* flex */); }
+ public void testGoogH263FlexArbitrary() { arbitrary(googH263(), true /* flex */); }
+ public void testGoogH263SurfArbitrary() { arbitrary(googH263(), false /* flex */); }
+ public void testGoogMpeg4FlexArbitrary() { arbitrary(googMpeg4(), true /* flex */); }
+ public void testGoogMpeg4SurfArbitrary() { arbitrary(googMpeg4(), false /* flex */); }
+ public void testGoogVP8FlexArbitrary() { arbitrary(googVP8(), true /* flex */); }
+ public void testGoogVP8SurfArbitrary() { arbitrary(googVP8(), false /* flex */); }
+ public void testGoogVP9FlexArbitrary() { arbitrary(googVP9(), true /* flex */); }
+ public void testGoogVP9SurfArbitrary() { arbitrary(googVP9(), false /* flex */); }
+
+ public void testOtherH265FlexArbitrary() { arbitrary(otherH265(), true /* flex */); }
+ public void testOtherH265SurfArbitrary() { arbitrary(otherH265(), false /* flex */); }
+ public void testOtherH264FlexArbitrary() { arbitrary(otherH264(), true /* flex */); }
+ public void testOtherH264SurfArbitrary() { arbitrary(otherH264(), false /* flex */); }
+ public void testOtherH263FlexArbitrary() { arbitrary(otherH263(), true /* flex */); }
+ public void testOtherH263SurfArbitrary() { arbitrary(otherH263(), false /* flex */); }
+ public void testOtherMpeg4FlexArbitrary() { arbitrary(otherMpeg4(), true /* flex */); }
+ public void testOtherMpeg4SurfArbitrary() { arbitrary(otherMpeg4(), false /* flex */); }
+ public void testOtherVP8FlexArbitrary() { arbitrary(otherVP8(), true /* flex */); }
+ public void testOtherVP8SurfArbitrary() { arbitrary(otherVP8(), false /* flex */); }
+ public void testOtherVP9FlexArbitrary() { arbitrary(otherVP9(), true /* flex */); }
+ public void testOtherVP9SurfArbitrary() { arbitrary(otherVP9(), false /* flex */); }
+
+ public void testGoogH265FlexQCIF() { specific(googH265(), 176, 144, true /* flex */); }
+ public void testGoogH265SurfQCIF() { specific(googH265(), 176, 144, false /* flex */); }
+ public void testGoogH264FlexQCIF() { specific(googH264(), 176, 144, true /* flex */); }
+ public void testGoogH264SurfQCIF() { specific(googH264(), 176, 144, false /* flex */); }
+ public void testGoogH263FlexQCIF() { specific(googH263(), 176, 144, true /* flex */); }
+ public void testGoogH263SurfQCIF() { specific(googH263(), 176, 144, false /* flex */); }
+ public void testGoogMpeg4FlexQCIF() { specific(googMpeg4(), 176, 144, true /* flex */); }
+ public void testGoogMpeg4SurfQCIF() { specific(googMpeg4(), 176, 144, false /* flex */); }
+ public void testGoogVP8FlexQCIF() { specific(googVP8(), 176, 144, true /* flex */); }
+ public void testGoogVP8SurfQCIF() { specific(googVP8(), 176, 144, false /* flex */); }
+ public void testGoogVP9FlexQCIF() { specific(googVP9(), 176, 144, true /* flex */); }
+ public void testGoogVP9SurfQCIF() { specific(googVP9(), 176, 144, false /* flex */); }
+
+ public void testOtherH265FlexQCIF() { specific(otherH265(), 176, 144, true /* flex */); }
+ public void testOtherH265SurfQCIF() { specific(otherH265(), 176, 144, false /* flex */); }
+ public void testOtherH264FlexQCIF() { specific(otherH264(), 176, 144, true /* flex */); }
+ public void testOtherH264SurfQCIF() { specific(otherH264(), 176, 144, false /* flex */); }
+ public void testOtherH263FlexQCIF() { specific(otherH263(), 176, 144, true /* flex */); }
+ public void testOtherH263SurfQCIF() { specific(otherH263(), 176, 144, false /* flex */); }
+ public void testOtherMpeg4FlexQCIF() { specific(otherMpeg4(), 176, 144, true /* flex */); }
+ public void testOtherMpeg4SurfQCIF() { specific(otherMpeg4(), 176, 144, false /* flex */); }
+ public void testOtherVP8FlexQCIF() { specific(otherVP8(), 176, 144, true /* flex */); }
+ public void testOtherVP8SurfQCIF() { specific(otherVP8(), 176, 144, false /* flex */); }
+ public void testOtherVP9FlexQCIF() { specific(otherVP9(), 176, 144, true /* flex */); }
+ public void testOtherVP9SurfQCIF() { specific(otherVP9(), 176, 144, false /* flex */); }
+
+ public void testGoogH265Flex480p() { specific(googH265(), 720, 480, true /* flex */); }
+ public void testGoogH265Surf480p() { specific(googH265(), 720, 480, false /* flex */); }
+ public void testGoogH264Flex480p() { specific(googH264(), 720, 480, true /* flex */); }
+ public void testGoogH264Surf480p() { specific(googH264(), 720, 480, false /* flex */); }
+ public void testGoogH263Flex480p() { specific(googH263(), 720, 480, true /* flex */); }
+ public void testGoogH263Surf480p() { specific(googH263(), 720, 480, false /* flex */); }
+ public void testGoogMpeg4Flex480p() { specific(googMpeg4(), 720, 480, true /* flex */); }
+ public void testGoogMpeg4Surf480p() { specific(googMpeg4(), 720, 480, false /* flex */); }
+ public void testGoogVP8Flex480p() { specific(googVP8(), 720, 480, true /* flex */); }
+ public void testGoogVP8Surf480p() { specific(googVP8(), 720, 480, false /* flex */); }
+ public void testGoogVP9Flex480p() { specific(googVP9(), 720, 480, true /* flex */); }
+ public void testGoogVP9Surf480p() { specific(googVP9(), 720, 480, false /* flex */); }
+
+ public void testOtherH265Flex480p() { specific(otherH265(), 720, 480, true /* flex */); }
+ public void testOtherH265Surf480p() { specific(otherH265(), 720, 480, false /* flex */); }
+ public void testOtherH264Flex480p() { specific(otherH264(), 720, 480, true /* flex */); }
+ public void testOtherH264Surf480p() { specific(otherH264(), 720, 480, false /* flex */); }
+ public void testOtherH263Flex480p() { specific(otherH263(), 720, 480, true /* flex */); }
+ public void testOtherH263Surf480p() { specific(otherH263(), 720, 480, false /* flex */); }
+ public void testOtherMpeg4Flex480p() { specific(otherMpeg4(), 720, 480, true /* flex */); }
+ public void testOtherMpeg4Surf480p() { specific(otherMpeg4(), 720, 480, false /* flex */); }
+ public void testOtherVP8Flex480p() { specific(otherVP8(), 720, 480, true /* flex */); }
+ public void testOtherVP8Surf480p() { specific(otherVP8(), 720, 480, false /* flex */); }
+ public void testOtherVP9Flex480p() { specific(otherVP9(), 720, 480, true /* flex */); }
+ public void testOtherVP9Surf480p() { specific(otherVP9(), 720, 480, false /* flex */); }
+
+ // even though H.263 and MPEG-4 are not defined for 720p or 1080p
+ // test for it, in case device claims support for it.
+
+ public void testGoogH265Flex720p() { specific(googH265(), 1280, 720, true /* flex */); }
+ public void testGoogH265Surf720p() { specific(googH265(), 1280, 720, false /* flex */); }
+ public void testGoogH264Flex720p() { specific(googH264(), 1280, 720, true /* flex */); }
+ public void testGoogH264Surf720p() { specific(googH264(), 1280, 720, false /* flex */); }
+ public void testGoogH263Flex720p() { specific(googH263(), 1280, 720, true /* flex */); }
+ public void testGoogH263Surf720p() { specific(googH263(), 1280, 720, false /* flex */); }
+ public void testGoogMpeg4Flex720p() { specific(googMpeg4(), 1280, 720, true /* flex */); }
+ public void testGoogMpeg4Surf720p() { specific(googMpeg4(), 1280, 720, false /* flex */); }
+ public void testGoogVP8Flex720p() { specific(googVP8(), 1280, 720, true /* flex */); }
+ public void testGoogVP8Surf720p() { specific(googVP8(), 1280, 720, false /* flex */); }
+ public void testGoogVP9Flex720p() { specific(googVP9(), 1280, 720, true /* flex */); }
+ public void testGoogVP9Surf720p() { specific(googVP9(), 1280, 720, false /* flex */); }
+
+ public void testOtherH265Flex720p() { specific(otherH265(), 1280, 720, true /* flex */); }
+ public void testOtherH265Surf720p() { specific(otherH265(), 1280, 720, false /* flex */); }
+ public void testOtherH264Flex720p() { specific(otherH264(), 1280, 720, true /* flex */); }
+ public void testOtherH264Surf720p() { specific(otherH264(), 1280, 720, false /* flex */); }
+ public void testOtherH263Flex720p() { specific(otherH263(), 1280, 720, true /* flex */); }
+ public void testOtherH263Surf720p() { specific(otherH263(), 1280, 720, false /* flex */); }
+ public void testOtherMpeg4Flex720p() { specific(otherMpeg4(), 1280, 720, true /* flex */); }
+ public void testOtherMpeg4Surf720p() { specific(otherMpeg4(), 1280, 720, false /* flex */); }
+ public void testOtherVP8Flex720p() { specific(otherVP8(), 1280, 720, true /* flex */); }
+ public void testOtherVP8Surf720p() { specific(otherVP8(), 1280, 720, false /* flex */); }
+ public void testOtherVP9Flex720p() { specific(otherVP9(), 1280, 720, true /* flex */); }
+ public void testOtherVP9Surf720p() { specific(otherVP9(), 1280, 720, false /* flex */); }
+
+ public void testGoogH265Flex1080p() { specific(googH265(), 1920, 1080, true /* flex */); }
+ public void testGoogH265Surf1080p() { specific(googH265(), 1920, 1080, false /* flex */); }
+ public void testGoogH264Flex1080p() { specific(googH264(), 1920, 1080, true /* flex */); }
+ public void testGoogH264Surf1080p() { specific(googH264(), 1920, 1080, false /* flex */); }
+ public void testGoogH263Flex1080p() { specific(googH263(), 1920, 1080, true /* flex */); }
+ public void testGoogH263Surf1080p() { specific(googH263(), 1920, 1080, false /* flex */); }
+ public void testGoogMpeg4Flex1080p() { specific(googMpeg4(), 1920, 1080, true /* flex */); }
+ public void testGoogMpeg4Surf1080p() { specific(googMpeg4(), 1920, 1080, false /* flex */); }
+ public void testGoogVP8Flex1080p() { specific(googVP8(), 1920, 1080, true /* flex */); }
+ public void testGoogVP8Surf1080p() { specific(googVP8(), 1920, 1080, false /* flex */); }
+ public void testGoogVP9Flex1080p() { specific(googVP9(), 1920, 1080, true /* flex */); }
+ public void testGoogVP9Surf1080p() { specific(googVP9(), 1920, 1080, false /* flex */); }
+
+ public void testOtherH265Flex1080p() { specific(otherH265(), 1920, 1080, true /* flex */); }
+ public void testOtherH265Surf1080p() { specific(otherH265(), 1920, 1080, false /* flex */); }
+ public void testOtherH264Flex1080p() { specific(otherH264(), 1920, 1080, true /* flex */); }
+ public void testOtherH264Surf1080p() { specific(otherH264(), 1920, 1080, false /* flex */); }
+ public void testOtherH263Flex1080p() { specific(otherH263(), 1920, 1080, true /* flex */); }
+ public void testOtherH263Surf1080p() { specific(otherH263(), 1920, 1080, false /* flex */); }
+ public void testOtherMpeg4Flex1080p() { specific(otherMpeg4(), 1920, 1080, true /* flex */); }
+ public void testOtherMpeg4Surf1080p() { specific(otherMpeg4(), 1920, 1080, false /* flex */); }
+ public void testOtherVP8Flex1080p() { specific(otherVP8(), 1920, 1080, true /* flex */); }
+ public void testOtherVP8Surf1080p() { specific(otherVP8(), 1920, 1080, false /* flex */); }
+ public void testOtherVP9Flex1080p() { specific(otherVP9(), 1920, 1080, true /* flex */); }
+ public void testOtherVP9Surf1080p() { specific(otherVP9(), 1920, 1080, false /* flex */); }
+
+ private void minmin(Encoder[] encoders, boolean flexYUV) {
+ extreme(encoders, 0 /* x */, 0 /* y */, flexYUV, false /* near */);
+ }
+
+ private void minmax(Encoder[] encoders, boolean flexYUV) {
+ extreme(encoders, 0 /* x */, 1 /* y */, flexYUV, false /* near */);
+ }
+
+ private void maxmin(Encoder[] encoders, boolean flexYUV) {
+ extreme(encoders, 1 /* x */, 0 /* y */, flexYUV, false /* near */);
+ }
+
+ private void maxmax(Encoder[] encoders, boolean flexYUV) {
+ extreme(encoders, 1 /* x */, 1 /* y */, flexYUV, false /* near */);
+ }
+
+ private void nearminmin(Encoder[] encoders, boolean flexYUV) {
+ extreme(encoders, 0 /* x */, 0 /* y */, flexYUV, true /* near */);
+ }
+
+ private void nearminmax(Encoder[] encoders, boolean flexYUV) {
+ extreme(encoders, 0 /* x */, 1 /* y */, flexYUV, true /* near */);
+ }
+
+ private void nearmaxmin(Encoder[] encoders, boolean flexYUV) {
+ extreme(encoders, 1 /* x */, 0 /* y */, flexYUV, true /* near */);
+ }
+
+ private void nearmaxmax(Encoder[] encoders, boolean flexYUV) {
+ extreme(encoders, 1 /* x */, 1 /* y */, flexYUV, true /* near */);
+ }
+
+ private void extreme(Encoder[] encoders, int x, int y, boolean flexYUV, boolean near) {
+ boolean skipped = true;
+ if (encoders.length == 0) {
+ MediaUtils.skipTest("no such encoder present");
+ return;
+ }
+ for (Encoder encoder: encoders) {
+ if (encoder.testExtreme(x, y, flexYUV, near)) {
+ skipped = false;
+ }
+ }
+ if (skipped) {
+ MediaUtils.skipTest("duplicate resolution extreme");
+ }
+ }
+
+ private void arbitrary(Encoder[] encoders, boolean flexYUV) {
+ boolean skipped = true;
+ if (encoders.length == 0) {
+ MediaUtils.skipTest("no such encoder present");
+ return;
+ }
+ for (Encoder encoder: encoders) {
+ if (encoder.testArbitrary(flexYUV)) {
+ skipped = false;
+ }
+ }
+ if (skipped) {
+ MediaUtils.skipTest("duplicate resolution");
+ }
+ }
+
+ /* test specific size */
+ private void specific(Encoder[] encoders, int width, int height, boolean flexYUV) {
+ boolean skipped = true;
+ if (encoders.length == 0) {
+ MediaUtils.skipTest("no such encoder present");
+ return;
+ }
+ for (Encoder encoder : encoders) {
+ if (encoder.testSpecific(width, height, flexYUV)) {
+ skipped = false;
+ }
+ }
+ if (skipped) {
+ MediaUtils.skipTest("duplicate or unsupported resolution");
+ }
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/VisualizerTest.java b/tests/tests/media/src/android/media/cts/VisualizerTest.java
index 8c91e9b..4582c3f 100644
--- a/tests/tests/media/src/android/media/cts/VisualizerTest.java
+++ b/tests/tests/media/src/android/media/cts/VisualizerTest.java
@@ -16,10 +16,15 @@
package android.media.cts;
+import com.android.cts.media.R;
+
+import android.content.Context;
import android.media.audiofx.AudioEffect;
import android.media.AudioFormat;
import android.media.AudioManager;
+import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
+import android.media.audiofx.Visualizer.MeasurementPeakRms;
import android.os.Looper;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -126,7 +131,7 @@
// 2 - check capture
//----------------------------------
- //Test case 2.0: test cature in polling mode
+ //Test case 2.0: test capture in polling mode
public void test2_0PollingCapture() throws Exception {
if (!hasAudioOutput()) {
return;
@@ -217,6 +222,161 @@
}
//-----------------------------------------------------------------
+ // 3 - check measurement mode MEASUREMENT_MODE_NONE
+ //----------------------------------
+
+ //Test case 3.0: test setting NONE measurement mode
+ public void test3_0MeasurementModeNone() throws Exception {
+ try {
+ getVisualizer(0);
+ mVisualizer.setEnabled(true);
+ assertTrue("visualizer not enabled", mVisualizer.getEnabled());
+ Thread.sleep(100);
+
+ int status = mVisualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_NONE);
+ assertEquals("setMeasurementMode for NONE doesn't report success",
+ Visualizer.SUCCESS, status);
+
+ int mode = mVisualizer.getMeasurementMode();
+ assertEquals("getMeasurementMode reports NONE",
+ Visualizer.MEASUREMENT_MODE_NONE, mode);
+
+ } catch (IllegalStateException e) {
+ fail("method called in wrong state");
+ } catch (InterruptedException e) {
+ fail("sleep() interrupted");
+ } finally {
+ releaseVisualizer();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 4 - check measurement mode MEASUREMENT_MODE_PEAK_RMS
+ //----------------------------------
+
+ //Test case 4.0: test setting peak / RMS measurement mode
+ public void test4_0MeasurementModePeakRms() throws Exception {
+ try {
+ getVisualizer(0);
+ mVisualizer.setEnabled(true);
+ assertTrue("visualizer not enabled", mVisualizer.getEnabled());
+ Thread.sleep(100);
+
+ int status = mVisualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
+ assertEquals("setMeasurementMode for PEAK_RMS doesn't report success",
+ Visualizer.SUCCESS, status);
+
+ int mode = mVisualizer.getMeasurementMode();
+ assertEquals("getMeasurementMode doesn't report PEAK_RMS",
+ Visualizer.MEASUREMENT_MODE_PEAK_RMS, mode);
+
+ } catch (IllegalStateException e) {
+ fail("method called in wrong state");
+ } catch (InterruptedException e) {
+ fail("sleep() interrupted");
+ } finally {
+ releaseVisualizer();
+ }
+ }
+
+ //Test case 4.1: test measurement of peak / RMS
+ public void test4_1MeasurePeakRms() throws Exception {
+ try {
+ // this test will play a 1kHz sine wave with peaks at -40dB
+ MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.sine1khzm40db);
+ final int EXPECTED_PEAK_MB = -4015;
+ final int EXPECTED_RMS_MB = -4300;
+ final int MAX_MEASUREMENT_ERROR_MB = 2000;
+ assertNotNull("null MediaPlayer", mp);
+
+ AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+ assertNotNull("null AudioManager", am);
+ int originalVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
+ am.setStreamVolume(AudioManager.STREAM_MUSIC,
+ am.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
+ getVisualizer(mp.getAudioSessionId());
+ mp.setLooping(true);
+ mp.start();
+
+ mVisualizer.setEnabled(true);
+ assertTrue("visualizer not enabled", mVisualizer.getEnabled());
+ Thread.sleep(100);
+ int status = mVisualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
+ // make sure we're playing long enough so the measurement is valid
+ Thread.sleep(500);
+ assertEquals("setMeasurementMode() for PEAK_RMS doesn't report success",
+ Visualizer.SUCCESS, status);
+ MeasurementPeakRms measurement = new MeasurementPeakRms();
+ status = mVisualizer.getMeasurementPeakRms(measurement);
+ mp.stop();
+ mp.release();
+ am.setStreamVolume(AudioManager.STREAM_MUSIC, originalVolume, 0);
+ assertEquals("getMeasurementPeakRms() reports failure",
+ Visualizer.SUCCESS, status);
+ Log.i("VisTest", "peak="+measurement.mPeak+" rms="+measurement.mRms);
+ int deltaPeak = Math.abs(measurement.mPeak - EXPECTED_PEAK_MB);
+ int deltaRms = Math.abs(measurement.mRms - EXPECTED_RMS_MB);
+ assertTrue("peak deviation in mB=" + deltaPeak, deltaPeak < MAX_MEASUREMENT_ERROR_MB);
+ assertTrue("RMS deviation in mB=" + deltaRms, deltaRms < MAX_MEASUREMENT_ERROR_MB);
+
+ } catch (IllegalStateException e) {
+ fail("method called in wrong state");
+ } catch (InterruptedException e) {
+ fail("sleep() interrupted");
+ } finally {
+ releaseVisualizer();
+ }
+ }
+
+ //Test case 4.2: test measurement of peak / RMS in Long MP3
+ public void test4_2MeasurePeakRmsLongMP3() throws Exception {
+ try {
+ // this test will play a 1kHz sine wave with peaks at -40dB
+ MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.sine1khzs40dblong);
+ final int EXPECTED_PEAK_MB = -4015;
+ final int EXPECTED_RMS_MB = -4300;
+ final int MAX_MEASUREMENT_ERROR_MB = 2000;
+ assertNotNull("null MediaPlayer", mp);
+
+ AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+ assertNotNull("null AudioManager", am);
+ int originalVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
+ am.setStreamVolume(AudioManager.STREAM_MUSIC,
+ am.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
+ getVisualizer(mp.getAudioSessionId());
+ mp.start();
+
+ mVisualizer.setEnabled(true);
+ assertTrue("visualizer not enabled", mVisualizer.getEnabled());
+ Thread.sleep(100);
+ int status = mVisualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
+ // make sure we're playing long enough so the measurement is valid
+ Thread.sleep(500);
+ assertEquals("setMeasurementMode() for PEAK_RMS doesn't report success",
+ Visualizer.SUCCESS, status);
+ MeasurementPeakRms measurement = new MeasurementPeakRms();
+ status = mVisualizer.getMeasurementPeakRms(measurement);
+ mp.stop();
+ mp.release();
+ am.setStreamVolume(AudioManager.STREAM_MUSIC, originalVolume, 0);
+ assertEquals("getMeasurementPeakRms() reports failure",
+ Visualizer.SUCCESS, status);
+ Log.i("VisTest", "peak="+measurement.mPeak+" rms="+measurement.mRms);
+ int deltaPeak = Math.abs(measurement.mPeak - EXPECTED_PEAK_MB);
+ int deltaRms = Math.abs(measurement.mRms - EXPECTED_RMS_MB);
+ assertTrue("peak deviation in mB=" + deltaPeak, deltaPeak < MAX_MEASUREMENT_ERROR_MB);
+ assertTrue("RMS deviation in mB=" + deltaRms, deltaRms < MAX_MEASUREMENT_ERROR_MB);
+
+ } catch (IllegalStateException e) {
+ fail("method called in wrong state");
+ } catch (InterruptedException e) {
+ fail("sleep() interrupted");
+ } finally {
+ releaseVisualizer();
+ }
+ }
+
+ //-----------------------------------------------------------------
// private methods
//----------------------------------
diff --git a/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java b/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java
index 586b9ef..133b91d 100644
--- a/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java
+++ b/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java
@@ -53,10 +53,8 @@
public class Vp8CodecTestBase extends AndroidTestCase {
protected static final String TAG = "VP8CodecTestBase";
- protected static final String VP8_MIME = "video/x-vnd.on2.vp8";
- private static final String VPX_SW_DECODER_NAME = "OMX.google.vp8.decoder";
- private static final String VPX_SW_ENCODER_NAME = "OMX.google.vp8.encoder";
- private static final String OMX_SW_CODEC_PREFIX = "OMX.google";
+ protected static final String VP8_MIME = MediaFormat.MIMETYPE_VIDEO_VP8;
+ private static final String GOOGLE_CODEC_PREFIX = "omx.google.";
protected static final String SDCARD_DIR =
Environment.getExternalStorageDirectory().getAbsolutePath();
@@ -93,29 +91,6 @@
}
/**
- * Returns the first codec capable of encoding the specified MIME type, or null if no
- * match was found.
- */
- protected 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;
- }
-
- /**
* VP8 codec properties generated by getVp8CodecProperties() function.
*/
private class CodecProperties {
@@ -123,8 +98,8 @@
this.codecName = codecName;
this.colorFormat = colorFormat;
}
- public boolean isGoogleSwCodec() {
- return codecName.startsWith(OMX_SW_CODEC_PREFIX);
+ public boolean isGoogleCodec() {
+ return codecName.toLowerCase().startsWith(GOOGLE_CODEC_PREFIX);
}
public final String codecName; // OpenMax component name for VP8 codec.
@@ -135,76 +110,75 @@
* Function to find VP8 codec.
*
* Iterates through the list of available codecs and tries to find
- * VP8 codec, which can support either YUV420 planar or NV12 color formats.
- * If forceSwGoogleCodec parameter set to true the function always returns
- * Google sw VP8 codec.
- * If forceSwGoogleCodec parameter set to false the functions looks for platform
- * specific VP8 codec first. If no platform specific codec exist, falls back to
- * Google sw VP8 codec.
+ * VPX codec, which can support either YUV420 planar or NV12 color formats.
+ * If forceGoogleCodec parameter set to true the function always returns
+ * Google VPX codec.
+ * If forceGoogleCodec parameter set to false the functions looks for platform
+ * specific VPX codec first. If no platform specific codec exist, falls back to
+ * Google VPX codec.
*
* @param isEncoder Flag if encoder is requested.
- * @param forceSwGoogleCodec Forces to use Google sw codec.
+ * @param forceGoogleCodec Forces to use Google codec.
*/
- private CodecProperties getVp8CodecProperties(boolean isEncoder,
- boolean forceSwGoogleCodec) throws Exception {
+ private CodecProperties getVpxCodecProperties(
+ boolean isEncoder,
+ MediaFormat format,
+ boolean forceGoogleCodec) throws Exception {
CodecProperties codecProperties = null;
+ String mime = format.getString(MediaFormat.KEY_MIME);
- if (!forceSwGoogleCodec) {
- // Loop through the list of omx components in case platform specific codec
- // is requested.
- for (int i = 0; i < MediaCodecList.getCodecCount(); i++) {
- MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
- if (isEncoder != codecInfo.isEncoder()) {
+ // Loop through the list of omx components in case platform specific codec
+ // is requested.
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ for (MediaCodecInfo codecInfo : mcl.getCodecInfos()) {
+ if (isEncoder != codecInfo.isEncoder()) {
+ continue;
+ }
+ Log.v(TAG, codecInfo.getName());
+ // TODO: remove dependence of Google from the test
+ // Check if this is Google codec - we should ignore it.
+ boolean isGoogleCodec =
+ codecInfo.getName().toLowerCase().startsWith(GOOGLE_CODEC_PREFIX);
+ if (!isGoogleCodec && forceGoogleCodec) {
+ continue;
+ }
+
+ for (String type : codecInfo.getSupportedTypes()) {
+ if (!type.equalsIgnoreCase(mime)) {
continue;
}
- Log.v(TAG, codecInfo.getName());
- // Check if this is sw Google codec - we should ignore it.
- boolean isGoogleSwCodec = codecInfo.getName().startsWith(OMX_SW_CODEC_PREFIX);
- if (isGoogleSwCodec) {
+ CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(type);
+ if (!capabilities.isFormatSupported(format)) {
continue;
}
- for (String type : codecInfo.getSupportedTypes()) {
- if (!type.equalsIgnoreCase(VP8_MIME)) {
- continue;
- }
- CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(VP8_MIME);
+ // Get candidate codec properties.
+ Log.v(TAG, "Found candidate codec " + codecInfo.getName());
+ for (int colorFormat: capabilities.colorFormats) {
+ Log.v(TAG, " Color: 0x" + Integer.toHexString(colorFormat));
+ }
- // Get candidate codec properties.
- Log.v(TAG, "Found candidate codec " + codecInfo.getName());
- for (int colorFormat : capabilities.colorFormats) {
- Log.v(TAG, " Color: 0x" + Integer.toHexString(colorFormat));
- }
-
- // Check supported color formats.
- for (int supportedColorFormat : mSupportedColorList) {
- for (int codecColorFormat : capabilities.colorFormats) {
- if (codecColorFormat == supportedColorFormat) {
- codecProperties = new CodecProperties(codecInfo.getName(),
- codecColorFormat);
- Log.v(TAG, "Found target codec " + codecProperties.codecName +
- ". Color: 0x" + Integer.toHexString(codecColorFormat));
+ // Check supported color formats.
+ for (int supportedColorFormat : mSupportedColorList) {
+ for (int codecColorFormat : capabilities.colorFormats) {
+ if (codecColorFormat == supportedColorFormat) {
+ codecProperties = new CodecProperties(codecInfo.getName(),
+ codecColorFormat);
+ Log.v(TAG, "Found target codec " + codecProperties.codecName +
+ ". Color: 0x" + Integer.toHexString(codecColorFormat));
+ // return first HW codec found
+ if (!isGoogleCodec) {
return codecProperties;
}
}
}
- // HW codec we found does not support one of necessary color formats.
- throw new RuntimeException("No hw codec with YUV420 or NV12 color formats");
}
}
}
- // If no hw vp8 codec exist or sw codec is requested use default Google sw codec.
if (codecProperties == null) {
- Log.v(TAG, "Use SW VP8 codec");
- if (isEncoder) {
- codecProperties = new CodecProperties(VPX_SW_ENCODER_NAME,
- CodecCapabilities.COLOR_FormatYUV420Planar);
- } else {
- codecProperties = new CodecProperties(VPX_SW_DECODER_NAME,
- CodecCapabilities.COLOR_FormatYUV420Planar);
- }
+ Log.i(TAG, "no suitable " + (forceGoogleCodec ? "google " : "")
+ + (isEncoder ? "encoder " : "decoder ") + "found for " + format);
}
-
return codecProperties;
}
@@ -223,8 +197,8 @@
int inputResourceId;
// Name of the IVF file to write encoded bitsream
public String outputIvfFilename;
- // Force to use Google SW VP8 encoder.
- boolean forceSwEncoder;
+ // Force to use Google VP8 encoder.
+ boolean forceGoogleEncoder;
// Number of frames to encode.
int frameCount;
// Frame rate of input file in frames per second.
@@ -286,7 +260,7 @@
params.inputResourceId = R.raw.football_qvga;
params.outputIvfFilename = SDCARD_DIR + File.separator +
outputIvfBaseName + resolutionScales[i] + ".ivf";
- params.forceSwEncoder = false;
+ params.forceGoogleEncoder = false;
params.frameCount = encodeSeconds * frameRate;
params.frameRate = frameRate;
params.frameWidth = Math.min(frameWidth * resolutionScales[i], 1280);
@@ -532,15 +506,15 @@
* @param inputIvfFilename The name of the IVF file containing encoded bitsream.
* @param outputYuvFilename The name of the output YUV file (optional).
* @param frameRate Frame rate of input file in frames per second
- * @param forceSwDecoder Force to use Googlw sw VP8 decoder.
+ * @param forceGoogleDecoder Force to use Google VP8 decoder.
*/
protected ArrayList<MediaCodec.BufferInfo> decode(
String inputIvfFilename,
String outputYuvFilename,
int frameRate,
- boolean forceSwDecoder) throws Exception {
+ boolean forceGoogleDecoder) throws Exception {
ArrayList<MediaCodec.BufferInfo> bufferInfos = new ArrayList<MediaCodec.BufferInfo>();
- CodecProperties properties = getVp8CodecProperties(false, forceSwDecoder);
+
// Open input/output.
IvfReader ivf = new IvfReader(inputIvfFilename);
int frameWidth = ivf.getWidth();
@@ -548,21 +522,27 @@
int frameCount = ivf.getFrameCount();
int frameStride = frameWidth;
int frameSliceHeight = frameHeight;
- int frameColorFormat = properties.colorFormat;
assertTrue(frameWidth > 0);
assertTrue(frameHeight > 0);
assertTrue(frameCount > 0);
+ // Create decoder.
+ MediaFormat format = MediaFormat.createVideoFormat(
+ VP8_MIME, ivf.getWidth(), ivf.getHeight());
+ CodecProperties properties = getVpxCodecProperties(
+ false /* encoder */, format, forceGoogleDecoder);
+ if (properties == null) {
+ ivf.close();
+ return null;
+ }
+ int frameColorFormat = properties.colorFormat;
+ format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat);
+
FileOutputStream yuv = null;
if (outputYuvFilename != null) {
yuv = new FileOutputStream(outputYuvFilename, false);
}
- // Create decoder.
- MediaFormat format = MediaFormat.createVideoFormat(VP8_MIME,
- ivf.getWidth(),
- ivf.getHeight());
- format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat);
Log.d(TAG, "Creating decoder " + properties.codecName +
". Color format: 0x" + Integer.toHexString(frameColorFormat) +
". " + frameWidth + " x " + frameHeight);
@@ -1282,11 +1262,20 @@
EncoderOutputStreamParameters streamParams) throws Exception {
ArrayList<MediaCodec.BufferInfo> bufferInfos = new ArrayList<MediaCodec.BufferInfo>();
- CodecProperties properties = getVp8CodecProperties(true, streamParams.forceSwEncoder);
- Log.d(TAG, "Source reslution: " + streamParams.frameWidth + " x " +
+ Log.d(TAG, "Source resolution: "+streamParams.frameWidth + " x " +
streamParams.frameHeight);
int bitrate = streamParams.bitrateSet[0];
+ // Create minimal media format signifying desired output.
+ MediaFormat format = MediaFormat.createVideoFormat(
+ VP8_MIME, streamParams.frameWidth, streamParams.frameHeight);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+ CodecProperties properties = getVpxCodecProperties(
+ true, format, streamParams.forceGoogleEncoder);
+ if (properties == null) {
+ return null;
+ }
+
// Open input/output
InputStream yuvStream = OpenFileOrResourceId(
streamParams.inputYuvFilename, streamParams.inputResourceId);
@@ -1294,9 +1283,6 @@
streamParams.outputIvfFilename, streamParams.frameWidth, streamParams.frameHeight);
// Create a media format signifying desired output.
- MediaFormat format = MediaFormat.createVideoFormat(
- VP8_MIME, streamParams.frameWidth, streamParams.frameHeight);
- format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
if (streamParams.bitrateType == VIDEO_ControlRateConstant) {
format.setInteger("bitrate-mode", VIDEO_ControlRateConstant); // set CBR
}
@@ -1451,19 +1437,25 @@
}
ArrayList<MediaCodec.BufferInfo> bufferInfos = new ArrayList<MediaCodec.BufferInfo>();
- CodecProperties properties = getVp8CodecProperties(true, streamParams.forceSwEncoder);
- Log.d(TAG, "Source reslution: " + streamParams.frameWidth + " x " +
+ Log.d(TAG, "Source resolution: "+streamParams.frameWidth + " x " +
streamParams.frameHeight);
int bitrate = streamParams.bitrateSet[0];
+ // Create minimal media format signifying desired output.
+ MediaFormat format = MediaFormat.createVideoFormat(
+ VP8_MIME, streamParams.frameWidth, streamParams.frameHeight);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+ CodecProperties properties = getVpxCodecProperties(
+ true, format, streamParams.forceGoogleEncoder);
+ if (properties == null) {
+ return null;
+ }
+
// Open input/output
IvfWriter ivf = new IvfWriter(
streamParams.outputIvfFilename, streamParams.frameWidth, streamParams.frameHeight);
// Create a media format signifying desired output.
- MediaFormat format = MediaFormat.createVideoFormat(
- VP8_MIME, streamParams.frameWidth, streamParams.frameHeight);
- format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
if (streamParams.bitrateType == VIDEO_ControlRateConstant) {
format.setInteger("bitrate-mode", VIDEO_ControlRateConstant); // set CBR
}
@@ -1546,9 +1538,22 @@
boolean bufferConsumedTotal = false;
CodecProperties[] codecProperties = new CodecProperties[numEncoders];
- for (int i = 0; i < numEncoders; i++) {
- EncoderOutputStreamParameters params = encodingParams.get(i);
- CodecProperties properties = getVp8CodecProperties(true, params.forceSwEncoder);
+ numEncoders = 0;
+ for (EncoderOutputStreamParameters params : encodingParams) {
+ int i = numEncoders;
+ Log.d(TAG, "Source resolution: " + params.frameWidth + " x " +
+ params.frameHeight);
+ int bitrate = params.bitrateSet[0];
+
+ // Create minimal media format signifying desired output.
+ format[i] = MediaFormat.createVideoFormat(VP8_MIME,
+ params.frameWidth, params.frameHeight);
+ format[i].setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+ CodecProperties properties = getVpxCodecProperties(
+ true, format[i], params.forceGoogleEncoder);
+ if (properties == null) {
+ continue;
+ }
// Check if scaled image was created
int scale = params.frameWidth / srcFrameWidth;
@@ -1574,10 +1579,6 @@
srcFrame[i] = new byte[frameSize];
// Create a media format signifying desired output.
- int bitrate = params.bitrateSet[0];
- format[i] = MediaFormat.createVideoFormat(VP8_MIME,
- params.frameWidth, params.frameHeight);
- format[i].setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
if (params.bitrateType == VIDEO_ControlRateConstant) {
format[i].setInteger("bitrate-mode", VIDEO_ControlRateConstant); // set CBR
}
@@ -1607,6 +1608,11 @@
codecProperties[i] = new CodecProperties(properties.codecName, properties.colorFormat);
inputConsumed[i] = true;
+ ++numEncoders;
+ }
+ if (numEncoders == 0) {
+ Log.i(TAG, "no suitable encoders found for any of the streams");
+ return null;
}
while (!sawOutputEOSTotal) {
@@ -1644,7 +1650,8 @@
// Convert YUV420 to NV12 if necessary
if (codecProperties[i].colorFormat !=
CodecCapabilities.COLOR_FormatYUV420Planar) {
- srcFrame[i] = YUV420ToNV(params.frameWidth, params.frameHeight, srcFrame[i]);
+ srcFrame[i] =
+ YUV420ToNV(params.frameWidth, params.frameHeight, srcFrame[i]);
}
}
diff --git a/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java b/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
index 57e397f..be7e721 100644
--- a/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
@@ -18,6 +18,8 @@
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
import android.util.Log;
import com.android.cts.media.R;
@@ -52,13 +54,13 @@
private static final int[] TEST_BITRATES_SET = { 300000, 500000, 700000, 900000 };
// Maximum allowed bitrate variation from the target value.
private static final double MAX_BITRATE_VARIATION = 0.2;
- // Average PSNR values for reference SW VP8 codec for the above bitrates.
+ // Average PSNR values for reference Google VP8 codec for the above bitrates.
private static final double[] REFERENCE_AVERAGE_PSNR = { 33.1, 35.2, 36.6, 37.8 };
- // Minimum PSNR values for reference SW VP8 codec for the above bitrates.
+ // Minimum PSNR values for reference Google VP8 codec for the above bitrates.
private static final double[] REFERENCE_MINIMUM_PSNR = { 25.9, 27.5, 28.4, 30.3 };
- // Maximum allowed average PSNR difference of HW encoder comparing to reference SW encoder.
+ // Maximum allowed average PSNR difference of encoder comparing to reference Google encoder.
private static final double MAX_AVERAGE_PSNR_DIFFERENCE = 2;
- // Maximum allowed minimum PSNR difference of HW encoder comparing to reference SW encoder.
+ // Maximum allowed minimum PSNR difference of encoder comparing to reference Google encoder.
private static final double MAX_MINIMUM_PSNR_DIFFERENCE = 4;
// Maximum allowed average PSNR difference of the encoder running in a looper thread with 0 ms
// buffer dequeue timeout comparing to the encoder running in a callee's thread with 100 ms
@@ -80,13 +82,8 @@
* Also checks the average bitrate is within MAX_BITRATE_VARIATION of the target value.
*/
public void testBasic() throws Exception {
- MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
- if (codecInfo == null) {
- Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testBasic.");
- return;
- }
-
int encodeSeconds = 9;
+ boolean skipped = true;
for (int targetBitrate : TEST_BITRATES_SET) {
EncoderOutputStreamParameters params = getDefaultEncodingParameters(
@@ -100,6 +97,11 @@
targetBitrate,
true);
ArrayList<MediaCodec.BufferInfo> bufInfo = encode(params);
+ if (bufInfo == null) {
+ continue;
+ }
+ skipped = false;
+
Vp8EncodingStatistics statistics = computeEncodingStatistics(bufInfo);
assertEquals("Stream bitrate " + statistics.mAverageBitrate +
@@ -107,7 +109,11 @@
targetBitrate, statistics.mAverageBitrate,
MAX_BITRATE_VARIATION * targetBitrate);
- decode(params.outputIvfFilename, null, FPS, params.forceSwEncoder);
+ decode(params.outputIvfFilename, null, FPS, params.forceGoogleEncoder);
+ }
+
+ if (skipped) {
+ Log.i(TAG, "SKIPPING testBasic(): codec is not supported");
}
}
@@ -119,12 +125,6 @@
* does not change much for two different ways of the encoder call.
*/
public void testAsyncEncoding() throws Exception {
- MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
- if (codecInfo == null) {
- Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testAsyncEncoding.");
- return;
- }
-
int encodeSeconds = 9;
// First test the encoder running in a looper thread with buffer callbacks enabled.
@@ -140,8 +140,12 @@
BITRATE,
syncEncoding);
ArrayList<MediaCodec.BufferInfo> bufInfos = encodeAsync(params);
+ if (bufInfos == null) {
+ Log.i(TAG, "SKIPPING testAsyncEncoding(): no suitable encoder found");
+ return;
+ }
computeEncodingStatistics(bufInfos);
- decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceSwEncoder);
+ decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceGoogleEncoder);
Vp8DecodingStatistics statisticsAsync = computeDecodingStatistics(
params.inputYuvFilename, R.raw.football_qvga, OUTPUT_YUV,
params.frameWidth, params.frameHeight);
@@ -160,8 +164,12 @@
BITRATE,
syncEncoding);
bufInfos = encode(params);
+ if (bufInfos == null) {
+ Log.i(TAG, "SKIPPING testAsyncEncoding(): no suitable encoder found");
+ return;
+ }
computeEncodingStatistics(bufInfos);
- decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceSwEncoder);
+ decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceGoogleEncoder);
Vp8DecodingStatistics statisticsSync = computeDecodingStatistics(
params.inputYuvFilename, R.raw.football_qvga, OUTPUT_YUV,
params.frameWidth, params.frameHeight);
@@ -186,12 +194,6 @@
* The test does not verify the output stream.
*/
public void testSyncFrame() throws Exception {
- MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
- if (codecInfo == null) {
- Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testSyncFrame.");
- return;
- }
-
int encodeSeconds = 9;
EncoderOutputStreamParameters params = getDefaultEncodingParameters(
@@ -207,6 +209,11 @@
params.syncFrameInterval = encodeSeconds * FPS;
params.syncForceFrameInterval = FPS;
ArrayList<MediaCodec.BufferInfo> bufInfo = encode(params);
+ if (bufInfo == null) {
+ Log.i(TAG, "SKIPPING testSyncFrame(): no suitable encoder found");
+ return;
+ }
+
Vp8EncodingStatistics statistics = computeEncodingStatistics(bufInfo);
// First check if we got expected number of key frames.
@@ -236,12 +243,6 @@
* bitrate after 6 seconds and ensure the encoder responds.
*/
public void testDynamicBitrateChange() throws Exception {
- MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
- if (codecInfo == null) {
- Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testDynamicBitrateChange.");
- return;
- }
-
int encodeSeconds = 12; // Encoding sequence duration in seconds.
int[] bitrateTargetValues = { 400000, 800000 }; // List of bitrates to test.
@@ -268,6 +269,11 @@
}
ArrayList<MediaCodec.BufferInfo> bufInfo = encode(params);
+ if (bufInfo == null) {
+ Log.i(TAG, "SKIPPING testDynamicBitrateChange(): no suitable encoder found");
+ return;
+ }
+
Vp8EncodingStatistics statistics = computeEncodingStatistics(bufInfo);
// Calculate actual average bitrates for every [stepSeconds] second.
@@ -304,10 +310,12 @@
* Compares average bitrate and PSNR for sequential and parallel runs.
*/
public void testParallelEncodingAndDecoding() throws Exception {
- MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
- if (codecInfo == null) {
- Log.w(TAG, "Codec " + VP8_MIME + " not supported. "
- + "Return from testParallelEncodingAndDecoding.");
+ // check for encoder up front, as by the time we detect lack of
+ // encoder support, we may have already started decoding.
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ MediaFormat format = MediaFormat.createVideoFormat(VP8_MIME, WIDTH, HEIGHT);
+ if (mcl.findEncoderForFormat(format) == null) {
+ Log.i(TAG, "SKIPPING testParallelEncodingAndDecoding(): no suitable encoder found");
return;
}
@@ -343,7 +351,7 @@
Runnable runDecoder = new Runnable() {
public void run() {
try {
- decode(inputIvfFilename, OUTPUT_YUV, FPS, params.forceSwEncoder);
+ decode(inputIvfFilename, OUTPUT_YUV, FPS, params.forceGoogleEncoder);
Vp8DecodingStatistics statistics = computeDecodingStatistics(
params.inputYuvFilename, R.raw.football_qvga, OUTPUT_YUV,
params.frameWidth, params.frameHeight);
@@ -400,21 +408,17 @@
* Run the the encoder for 9 seconds for each bitrate and calculate PSNR
* for each encoded stream.
* Video streams with higher bitrates should have higher PSNRs.
- * Also compares average and minimum PSNR of HW codec with PSNR values of reference SW codec.
+ * Also compares average and minimum PSNR of codec with PSNR values of reference Google codec.
*/
public void testEncoderQuality() throws Exception {
- MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
- if (codecInfo == null) {
- Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testEncoderQuality.");
- return;
- }
-
int encodeSeconds = 9; // Encoding sequence duration in seconds for each bitrate.
double[] psnrPlatformCodecAverage = new double[TEST_BITRATES_SET.length];
double[] psnrPlatformCodecMin = new double[TEST_BITRATES_SET.length];
+ boolean[] completed = new boolean[TEST_BITRATES_SET.length];
+ boolean skipped = true;
// Run platform specific encoder for different bitrates
- // and compare PSNR of hw codec with PSNR of reference sw codec.
+ // and compare PSNR of codec with PSNR of reference Google codec.
for (int i = 0; i < TEST_BITRATES_SET.length; i++) {
EncoderOutputStreamParameters params = getDefaultEncodingParameters(
INPUT_YUV,
@@ -426,9 +430,15 @@
BITRATE_MODE,
TEST_BITRATES_SET[i],
true);
- encode(params);
+ if (encode(params) == null) {
+ // parameters not supported, try other bitrates
+ completed[i] = false;
+ continue;
+ }
+ completed[i] = true;
+ skipped = false;
- decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceSwEncoder);
+ decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceGoogleEncoder);
Vp8DecodingStatistics statistics = computeDecodingStatistics(
params.inputYuvFilename, R.raw.football_qvga, OUTPUT_YUV,
params.frameWidth, params.frameHeight);
@@ -436,9 +446,20 @@
psnrPlatformCodecMin[i] = statistics.mMinimumPSNR;
}
+ if (skipped) {
+ Log.i(TAG, "SKIPPING testEncoderQuality(): no bitrates supported");
+ return;
+ }
+
// First do a sanity check - higher bitrates should results in higher PSNR.
for (int i = 1; i < TEST_BITRATES_SET.length ; i++) {
+ if (!completed[i]) {
+ continue;
+ }
for (int j = 0; j < i; j++) {
+ if (!completed[j]) {
+ continue;
+ }
double differenceBitrate = TEST_BITRATES_SET[i] - TEST_BITRATES_SET[j];
double differencePSNR = psnrPlatformCodecAverage[i] - psnrPlatformCodecAverage[j];
if (differenceBitrate * differencePSNR < 0) {
@@ -450,12 +471,16 @@
}
}
- // Then compare average and minimum PSNR of platform codec with reference sw codec -
+ // Then compare average and minimum PSNR of platform codec with reference Google codec -
// average PSNR for platform codec should be no more than 2 dB less than reference PSNR
// and minumum PSNR - no more than 4 dB less than reference minimum PSNR.
// These PSNR difference numbers are arbitrary for now, will need further estimation
- // when more devices with hw VP8 codec will appear.
+ // when more devices with HW VP8 codec will appear.
for (int i = 0; i < TEST_BITRATES_SET.length ; i++) {
+ if (!completed[i]) {
+ continue;
+ }
+
Log.d(TAG, "Bitrate " + TEST_BITRATES_SET[i]);
Log.d(TAG, "Reference: Average: " + REFERENCE_AVERAGE_PSNR[i] + ". Minimum: " +
REFERENCE_MINIMUM_PSNR[i]);
@@ -470,7 +495,7 @@
if (psnrPlatformCodecMin[i] < REFERENCE_MINIMUM_PSNR[i] -
MAX_MINIMUM_PSNR_DIFFERENCE) {
throw new RuntimeException("Low minimum PSNR " + psnrPlatformCodecMin[i] +
- " comparing to sw PSNR " + REFERENCE_MINIMUM_PSNR[i] +
+ " comparing to reference PSNR " + REFERENCE_MINIMUM_PSNR[i] +
" for bitrate " + TEST_BITRATES_SET[i]);
}
}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java b/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
index 09cc8b8..d39bc16 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
@@ -19,15 +19,13 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
-import android.graphics.Bitmap;
+import android.media.MediaFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.PowerManager;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
-import android.view.ViewGroup;
-import android.widget.ImageView;
import com.android.cts.mediastress.R;
@@ -85,7 +83,7 @@
}
public void startPlayback(String filename){
- String mimetype = "audio/mpeg";
+ String mimetype = MediaFormat.MIMETYPE_AUDIO_MPEG;
Uri path = Uri.parse(filename);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(path, mimetype);
diff --git a/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java b/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java
new file mode 100644
index 0000000..0c648c5
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014 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.permission.cts;
+
+import android.content.ContentValues;
+import android.content.pm.PackageManager;
+import android.media.tv.TvContract;
+import android.net.Uri;
+import android.test.AndroidTestCase;
+
+/**
+ * Tests for TV API related permissions.
+ */
+public class TvPermissionTest extends AndroidTestCase {
+ private static final String DUMMY_INPUT_ID = "dummy";
+
+ private boolean mHasTvInputFramework;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mHasTvInputFramework = getContext().getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_LIVE_TV);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private void verifyQuery(Uri uri, final String[] projection,
+ String tableName) throws Exception {
+ try {
+ getContext().getContentResolver().query(uri, projection, null, null, null);
+ fail("Accessing " + tableName + " table should require READ_EPG_DATA permission.");
+ } catch (SecurityException e) {
+ // Expected exception
+ }
+ }
+
+ public void verifyInsert(Uri uri, String tableName) throws Exception {
+ try {
+ ContentValues values = new ContentValues();
+ getContext().getContentResolver().insert(uri, values);
+ fail("Accessing " + tableName + " table should require WRITE_EPG_DATA permission.");
+ } catch (SecurityException e) {
+ // Expected exception
+ }
+ }
+
+ public void verifyUpdate(Uri uri, String tableName) throws Exception {
+ try {
+ ContentValues values = new ContentValues();
+ getContext().getContentResolver().update(uri, values, null, null);
+ fail("Accessing " + tableName + " table should require WRITE_EPG_DATA permission.");
+ } catch (SecurityException e) {
+ // Expected exception
+ }
+ }
+
+ public void verifyDelete(Uri uri, String tableName) throws Exception {
+ try {
+ getContext().getContentResolver().delete(uri, null, null);
+ fail("Accessing " + tableName + " table should require WRITE_EPG_DATA permission.");
+ } catch (SecurityException e) {
+ // Expected exception
+ }
+ }
+
+ public void testQueryChannels() throws Exception {
+ if (!mHasTvInputFramework) return;
+ final String[] projection = { TvContract.Channels._ID };
+ verifyQuery(TvContract.Channels.CONTENT_URI, projection, "channels");
+ }
+
+ public void testInsertChannels() throws Exception {
+ if (!mHasTvInputFramework) return;
+ verifyInsert(TvContract.Channels.CONTENT_URI, "channels");
+ }
+
+ public void testUpdateChannels() throws Exception {
+ if (!mHasTvInputFramework) return;
+ verifyUpdate(TvContract.Channels.CONTENT_URI, "channels");
+ }
+
+ public void testDeleteChannels() throws Exception {
+ if (!mHasTvInputFramework) return;
+ verifyDelete(TvContract.Channels.CONTENT_URI, "channels");
+ }
+
+ public void testQueryPrograms() throws Exception {
+ if (!mHasTvInputFramework) return;
+ final String[] projection = { TvContract.Programs._ID };
+ verifyQuery(TvContract.Programs.CONTENT_URI, projection, "programs");
+ }
+
+ public void testInsertPrograms() throws Exception {
+ if (!mHasTvInputFramework) return;
+ verifyInsert(TvContract.Programs.CONTENT_URI, "programs");
+ }
+
+ public void testUpdatePrograms() throws Exception {
+ if (!mHasTvInputFramework) return;
+ verifyUpdate(TvContract.Programs.CONTENT_URI, "programs");
+ }
+
+ public void testDeletePrograms() throws Exception {
+ if (!mHasTvInputFramework) return;
+ verifyDelete(TvContract.Programs.CONTENT_URI, "programs");
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
index b6175be..974eeb71 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
@@ -22,6 +22,7 @@
import android.content.ContentUris;
import android.content.ContentValues;
import android.cts.util.FileCopyHelper;
+import android.cts.util.MediaUtils;
import android.database.Cursor;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
@@ -38,32 +39,13 @@
public class MediaStore_Video_ThumbnailsTest extends AndroidTestCase {
private static final String TAG = "MediaStore_Video_ThumbnailsTest";
- private static final String MIME_TYPE = "video/3gpp";
private ContentResolver mResolver;
private FileCopyHelper mFileHelper;
- // TODO: Make a public method selectCodec() in common libraries (e.g. cts/libs/), to avoid
- // redundant function definitions in this and other media related test files.
- private static boolean hasCodec(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 true;
- }
- }
- }
- return false;
+ private boolean hasCodec() {
+ return MediaUtils.hasCodecForResourceAndDomain(mContext, R.raw.testvideo, "video/");
}
@Override
@@ -98,10 +80,10 @@
int count = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
// Don't run the test if the codec isn't supported.
- if (!hasCodec(MIME_TYPE)) {
+ if (!hasCodec()) {
// Calling getThumbnail should not generate a new thumbnail.
assertNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MINI_KIND, null));
- Log.w(TAG, "Codec " + MIME_TYPE + " not supported. Return from testGetThumbnail.");
+ Log.i(TAG, "SKIPPING testGetThumbnail(): codec not supported");
return;
}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
new file mode 100644
index 0000000..d593bff
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2013 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.renderscript.cts;
+
+import android.renderscript.*;
+import android.util.Log;
+
+public class IntrinsicResize extends IntrinsicBase {
+
+ static final int inX = 307;
+ static final int inY = 157;
+
+ private void testReszie(int w, int h, Element.DataType dt, int vecSize, float scaleX, float scaleY) {
+
+ Element e = makeElement(dt, vecSize);
+
+ System.gc();
+ makeSource(w, h, e);
+
+ int outW = (int) (w*scaleX);
+ int outH = (int) (h*scaleY);
+ if (mAllocRef != null) {
+ mAllocRef.destroy();
+ }
+ if (mAllocDst != null) {
+ mAllocDst.destroy();
+ }
+ mAllocRef = makeAllocation(outW, outH, e);
+ mAllocDst = makeAllocation(outW, outH, e);
+
+ ScriptIntrinsicResize si = ScriptIntrinsicResize.create(mRS);
+ si.setInput(mAllocSrc);
+ si.forEach_bicubic(mAllocRef);
+
+ ScriptC_intrinsic_resize sr = new ScriptC_intrinsic_resize(mRS);
+ sr.set_scaleX((float)w/outW);
+ sr.set_scaleY((float)h/outH);
+ sr.set_gIn(mAllocSrc);
+ sr.set_gWidthIn(w);
+ sr.set_gHeightIn(h);
+ if (dt == Element.DataType.UNSIGNED_8) {
+ switch(vecSize) {
+ case 4:
+ sr.forEach_bicubic_U4(mAllocDst);
+ break;
+ case 3:
+ sr.forEach_bicubic_U3(mAllocDst);
+ break;
+ case 2:
+ sr.forEach_bicubic_U2(mAllocDst);
+ break;
+ case 1:
+ sr.forEach_bicubic_U1(mAllocDst);
+ break;
+ }
+ }
+
+ mVerify.invoke_verify(mAllocRef, mAllocDst, mAllocSrc);
+ if (outW == w && outH == h) {
+ //when scale = 1, check with the original.
+ mVerify.invoke_verify(mAllocRef, mAllocSrc, mAllocSrc);
+ mVerify.invoke_verify(mAllocDst, mAllocSrc, mAllocSrc);
+ }
+ mRS.finish();
+ }
+
+
+ public void test_U8_4_SCALE10_10_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 1.f, 1.f);
+ checkError();
+ }
+ public void test_U8_3_SCALE10_10_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 1.f, 1.f);
+ checkError();
+ }
+ public void test_U8_2_SCALE10_10_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 1.f, 1.f);
+ checkError();
+ }
+ public void test_U8_1_SCALE10_10_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 1.f, 1.f);
+ checkError();
+ }
+
+ public void test_U8_4_SCALE20_20_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 2.f);
+ checkError();
+ }
+ public void test_U8_3_SCALE20_20_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 2.f);
+ checkError();
+ }
+ public void test_U8_2_SCALE20_20_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 2.f);
+ checkError();
+ }
+ public void test_U8_1_SCALE20_20_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 2.f);
+ checkError();
+ }
+
+ public void test_U8_4_SCALE05_20_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 2.f);
+ checkError();
+ }
+ public void test_U8_3_SCALE05_20_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 2.f);
+ checkError();
+ }
+ public void test_U8_2_SCALE05_20_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 2.f);
+ checkError();
+ }
+ public void test_U8_1_SCALE05_20_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 2.f);
+ checkError();
+ }
+
+ public void test_U8_4_SCALE20_05_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 0.5f);
+ checkError();
+ }
+ public void test_U8_3_SCALE20_05_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 0.5f);
+ checkError();
+ }
+ public void test_U8_2_SCALE20_05_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 0.5f);
+ checkError();
+ }
+ public void test_U8_1_SCALE20_05_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 0.5f);
+ checkError();
+ }
+
+ public void test_U8_4_SCALE05_05_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 0.5f);
+ checkError();
+ }
+ public void test_U8_3_SCALE05_05_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 0.5f);
+ checkError();
+ }
+ public void test_U8_2_SCALE05_05_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 0.5f);
+ checkError();
+ }
+ public void test_U8_1_SCALE05_05_inSqure() {
+ testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 0.5f);
+ checkError();
+ }
+
+ public void test_U8_4_SCALE10_10_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 1.f, 1.f);
+ checkError();
+ }
+ public void test_U8_3_SCALE10_10_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 1.f, 1.f);
+ checkError();
+ }
+ public void test_U8_2_SCALE10_10_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 1.f, 1.f);
+ checkError();
+ }
+ public void test_U8_1_SCALE10_10_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 1.f, 1.f);
+ checkError();
+ }
+
+ public void test_U8_4_SCALE20_20_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 2.f, 2.f);
+ checkError();
+ }
+ public void test_U8_3_SCALE20_20_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 2.f, 2.f);
+ checkError();
+ }
+ public void test_U8_2_SCALE20_20_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 2.f, 2.f);
+ checkError();
+ }
+ public void test_U8_1_SCALE20_20_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 2.f, 2.f);
+ checkError();
+ }
+
+ public void test_U8_4_SCALE05_20_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 0.5f, 2.f);
+ checkError();
+ }
+ public void test_U8_3_SCALE05_20_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 0.5f, 2.f);
+ checkError();
+ }
+ public void test_U8_2_SCALE05_20_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 0.5f, 2.f);
+ checkError();
+ }
+ public void test_U8_1_SCALE05_20_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 0.5f, 2.f);
+ checkError();
+ }
+
+ public void test_U8_4_SCALE20_05_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 2.f, 0.5f);
+ checkError();
+ }
+ public void test_U8_3_SCALE20_05_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 2.f, 0.5f);
+ checkError();
+ }
+ public void test_U8_2_SCALE20_05_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 2.f, 0.5f);
+ checkError();
+ }
+ public void test_U8_1_SCALE20_05_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 2.f, 0.5f);
+ checkError();
+ }
+
+ public void test_U8_4_SCALE05_05_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 0.5f, 0.5f);
+ checkError();
+ }
+ public void test_U8_3_SCALE05_05_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 0.5f, 0.5f);
+ checkError();
+ }
+ public void test_U8_2_SCALE05_05_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 0.5f, 0.5f);
+ checkError();
+ }
+ public void test_U8_1_SCALE05_05_inRectangle() {
+ testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 0.5f, 0.5f);
+ checkError();
+ }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestVLoad.java b/tests/tests/renderscript/src/android/renderscript/cts/TestVLoad.java
new file mode 100644
index 0000000..a2d22d9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestVLoad.java
@@ -0,0 +1,371 @@
+ /*
+ * Copyright (C) 2014 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.renderscript.cts;
+
+import android.renderscript.*;
+
+public class TestVLoad extends RSBaseCompute {
+
+ private ScriptC_vload script;
+ private ScriptC_vload_relaxed scriptRelaxed;
+ Allocation walkAlloc;
+ Allocation inAlloc;
+ Allocation outAlloc;
+ private static java.util.Random random = new java.util.Random();
+
+ final int w = 253;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ random.setSeed(10);
+ script = new ScriptC_vload(mRS);
+ scriptRelaxed = new ScriptC_vload_relaxed(mRS);
+ }
+
+
+
+ protected void createWalk() {
+ int tmp[] = new int[w];
+ boolean b[] = new boolean[w];
+ int toCopy = w;
+ int i = 0;
+
+ while (toCopy > 0) {
+ int x = random.nextInt(w);
+
+ //android.util.Log.v("rs", "x " + x + ", y " + y + ", toCopy " + toCopy);
+ while ((x < w) && b[x]) {
+ x++;
+ if (x >= w) {
+ x = 0;
+ }
+ }
+
+ int maxsize = 1;
+ b[x] = true;
+ if ((x+1 < w) && !b[x+1]) {
+ maxsize ++;
+ b[x+1] = true;
+ if ((x+2 < w) && !b[x+2]) {
+ maxsize ++;
+ b[x+2] = true;
+ if ((x+3 < w) && !b[x+3]) {
+ maxsize ++;
+ b[x+3] = true;
+ }
+ }
+ }
+
+ toCopy -= maxsize;
+ tmp[i] = x | (maxsize << 16);
+ android.util.Log.v("rs", "x " + x + ", vec " + maxsize);
+ i++;
+ }
+
+ walkAlloc = Allocation.createSized(mRS, Element.I32(mRS), i);
+ walkAlloc.copy1DRangeFrom(0, i, tmp);
+ }
+
+ private void testSetup(Type t) {
+ createWalk();
+
+ inAlloc = Allocation.createTyped(mRS, t);
+ outAlloc = Allocation.createTyped(mRS, t);
+ script.set_gAllocIn(inAlloc);
+ script.set_gAllocOut(outAlloc);
+ scriptRelaxed.set_gAllocIn(inAlloc);
+ scriptRelaxed.set_gAllocOut(outAlloc);
+ }
+
+ private void verify(byte[] a1, byte[] a2, String s) {
+ outAlloc.copyTo(a2);
+ for (int i=0; i < w; i++) {
+ if (a1[i] != a2[i]) {
+ throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+ }
+ a2[i] = 0;
+ }
+ outAlloc.copyFrom(a2);
+ }
+
+ private void verify(short[] a1, short[] a2, String s) {
+ outAlloc.copyTo(a2);
+ for (int i=0; i < w; i++) {
+ if (a1[i] != a2[i]) {
+ throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+ }
+ a2[i] = 0;
+ }
+ outAlloc.copyFrom(a2);
+ }
+
+ private void verify(int[] a1, int[] a2, String s) {
+ outAlloc.copyTo(a2);
+ for (int i=0; i < w; i++) {
+ if (a1[i] != a2[i]) {
+ throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+ }
+ a2[i] = 0;
+ }
+ outAlloc.copyFrom(a2);
+ }
+
+ private void verify(long[] a1, long[] a2, String s) {
+ outAlloc.copyTo(a2);
+ for (int i=0; i < w; i++) {
+ if (a1[i] != a2[i]) {
+ throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+ }
+ a2[i] = 0;
+ }
+ outAlloc.copyFrom(a2);
+ }
+
+ private void verify(float[] a1, float[] a2, String s) {
+ outAlloc.copyTo(a2);
+ for (int i=0; i < w; i++) {
+ if (a1[i] != a2[i]) {
+ throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+ }
+ a2[i] = 0;
+ }
+ outAlloc.copyFrom(a2);
+ }
+
+ private void verify(double[] a1, double[] a2, String s) {
+ outAlloc.copyTo(a2);
+ for (int i=0; i < w; i++) {
+ if (a1[i] != a2[i]) {
+ throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+ }
+ a2[i] = 0;
+ }
+ outAlloc.copyFrom(a2);
+ }
+
+ private byte[] randomByteArray(int len) {
+ byte t[] = new byte[len];
+ random.nextBytes(t);
+ inAlloc.copyFrom(t);
+ return t;
+ }
+
+ private short[] randomShortArray(int len) {
+ short t[] = new short[len];
+ for (int i = 0; i < t.length; i++) {
+ t[i] = (short)(random.nextInt() & 0xffff);
+ }
+ inAlloc.copyFrom(t);
+ return t;
+ }
+
+ private int[] randomIntArray(int len) {
+ int t[] = new int[len];
+ for (int i = 0; i < t.length; i++) {
+ t[i] = random.nextInt();
+ }
+ inAlloc.copyFrom(t);
+ return t;
+ }
+
+ private long[] randomLongArray(int len) {
+ long t[] = new long[len];
+ for (int i = 0; i < t.length; i++) {
+ t[i] = random.nextLong();
+ }
+ inAlloc.copyFrom(t);
+ return t;
+ }
+
+ public void testVload_char() {
+ testSetup(Type.createX(mRS, Element.I8(mRS), w));
+ byte tmp[] = randomByteArray(w);
+ byte tmp2[] = new byte[w];
+ script.forEach_copy2d_char(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch char: ");
+ }
+
+ public void testVload_uchar() {
+ testSetup(Type.createX(mRS, Element.I8(mRS), w));
+ byte tmp[] = randomByteArray(w);
+ byte tmp2[] = new byte[w];
+ script.forEach_copy2d_uchar(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch uchar: ");
+ }
+
+ public void testVload_char_relaxed() {
+ testSetup(Type.createX(mRS, Element.I8(mRS), w));
+ byte tmp[] = randomByteArray(w);
+ byte tmp2[] = new byte[w];
+ scriptRelaxed.forEach_copy2d_char(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch relaxed char: ");
+ }
+
+ public void testVload_uchar_relaxed() {
+ testSetup(Type.createX(mRS, Element.I8(mRS), w));
+ byte tmp[] = randomByteArray(w);
+ byte tmp2[] = new byte[w];
+ scriptRelaxed.forEach_copy2d_uchar(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch relaxed uchar: ");
+ }
+
+ public void testVload_short() {
+ testSetup(Type.createX(mRS, Element.I16(mRS), w));
+ short tmp[] = randomShortArray(w);
+ short tmp2[] = new short[w];
+ script.forEach_copy2d_short(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch short: ");
+ }
+
+ public void testVload_ushort() {
+ testSetup(Type.createX(mRS, Element.I16(mRS), w));
+ short tmp[] = randomShortArray(w);
+ short tmp2[] = new short[w];
+ script.forEach_copy2d_ushort(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch ushort: ");
+ }
+
+ public void testVload_short_relaxed() {
+ testSetup(Type.createX(mRS, Element.I16(mRS), w));
+ short tmp[] = randomShortArray(w);
+ short tmp2[] = new short[w];
+ scriptRelaxed.forEach_copy2d_short(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch relaxed short: ");
+ }
+
+ public void testVload_ushort_relaxed() {
+ testSetup(Type.createX(mRS, Element.I16(mRS), w));
+ short tmp[] = randomShortArray(w);
+ short tmp2[] = new short[w];
+ scriptRelaxed.forEach_copy2d_ushort(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch ushort: ");
+ }
+
+ public void testVload_int() {
+ testSetup(Type.createX(mRS, Element.I32(mRS), w));
+ int tmp[] = randomIntArray(w);
+ int tmp2[] = new int[w];
+ script.forEach_copy2d_int(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch int: ");
+ }
+
+ public void testVload_uint() {
+ testSetup(Type.createX(mRS, Element.I32(mRS), w));
+ int tmp[] = randomIntArray(w);
+ int tmp2[] = new int[w];
+ script.forEach_copy2d_uint(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch uint: ");
+ }
+
+ public void testVload_int_relaxed() {
+ testSetup(Type.createX(mRS, Element.I32(mRS), w));
+ int tmp[] = randomIntArray(w);
+ int tmp2[] = new int[w];
+ scriptRelaxed.forEach_copy2d_int(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch relaxed int: ");
+ }
+
+ public void testVload_uint_relaxed() {
+ testSetup(Type.createX(mRS, Element.I32(mRS), w));
+ int tmp[] = randomIntArray(w);
+ int tmp2[] = new int[w];
+ scriptRelaxed.forEach_copy2d_uint(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch uint: ");
+ }
+
+ public void testVload_long() {
+ testSetup(Type.createX(mRS, Element.I64(mRS), w));
+ long tmp[] = randomLongArray(w);
+ long tmp2[] = new long[w];
+ script.forEach_copy2d_long(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch long: ");
+ }
+
+ public void testVload_ulong() {
+ testSetup(Type.createX(mRS, Element.I64(mRS), w));
+ long tmp[] = randomLongArray(w);
+ long tmp2[] = new long[w];
+ script.forEach_copy2d_ulong(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch ulong: ");
+ }
+ public void testVload_long_relaxed() {
+ testSetup(Type.createX(mRS, Element.I64(mRS), w));
+ long tmp[] = randomLongArray(w);
+ long tmp2[] = new long[w];
+ scriptRelaxed.forEach_copy2d_long(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch relaxed long: ");
+ }
+ public void testVload_ulong_relaxed() {
+ testSetup(Type.createX(mRS, Element.I64(mRS), w));
+ long tmp[] = randomLongArray(w);
+ long tmp2[] = new long[w];
+ scriptRelaxed.forEach_copy2d_ulong(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch ulong: ");
+ }
+
+ public void testVload_float() {
+ testSetup(Type.createX(mRS, Element.F32(mRS), w));
+ float tmp[] = new float[w];
+ float tmp2[] = new float[w];
+ for (int i=0; i < w; i++) {
+ tmp[i] = random.nextFloat();
+ }
+ inAlloc.copyFrom(tmp);
+ script.forEach_copy2d_float(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch float: ");
+ }
+
+ public void testVload_float_relaxed() {
+ testSetup(Type.createX(mRS, Element.F32(mRS), w));
+ float tmp[] = new float[w];
+ float tmp2[] = new float[w];
+ for (int i=0; i < w; i++) {
+ tmp[i] = random.nextFloat();
+ }
+ inAlloc.copyFrom(tmp);
+ scriptRelaxed.forEach_copy2d_float(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch relaxed float: ");
+ }
+
+ public void testVload_double() {
+ testSetup(Type.createX(mRS, Element.F64(mRS), w));
+ double tmp[] = new double[w];
+ double tmp2[] = new double[w];
+ for (int i=0; i < w; i++) {
+ tmp[i] = random.nextDouble();
+ }
+ inAlloc.copyFrom(tmp);
+ script.forEach_copy2d_double(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch double: ");
+ }
+
+ public void testVload_double_relaxed() {
+ testSetup(Type.createX(mRS, Element.F64(mRS), w));
+ double tmp[] = new double[w];
+ double tmp2[] = new double[w];
+ for (int i=0; i < w; i++) {
+ tmp[i] = random.nextDouble();
+ }
+ inAlloc.copyFrom(tmp);
+ scriptRelaxed.forEach_copy2d_double(walkAlloc);
+ verify(tmp, tmp2, "Data mismatch relaxed double: ");
+ }
+
+}
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_resize.rs b/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_resize.rs
new file mode 100644
index 0000000..fa8c8dd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_resize.rs
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include "shared.rsh"
+
+int32_t gWidthIn;
+int32_t gHeightIn;
+rs_allocation gIn;
+float scaleX;
+float scaleY;
+
+static float4 cubicInterpolate_F4 (float4 p0,float4 p1,float4 p2,float4 p3 , float x) {
+ return p1 + 0.5f * x * (p2 - p0 + x * (2.f * p0 - 5.f * p1 + 4.f * p2 - p3
+ + x * (3.f * (p1 - p2) + p3 - p0)));
+}
+
+static float3 cubicInterpolate_F3 (float3 p0,float3 p1,float3 p2,float3 p3 , float x) {
+ return p1 + 0.5f * x * (p2 - p0 + x * (2.f * p0 - 5.f * p1 + 4.f * p2 - p3
+ + x * (3.f * (p1 - p2) + p3 - p0)));
+}
+
+static float2 cubicInterpolate_F2 (float2 p0,float2 p1,float2 p2,float2 p3 , float x) {
+ return p1 + 0.5f * x * (p2 - p0 + x * (2.f * p0 - 5.f * p1 + 4.f * p2 - p3
+ + x * (3.f * (p1 - p2) + p3 - p0)));
+}
+
+static float cubicInterpolate_F1 (float p0,float p1,float p2,float p3 , float x) {
+ return p1 + 0.5f * x * (p2 - p0 + x * (2.f * p0 - 5.f * p1 + 4.f * p2 - p3
+ + x * (3.f * (p1 - p2) + p3 - p0)));
+}
+
+uchar4 __attribute__((kernel)) bicubic_U4(uint32_t x, uint32_t y) {
+ float xf = (x + 0.5f) * scaleX - 0.5f;
+ float yf = (y + 0.5f) * scaleY - 0.5f;
+
+ int startx = (int) floor(xf - 1);
+ int starty = (int) floor(yf - 1);
+ xf = xf - floor(xf);
+ yf = yf - floor(yf);
+ int maxx = gWidthIn - 1;
+ int maxy = gHeightIn - 1;
+
+ uint32_t xs0 = (uint32_t) max(0, startx + 0);
+ uint32_t xs1 = (uint32_t) max(0, startx + 1);
+ uint32_t xs2 = (uint32_t) min(maxx, startx + 2);
+ uint32_t xs3 = (uint32_t) min(maxx, startx + 3);
+
+ uint32_t ys0 = (uint32_t) max(0, starty + 0);
+ uint32_t ys1 = (uint32_t) max(0, starty + 1);
+ uint32_t ys2 = (uint32_t) min(maxy, starty + 2);
+ uint32_t ys3 = (uint32_t) min(maxy, starty + 3);
+
+ float4 p00 = convert_float4(rsGetElementAt_uchar4(gIn, xs0, ys0));
+ float4 p01 = convert_float4(rsGetElementAt_uchar4(gIn, xs1, ys0));
+ float4 p02 = convert_float4(rsGetElementAt_uchar4(gIn, xs2, ys0));
+ float4 p03 = convert_float4(rsGetElementAt_uchar4(gIn, xs3, ys0));
+ float4 p0 = cubicInterpolate_F4(p00, p01, p02, p03, xf);
+
+ float4 p10 = convert_float4(rsGetElementAt_uchar4(gIn, xs0, ys1));
+ float4 p11 = convert_float4(rsGetElementAt_uchar4(gIn, xs1, ys1));
+ float4 p12 = convert_float4(rsGetElementAt_uchar4(gIn, xs2, ys1));
+ float4 p13 = convert_float4(rsGetElementAt_uchar4(gIn, xs3, ys1));
+ float4 p1 = cubicInterpolate_F4(p10, p11, p12, p13, xf);
+
+ float4 p20 = convert_float4(rsGetElementAt_uchar4(gIn, xs0, ys2));
+ float4 p21 = convert_float4(rsGetElementAt_uchar4(gIn, xs1, ys2));
+ float4 p22 = convert_float4(rsGetElementAt_uchar4(gIn, xs2, ys2));
+ float4 p23 = convert_float4(rsGetElementAt_uchar4(gIn, xs3, ys2));
+ float4 p2 = cubicInterpolate_F4(p20, p21, p22, p23, xf);
+
+ float4 p30 = convert_float4(rsGetElementAt_uchar4(gIn, xs0, ys3));
+ float4 p31 = convert_float4(rsGetElementAt_uchar4(gIn, xs1, ys3));
+ float4 p32 = convert_float4(rsGetElementAt_uchar4(gIn, xs2, ys3));
+ float4 p33 = convert_float4(rsGetElementAt_uchar4(gIn, xs3, ys3));
+ float4 p3 = cubicInterpolate_F4(p30, p31, p32, p33, xf);
+
+ float4 p = cubicInterpolate_F4(p0, p1, p2, p3, yf);
+ p = clamp(p + 0.5f, 0.f, 255.f);
+ return convert_uchar4(p);
+}
+
+uchar3 __attribute__((kernel)) bicubic_U3(uint32_t x, uint32_t y) {
+ float xf = (x + 0.5f) * scaleX - 0.5f;
+ float yf = (y + 0.5f) * scaleY - 0.5f;
+
+ int startx = (int) floor(xf - 1);
+ int starty = (int) floor(yf - 1);
+ xf = xf - floor(xf);
+ yf = yf - floor(yf);
+ int maxx = gWidthIn - 1;
+ int maxy = gHeightIn - 1;
+
+ uint32_t xs0 = (uint32_t) max(0, startx + 0);
+ uint32_t xs1 = (uint32_t) max(0, startx + 1);
+ uint32_t xs2 = (uint32_t) min(maxx, startx + 2);
+ uint32_t xs3 = (uint32_t) min(maxx, startx + 3);
+
+ uint32_t ys0 = (uint32_t) max(0, starty + 0);
+ uint32_t ys1 = (uint32_t) max(0, starty + 1);
+ uint32_t ys2 = (uint32_t) min(maxy, starty + 2);
+ uint32_t ys3 = (uint32_t) min(maxy, starty + 3);
+
+ float3 p00 = convert_float3(rsGetElementAt_uchar3(gIn, xs0, ys0));
+ float3 p01 = convert_float3(rsGetElementAt_uchar3(gIn, xs1, ys0));
+ float3 p02 = convert_float3(rsGetElementAt_uchar3(gIn, xs2, ys0));
+ float3 p03 = convert_float3(rsGetElementAt_uchar3(gIn, xs3, ys0));
+ float3 p0 = cubicInterpolate_F3(p00, p01, p02, p03, xf);
+
+ float3 p10 = convert_float3(rsGetElementAt_uchar3(gIn, xs0, ys1));
+ float3 p11 = convert_float3(rsGetElementAt_uchar3(gIn, xs1, ys1));
+ float3 p12 = convert_float3(rsGetElementAt_uchar3(gIn, xs2, ys1));
+ float3 p13 = convert_float3(rsGetElementAt_uchar3(gIn, xs3, ys1));
+ float3 p1 = cubicInterpolate_F3(p10, p11, p12, p13, xf);
+
+ float3 p20 = convert_float3(rsGetElementAt_uchar3(gIn, xs0, ys2));
+ float3 p21 = convert_float3(rsGetElementAt_uchar3(gIn, xs1, ys2));
+ float3 p22 = convert_float3(rsGetElementAt_uchar3(gIn, xs2, ys2));
+ float3 p23 = convert_float3(rsGetElementAt_uchar3(gIn, xs3, ys2));
+ float3 p2 = cubicInterpolate_F3(p20, p21, p22, p23, xf);
+
+ float3 p30 = convert_float3(rsGetElementAt_uchar3(gIn, xs0, ys3));
+ float3 p31 = convert_float3(rsGetElementAt_uchar3(gIn, xs1, ys3));
+ float3 p32 = convert_float3(rsGetElementAt_uchar3(gIn, xs2, ys3));
+ float3 p33 = convert_float3(rsGetElementAt_uchar3(gIn, xs3, ys3));
+ float3 p3 = cubicInterpolate_F3(p30, p31, p32, p33, xf);
+
+ float3 p = cubicInterpolate_F3(p0, p1, p2, p3, yf);
+ p = clamp(p + 0.5f, 0.f, 255.f);
+ return convert_uchar3(p);
+}
+
+uchar2 __attribute__((kernel)) bicubic_U2(uint32_t x, uint32_t y) {
+ float xf = (x + 0.5f) * scaleX - 0.5f;
+ float yf = (y + 0.5f) * scaleY - 0.5f;
+
+ int startx = (int) floor(xf - 1);
+ int starty = (int) floor(yf - 1);
+ xf = xf - floor(xf);
+ yf = yf - floor(yf);
+ int maxx = gWidthIn - 1;
+ int maxy = gHeightIn - 1;
+
+ uint32_t xs0 = (uint32_t) max(0, startx + 0);
+ uint32_t xs1 = (uint32_t) max(0, startx + 1);
+ uint32_t xs2 = (uint32_t) min(maxx, startx + 2);
+ uint32_t xs3 = (uint32_t) min(maxx, startx + 3);
+
+ uint32_t ys0 = (uint32_t) max(0, starty + 0);
+ uint32_t ys1 = (uint32_t) max(0, starty + 1);
+ uint32_t ys2 = (uint32_t) min(maxy, starty + 2);
+ uint32_t ys3 = (uint32_t) min(maxy, starty + 3);
+
+ float2 p00 = convert_float2(rsGetElementAt_uchar2(gIn, xs0, ys0));
+ float2 p01 = convert_float2(rsGetElementAt_uchar2(gIn, xs1, ys0));
+ float2 p02 = convert_float2(rsGetElementAt_uchar2(gIn, xs2, ys0));
+ float2 p03 = convert_float2(rsGetElementAt_uchar2(gIn, xs3, ys0));
+ float2 p0 = cubicInterpolate_F2(p00, p01, p02, p03, xf);
+
+ float2 p10 = convert_float2(rsGetElementAt_uchar2(gIn, xs0, ys1));
+ float2 p11 = convert_float2(rsGetElementAt_uchar2(gIn, xs1, ys1));
+ float2 p12 = convert_float2(rsGetElementAt_uchar2(gIn, xs2, ys1));
+ float2 p13 = convert_float2(rsGetElementAt_uchar2(gIn, xs3, ys1));
+ float2 p1 = cubicInterpolate_F2(p10, p11, p12, p13, xf);
+
+ float2 p20 = convert_float2(rsGetElementAt_uchar2(gIn, xs0, ys2));
+ float2 p21 = convert_float2(rsGetElementAt_uchar2(gIn, xs1, ys2));
+ float2 p22 = convert_float2(rsGetElementAt_uchar2(gIn, xs2, ys2));
+ float2 p23 = convert_float2(rsGetElementAt_uchar2(gIn, xs3, ys2));
+ float2 p2 = cubicInterpolate_F2(p20, p21, p22, p23, xf);
+
+ float2 p30 = convert_float2(rsGetElementAt_uchar2(gIn, xs0, ys3));
+ float2 p31 = convert_float2(rsGetElementAt_uchar2(gIn, xs1, ys3));
+ float2 p32 = convert_float2(rsGetElementAt_uchar2(gIn, xs2, ys3));
+ float2 p33 = convert_float2(rsGetElementAt_uchar2(gIn, xs3, ys3));
+ float2 p3 = cubicInterpolate_F2(p30, p31, p32, p33, xf);
+
+ float2 p = cubicInterpolate_F2(p0, p1, p2, p3, yf);
+ p = clamp(p + 0.5f, 0.f, 255.f);
+ return convert_uchar2(p);
+}
+
+uchar __attribute__((kernel)) bicubic_U1(uint32_t x, uint32_t y) {
+ float xf = (x + 0.5f) * scaleX - 0.5f;
+ float yf = (y + 0.5f) * scaleY - 0.5f;
+
+ int startx = (int) floor(xf - 1);
+ int starty = (int) floor(yf - 1);
+ xf = xf - floor(xf);
+ yf = yf - floor(yf);
+ int maxx = gWidthIn - 1;
+ int maxy = gHeightIn - 1;
+
+ uint32_t xs0 = (uint32_t) max(0, startx + 0);
+ uint32_t xs1 = (uint32_t) max(0, startx + 1);
+ uint32_t xs2 = (uint32_t) min(maxx, startx + 2);
+ uint32_t xs3 = (uint32_t) min(maxx, startx + 3);
+
+ uint32_t ys0 = (uint32_t) max(0, starty + 0);
+ uint32_t ys1 = (uint32_t) max(0, starty + 1);
+ uint32_t ys2 = (uint32_t) min(maxy, starty + 2);
+ uint32_t ys3 = (uint32_t) min(maxy, starty + 3);
+
+ float p00 = (float)(rsGetElementAt_uchar(gIn, xs0, ys0));
+ float p01 = (float)(rsGetElementAt_uchar(gIn, xs1, ys0));
+ float p02 = (float)(rsGetElementAt_uchar(gIn, xs2, ys0));
+ float p03 = (float)(rsGetElementAt_uchar(gIn, xs3, ys0));
+ float p0 = cubicInterpolate_F1(p00, p01, p02, p03, xf);
+
+ float p10 = (float)(rsGetElementAt_uchar(gIn, xs0, ys1));
+ float p11 = (float)(rsGetElementAt_uchar(gIn, xs1, ys1));
+ float p12 = (float)(rsGetElementAt_uchar(gIn, xs2, ys1));
+ float p13 = (float)(rsGetElementAt_uchar(gIn, xs3, ys1));
+ float p1 = cubicInterpolate_F1(p10, p11, p12, p13, xf);
+
+ float p20 = (float)(rsGetElementAt_uchar(gIn, xs0, ys2));
+ float p21 = (float)(rsGetElementAt_uchar(gIn, xs1, ys2));
+ float p22 = (float)(rsGetElementAt_uchar(gIn, xs2, ys2));
+ float p23 = (float)(rsGetElementAt_uchar(gIn, xs3, ys2));
+ float p2 = cubicInterpolate_F1(p20, p21, p22, p23, xf);
+
+ float p30 = (float)(rsGetElementAt_uchar(gIn, xs0, ys3));
+ float p31 = (float)(rsGetElementAt_uchar(gIn, xs1, ys3));
+ float p32 = (float)(rsGetElementAt_uchar(gIn, xs2, ys3));
+ float p33 = (float)(rsGetElementAt_uchar(gIn, xs3, ys3));
+ float p3 = cubicInterpolate_F1(p30, p31, p32, p33, xf);
+
+ float p = cubicInterpolate_F1(p0, p1, p2, p3, yf);
+ p = clamp(p + 0.5f, 0.f, 255.f);
+ return (uchar)p;
+}
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/vload.rs b/tests/tests/renderscript/src/android/renderscript/cts/vload.rs
new file mode 100644
index 0000000..cdf5fd1
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/vload.rs
@@ -0,0 +1,60 @@
+ /*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+rs_allocation gAllocIn;
+rs_allocation gAllocOut;
+
+
+
+#define COPY_2D(ty) \
+ void __attribute__((kernel)) copy2d_##ty(int xy_v) { \
+ int lx = xy_v & 0xff; \
+ int vecsize = (xy_v & 0xff0000) >> 16; \
+ switch(vecsize) { \
+ case 1: { \
+ ty i = rsGetElementAt_##ty(gAllocIn, lx); \
+ rsSetElementAt_##ty(gAllocOut, i, lx); \
+ } break; \
+ case 2: { \
+ ty##2 i = rsAllocationVLoadX_##ty##2(gAllocIn, lx); \
+ rsAllocationVStoreX_##ty##2(gAllocOut, i, lx); \
+ } break; \
+ case 3: { \
+ ty##3 i = rsAllocationVLoadX_##ty##3(gAllocIn, lx); \
+ rsAllocationVStoreX_##ty##3(gAllocOut, i, lx); \
+ } break; \
+ case 4: { \
+ ty##4 i = rsAllocationVLoadX_##ty##4(gAllocIn, lx); \
+ rsAllocationVStoreX_##ty##4(gAllocOut, i, lx); \
+ } break; \
+ } \
+ }
+
+COPY_2D(char)
+COPY_2D(uchar)
+COPY_2D(short)
+COPY_2D(ushort)
+COPY_2D(int)
+COPY_2D(uint)
+COPY_2D(long)
+COPY_2D(ulong)
+
+COPY_2D(float)
+COPY_2D(double)
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/vload_relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/vload_relaxed.rs
new file mode 100644
index 0000000..61940ba
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/vload_relaxed.rs
@@ -0,0 +1,62 @@
+ /*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+#pragma rs_fp_relaxed
+
+rs_allocation gAllocIn;
+rs_allocation gAllocOut;
+
+
+
+#define COPY_2D(ty) \
+ void __attribute__((kernel)) copy2d_##ty(int xy_v) { \
+ int lx = xy_v & 0xff; \
+ int vecsize = (xy_v & 0xff0000) >> 16; \
+ switch(vecsize) { \
+ case 1: { \
+ ty i = rsGetElementAt_##ty(gAllocIn, lx); \
+ rsSetElementAt_##ty(gAllocOut, i, lx); \
+ } break; \
+ case 2: { \
+ ty##2 i = rsAllocationVLoadX_##ty##2(gAllocIn, lx); \
+ rsAllocationVStoreX_##ty##2(gAllocOut, i, lx); \
+ } break; \
+ case 3: { \
+ ty##3 i = rsAllocationVLoadX_##ty##3(gAllocIn, lx); \
+ rsAllocationVStoreX_##ty##3(gAllocOut, i, lx); \
+ } break; \
+ case 4: { \
+ ty##4 i = rsAllocationVLoadX_##ty##4(gAllocIn, lx); \
+ rsAllocationVStoreX_##ty##4(gAllocOut, i, lx); \
+ } break; \
+ } \
+ }
+
+COPY_2D(char)
+COPY_2D(uchar)
+COPY_2D(short)
+COPY_2D(ushort)
+COPY_2D(int)
+COPY_2D(uint)
+COPY_2D(long)
+COPY_2D(ulong)
+
+COPY_2D(float)
+COPY_2D(double)
+
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index de58783..c41ee58 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -34,22 +34,6 @@
LOCAL_SDK_VERSION := current
-intermediates.COMMON := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)
-
-sepolicy_asset_dir := $(intermediates.COMMON)/assets
-
-LOCAL_ASSET_DIR := $(sepolicy_asset_dir)
-
include $(BUILD_CTS_PACKAGE)
-selinux_policy.xml := $(sepolicy_asset_dir)/selinux_policy.xml
-selinux_policy_parser := cts/tools/selinux/src/gen_SELinux_CTS.py
-general_sepolicy_policy.conf := $(call intermediates-dir-for,ETC,general_sepolicy.conf)/general_sepolicy.conf
-$(selinux_policy.xml): PRIVATE_POLICY_PARSER := $(selinux_policy_parser)
-$(selinux_policy.xml): $(general_sepolicy_policy.conf) $(selinux_policy_parser)
- mkdir -p $(dir $@)
- $(PRIVATE_POLICY_PARSER) $< $@ neverallow_only=t
-
-$(R_file_stamp): $(selinux_policy.xml)
-
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
index 9daa2cb..fac8f89 100644
--- a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
@@ -35,10 +35,10 @@
{
aps = 0;
if (output != NULL) {
- *output = 0;
+ *output = AUDIO_IO_HANDLE_NONE;
}
if (session != NULL) {
- *session = 0;
+ *session = AUDIO_UNIQUE_ID_ALLOCATE;
}
int64_t startTime = 0;
@@ -60,19 +60,24 @@
if (output != NULL) {
// get a valid output. Any use case will do.
- for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
+ for (int stream = AUDIO_STREAM_MIN; stream < AUDIO_STREAM_CNT; stream++) {
*output = AudioSystem::getOutput((audio_stream_type_t)stream);
- if (*output != 0) {
+ if (*output != AUDIO_IO_HANDLE_NONE) {
break;
}
}
- if (*output == 0) {
+ if (*output == AUDIO_IO_HANDLE_NONE) {
ALOGE("cannot get valid audio output");
return false;
}
}
if (session != NULL) {
- *session = 10000;
+ //get a valid session
+ *session = AudioSystem::newAudioUniqueId();
+ if (*session == AUDIO_UNIQUE_ID_ALLOCATE) {
+ ALOGE("cannot get valid audio session");
+ return false;
+ }
}
return true;
}
@@ -92,11 +97,13 @@
return false;
}
- status_t status = aps->startOutput(output, (audio_stream_type_t)(-1), session);
+ status_t status = aps->startOutput(output, (audio_stream_type_t)(AUDIO_STREAM_MIN -1),
+ (audio_session_t)session);
if (status == NO_ERROR) {
return false;
}
- status = aps->startOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT, session);
+ status = aps->startOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT,
+ (audio_session_t)session);
if (status == NO_ERROR) {
return false;
}
@@ -118,11 +125,13 @@
return false;
}
- status_t status = aps->stopOutput(output, (audio_stream_type_t)(-1), session);
+ status_t status = aps->stopOutput(output, (audio_stream_type_t)(AUDIO_STREAM_MIN -1),
+ (audio_session_t)session);
if (status == NO_ERROR) {
return false;
}
- status = aps->stopOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT, session);
+ status = aps->stopOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT,
+ (audio_session_t)session);
if (status == NO_ERROR) {
return false;
}
@@ -142,7 +151,7 @@
return false;
}
- status_t status = aps->isStreamActive((audio_stream_type_t)(-1), 0);
+ status_t status = aps->isStreamActive((audio_stream_type_t)(AUDIO_STREAM_MIN -1), 0);
if (status == NO_ERROR) {
return false;
}
@@ -153,6 +162,31 @@
return true;
}
+/*
+ * Checks that IAudioPolicyService::isStreamActiveRemotely() cannot be called with an
+ * invalid stream type.
+ * Test with NUM_RANDOM_TESTS random values for stream type.
+ */
+jboolean android_security_cts_AudioPolicy_test_isStreamActiveRemotely(JNIEnv* env __unused,
+ jobject thiz __unused)
+{
+ sp<IAudioPolicyService> aps;
+
+ if (!init(aps, NULL, NULL)) {
+ return false;
+ }
+
+ status_t status = aps->isStreamActiveRemotely((audio_stream_type_t)(AUDIO_STREAM_MIN -1), 0);
+ if (status == NO_ERROR) {
+ return false;
+ }
+ status = aps->isStreamActiveRemotely((audio_stream_type_t)AUDIO_STREAM_CNT, 0);
+ if (status == NO_ERROR) {
+ return false;
+ }
+ return true;
+}
+
static JNINativeMethod gMethods[] = {
{ "native_test_startOutput", "()Z",
(void *) android_security_cts_AudioPolicy_test_startOutput },
@@ -160,6 +194,8 @@
(void *) android_security_cts_AudioPolicy_test_stopOutput },
{ "native_test_isStreamActive", "()Z",
(void *) android_security_cts_AudioPolicy_test_isStreamActive },
+ { "native_test_isStreamActiveRemotely", "()Z",
+ (void *) android_security_cts_AudioPolicy_test_isStreamActiveRemotely },
};
int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env)
diff --git a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java b/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
index 399d8bb..b307247 100644
--- a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
+++ b/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
@@ -48,7 +48,16 @@
assertTrue(native_test_isStreamActive());
}
+ /**
+ * Checks that IAudioPolicyService::isStreamActiveRemotely() cannot be called with an
+ * invalid stream type.
+ */
+ public void test_isStreamActiveRemotely() throws Exception {
+ assertTrue(native_test_isStreamActiveRemotely());
+ }
+
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();
}
diff --git a/tests/tests/security/src/android/security/cts/SELinuxPolicyRule.java b/tests/tests/security/src/android/security/cts/SELinuxPolicyRule.java
deleted file mode 100644
index d06fd75..0000000
--- a/tests/tests/security/src/android/security/cts/SELinuxPolicyRule.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2014 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.util.Xml;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.HashMap;
-
-
-/**
- * A class for generating representations of SELinux avc rules parsed from an xml file.
- */
-public class SELinuxPolicyRule {
- public final List<String> source_types;
- public final List<String> target_types;
- public final Multimap<String, String> obj_classes;
- public final String name;
- public final String type;
-
- private SELinuxPolicyRule(List<String> source_types, List<String> target_types,
- Multimap<String, String> obj_classes, String name, String type) {
- this.source_types = source_types;
- this.target_types = target_types;
- this.obj_classes = obj_classes;
- this.name = name;
- this.type = type;
- }
-
- public static SELinuxPolicyRule readRule(XmlPullParser xpp) throws IOException, XmlPullParserException {
- List<String> source_types = new ArrayList<String>();
- List<String> target_types = new ArrayList<String>();
- Multimap<String, String> obj_classes = HashMultimap.create();
- xpp.require(XmlPullParser.START_TAG, null, "avc_rule");
- String ruleName = xpp.getAttributeValue(null, "name");
- String ruleType = xpp.getAttributeValue(null, "type");
- while (xpp.next() != XmlPullParser.END_TAG) {
- if (xpp.getEventType() != XmlPullParser.START_TAG) {
- continue;
- }
- String name = xpp.getName();
- if (name.equals("type")) {
- if (xpp.getAttributeValue(null, "type").equals("source")) {
- source_types.add(readType(xpp));
- } else if (xpp.getAttributeValue(null, "type").equals("target")) {
- target_types.add(readType(xpp));
- } else {
- skip(xpp);
- }
- } else if (name.equals("obj_class")) {
- String obj_name = xpp.getAttributeValue(null, "name");
- List<String> perms = readObjClass(xpp);
- obj_classes.putAll(obj_name, perms);
- } else {
- skip(xpp);
- }
- }
- return new SELinuxPolicyRule(source_types, target_types, obj_classes, ruleName, ruleType);
- }
-
- public static List<SELinuxPolicyRule> readRulesFile(InputStream in) throws IOException, XmlPullParserException {
- List<SELinuxPolicyRule> rules = new ArrayList<SELinuxPolicyRule>();
- XmlPullParser xpp = Xml.newPullParser();
- xpp.setInput(in, null);
- xpp.nextTag();
- xpp.require(XmlPullParser.START_TAG, null, "SELinux_AVC_Rules");
-
- /* read rules */
- while (xpp.next() != XmlPullParser.END_TAG) {
- if (xpp.getEventType() != XmlPullParser.START_TAG) {
- continue;
- }
- String name = xpp.getName();
- if (name.equals("avc_rule")) {
- SELinuxPolicyRule r = readRule(xpp);
- rules.add(r);
- } else {
- skip(xpp);
- }
- }
- return rules;
- }
-
- private static List<String> readObjClass(XmlPullParser xpp) throws IOException, XmlPullParserException {
- List<String> perms = new ArrayList<String>();
- xpp.require(XmlPullParser.START_TAG, null, "obj_class");
- while (xpp.next() != XmlPullParser.END_TAG) {
- if (xpp.getEventType() != XmlPullParser.START_TAG) {
- continue;
- }
- String name = xpp.getName();
- if (name.equals("permission")) {
- perms.add(readPermission(xpp));
- } else {
- skip(xpp);
- }
- }
- return perms;
- }
-
- private static String readType(XmlPullParser xpp) throws IOException, XmlPullParserException {
- xpp.require(XmlPullParser.START_TAG, null, "type");
- String type = readText(xpp);
- xpp.require(XmlPullParser.END_TAG, null, "type");
- return type;
- }
-
- private static String readPermission(XmlPullParser xpp) throws IOException, XmlPullParserException {
- xpp.require(XmlPullParser.START_TAG, null, "permission");
- String permission = readText(xpp);
- xpp.require(XmlPullParser.END_TAG, null, "permission");
- return permission;
- }
-
- private static String readText(XmlPullParser xpp) throws IOException, XmlPullParserException {
- String result = "";
- if (xpp.next() == XmlPullParser.TEXT) {
- result = xpp.getText();
- xpp.nextTag();
- }
- return result;
- }
-
- public static void skip(XmlPullParser xpp) throws XmlPullParserException, IOException {
- if (xpp.getEventType() != XmlPullParser.START_TAG) {
- throw new IllegalStateException();
- }
- int depth = 1;
- while (depth != 0) {
- switch (xpp.next()) {
- case XmlPullParser.END_TAG:
- depth--;
- break;
- case XmlPullParser.START_TAG:
- depth++;
- break;
- }
- }
- }
-}
diff --git a/tests/tests/security/src/android/security/cts/SELinuxTest.java b/tests/tests/security/src/android/security/cts/SELinuxTest.java
index 8e57037..711cb91 100644
--- a/tests/tests/security/src/android/security/cts/SELinuxTest.java
+++ b/tests/tests/security/src/android/security/cts/SELinuxTest.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.content.res.AssetManager;
-import android.security.cts.SELinuxPolicyRule;
import android.test.AndroidTestCase;
import junit.framework.TestCase;
@@ -82,130 +81,6 @@
assertEquals(0, files.length);
}
- /**
- * Verify all of the rules described by the selinux_policy.xml file are in effect. Allow rules
- * should return access granted, and Neverallow should return access denied. All checks are run
- * and then a list of specific failed checks is printed.
- */
- public void testSELinuxPolicyFile() throws IOException, XmlPullParserException {
- List<String> failedChecks = new ArrayList<String>();
- Map<String, Boolean> contextsCache = new HashMap<String, Boolean>();
- int invalidContextsCount = 0;
- int totalChecks = 0;
- int totalFailedChecks = 0;
- AssetManager assets = mContext.getAssets();
- InputStream in = assets.open("selinux_policy.xml");
- Collection<SELinuxPolicyRule> rules = SELinuxPolicyRule.readRulesFile(in);
- for (SELinuxPolicyRule r : rules) {
- PolicyFileTestResult result = runRuleChecks(r, contextsCache);
- totalChecks += result.numTotalChecks;
- if (result.numFailedChecks != 0) {
- totalFailedChecks += result.numFailedChecks;
-
- /* print failures to log, so as not to run OOM in the event of large policy mismatch,
- but record actual rule type and number */
- failedChecks.add("SELinux avc rule " + r.type + r.name + " failed " + result.numFailedChecks +
- " out of " + result.numTotalChecks + " checks.");
- for (String k : result.failedChecks) {
- System.out.println(r.type + r.name + " failed " + k);
- }
- }
- }
- if (totalFailedChecks != 0) {
-
- /* print out failed rules, just the rule number and type */
- for (String k : failedChecks) {
- System.out.println(k);
- }
- System.out.println("Failed SELinux Policy Test: " + totalFailedChecks + " failed out of " + totalChecks);
- }
- for (String k : contextsCache.keySet()) {
- if (!contextsCache.get(k)) {
- invalidContextsCount++;
- System.out.println("Invalid SELinux context encountered: " + k);
- }
- }
- System.out.println("SELinuxPolicy Test Encountered: " + invalidContextsCount + " missing contexts out of " + contextsCache.size());
- assertTrue(totalFailedChecks == 0);
- }
-
- /**
- * A class for containing all of the results we care to know from checking each SELinux rule
- */
- private class PolicyFileTestResult {
- private int numTotalChecks;
- private int numFailedChecks;
- private List<String> failedChecks = new ArrayList<String>();
- }
-
- private PolicyFileTestResult runRuleChecks(SELinuxPolicyRule r, Map<String, Boolean> contextsCache) {
- PolicyFileTestResult result = new PolicyFileTestResult();
-
- /* run checks by going through every possible 4-tuple specified by rule. Start with class
- and perm to allow early-exit based on context. */
- for (String c : r.obj_classes.keySet()) {
- for (String p : r.obj_classes.get(c)) {
- for (String s : r.source_types) {
-
- /* check source context */
- String source_context = createAvcContext(s, false, c, p);
- if (!contextsCache.containsKey(source_context)) {
- contextsCache.put(source_context, checkSELinuxContext(source_context));
- }
- if (!contextsCache.get(source_context)) {
- continue;
- }
- for (String t : r.target_types) {
- if (t.equals("self")) {
- t = s;
- }
-
- /* check target context */
- String target_context = createAvcContext(t, true, c, p);
- if (!contextsCache.containsKey(target_context)) {
- contextsCache.put(target_context, checkSELinuxContext(target_context));
- }
- if (!contextsCache.get(target_context)) {
- continue;
- }
- boolean canAccess = checkSELinuxAccess(source_context, target_context,
- c, p, "");
- result.numTotalChecks++;
- if ((r.type.equals("allow") && !canAccess)
- || (r.type.equals("neverallow") && canAccess)) {
- String failureNotice = s + ", " + t + ", " + c + ", " + p;
- result.numFailedChecks++;
- result.failedChecks.add(failureNotice);
- }
- }
- }
- }
- }
- return result;
- }
-
- /* createAvcContext - currently uses class type and perm to determine user, role and mls values.
- *
- * @param target - false if source domain, true if target.
- */
- private String createAvcContext(String domain, boolean target,
- String obj_class, String perm) {
- String usr = "u";
- String role;
-
- /* understand role labeling better */
- if (obj_class.equals("filesystem") && perm.equals("associate")) {
- role = "object_r";
- } else if(obj_class.equals("process") || obj_class.endsWith("socket")) {
- role = "r";
- } else if (target) {
- role = "object_r";
- } else {
- role = "r";
- }
- return String.format("%s:%s:%s:s0", usr, role, domain);
- }
-
private static native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm, String extra);
private static native boolean checkSELinuxContext(String con);
diff --git a/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java b/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
new file mode 100644
index 0000000..661b175
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2014 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.telephony.cts;
+
+import android.content.Context;
+import android.telephony.SmsManager;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+
+public class SimRestrictedApisTest extends AndroidTestCase {
+ private static final byte[] TEST_PDU = {
+ 0, 0 };
+ private TelephonyManager mTelephonyManager;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTelephonyManager =
+ (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
+ }
+
+ private boolean isSimCardPresent() {
+ return mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_ABSENT;
+ }
+
+ /**
+ * Tests the SmsManager.injectSmsPdu() API. This makes a call to injectSmsPdu() API and expects
+ * a SecurityException since the test apk is not signed by a certificate on the SIM.
+ */
+ public void testInjectSmsPdu() {
+ try {
+ if (isSimCardPresent()) {
+ SmsManager.getDefault().injectSmsPdu(TEST_PDU, "3gpp", null);
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the SmsManager.updateMmsDownloadStatus() API. This makes a call to
+ * updateMmsDownloadStatus() API and expects a SecurityException since the test apk is not
+ * signed by a certificate on the SIM.
+ */
+ public void testUpdateMmsDownloadStatus() {
+ try {
+ if (isSimCardPresent()) {
+ SmsManager.getDefault().updateMmsDownloadStatus(null, 0, 0, null);
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the SmsManager.updateMmsSendStatus() API. This makes a call to updateMmsSendStatus()
+ * API and expects a SecurityException since the test apk is not signed by a certificate on the
+ * SIM.
+ */
+ public void testUpdateMmsSendStatus() {
+ try {
+ if (isSimCardPresent()) {
+ SmsManager.getDefault().updateMmsSendStatus(null, 0, TEST_PDU, 0, null);
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the SmsManager.updateSmsSendStatus() API. This makes a call to updateSmsSendStatus()
+ * API and expects a SecurityException since the test apk is not signed by a certificate on the
+ * SIM.
+ */
+ public void testUpdateSmsSendStatus() {
+ try {
+ if (isSimCardPresent()) {
+ SmsManager.getDefault().updateSmsSendStatus(0, false);
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.setLine1NumberForDisplay() API. This makes a call to
+ * setLine1NumberForDisplay() API and expects a SecurityException since the test apk is not
+ * signed by a certificate on the SIM.
+ */
+ public void testSetLine1NumberForDisplay() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().setLine1NumberForDisplay("", "");
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.setLine1NumberForDisplay(long, string, string) API. This makes a
+ * call to setLine1NumberForDisplay() API and expects a SecurityException since the test apk is
+ * not signed by the certificate on the SIM.
+ */
+ public void testSetLine1NumberForDisplay2() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().setLine1NumberForDisplayForSubscriber(0, "", "");
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.iccOpenLogicalChannel() API. This makes a call to
+ * iccOpenLogicalChannel() API and expects a SecurityException since the test apk is not signed
+ * by certificate on the SIM.
+ */
+ public void testIccOpenLogicalChannel() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().iccOpenLogicalChannel("");
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.iccCloseLogicalChannel() API. This makes a call to
+ * iccCloseLogicalChannel() API and expects a SecurityException since the test apk is not signed
+ * by certificate on the SIM.
+ */
+ public void testIccCloseLogicalChannel() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().iccCloseLogicalChannel(0);
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.iccTransmitApduLogicalChannel() API. This makes a call to
+ * iccTransmitApduLogicalChannel() API and expects a SecurityException since the test apk is not
+ * signed by a certificate on the SIM.
+ */
+ public void testIccTransmitApduLogicalChannel() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().iccTransmitApduLogicalChannel(0, 0, 0, 0, 0, 0, "");
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.iccTransmitApduBasicChannel() API. This makes a call to
+ * iccTransmitApduBasicChannel() API and expects a SecurityException since the test apk is not
+ * signed by a certificate on the SIM.
+ */
+ public void testIccTransmitApduBasicChannel() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().iccTransmitApduBasicChannel(0, 0, 0, 0, 0, "");
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.sendEnvelopeWithStatus() API. This makes a call to
+ * sendEnvelopeWithStatus() API and expects a SecurityException since the test apk is not signed
+ * by certificate on the SIM.
+ */
+ public void testSendEnvelopeWithStatus() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().sendEnvelopeWithStatus("");
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.nvReadItem() API. This makes a call to nvReadItem() API and
+ * expects a SecurityException since the test apk is not signed by a certificate on the SIM.
+ */
+ public void testNvReadItem() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().nvReadItem(0);
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.nvWriteItem() API. This makes a call to nvWriteItem() API and
+ * expects a SecurityException since the test apk is not signed by a certificate on the SIM.
+ */
+ public void testNvWriteItem() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().nvWriteItem(0, "");
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.nvWriteCdmaPrl() API. This makes a call to nvWriteCdmaPrl() API
+ * and expects a SecurityException since the test apk is not signed by a certificate on the SIM.
+ */
+ public void testNvWriteCdmaPrl() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().nvWriteCdmaPrl(null);
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.nvResetConfig() API. This makes a call to nvResetConfig() API and
+ * expects a SecurityException since the test apk is not signed by a certificate on the SIM.
+ */
+ public void testNvResetConfig() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().nvResetConfig(0);
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.getPreferredNetworkType() API. This makes a call to
+ * getPreferredNetworkType() API and expects a SecurityException since the test apk is not
+ * signed by certificate on the SIM.
+ */
+ public void testGetPreferredNetworkType() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().getPreferredNetworkType();
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.setGlobalPreferredNetworkType() API. This makes a call to
+ * setGlobalPreferredNetworkType() API and expects a SecurityException since the test apk is not
+ * signed by certificate on the SIM.
+ */
+ public void testSetGlobalPreferredNetworkType() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().setGlobalPreferredNetworkType();
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+
+ /**
+ * Tests that the test apk doesn't have carrier previliges.
+ */
+ public void testHasCarrierPrivileges() {
+ if (TelephonyManager.getDefault().hasCarrierPrivileges()) {
+ fail("App unexpectedly has carrier privileges");
+ }
+ }
+
+ /**
+ * Tests the TelephonyManager.setOperatorBrandOverride() API. This makes a call to
+ * setOperatorBrandOverride() API and expects a SecurityException since the test apk is not
+ * signed by certificate on the SIM.
+ */
+ public void testSetOperatorBrandOverride() {
+ try {
+ if (isSimCardPresent()) {
+ TelephonyManager.getDefault().setOperatorBrandOverride("");
+ fail("Expected SecurityException. App doesn't have carrier privileges.");
+ }
+ } catch (SecurityException expected) {
+ }
+ }
+}
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
index 651a199a..017fadd 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
@@ -395,4 +395,132 @@
verifyOverlap(programEndMillis + hour, programEndMillis + hour * 2, 0,
channelId, channelUri);
}
+
+ private void verifyQueryWithSortOrder(Uri uri, final String[] projection,
+ String sortOrder) throws Exception {
+ try {
+ getContext().getContentResolver().query(uri, projection, null, null, sortOrder);
+ fail("Setting sortOrder should fail without ACCESS_ALL_EPG_DATA permission for " + uri);
+ } catch (SecurityException e) {
+ // Expected exception
+ }
+ }
+
+ private void verifyQueryWithSelection(Uri uri, final String[] projection,
+ String selection) throws Exception {
+ try {
+ getContext().getContentResolver().query(uri, projection, selection, null, null);
+ fail("Setting selection should fail without ACCESS_ALL_EPG_DATA permission for " + uri);
+ } catch (SecurityException e) {
+ // Expected exception
+ }
+ }
+
+ private void verifyUpdateWithSelection(Uri uri, String selection) throws Exception {
+ try {
+ ContentValues values = new ContentValues();
+ getContext().getContentResolver().update(uri, values, selection, null);
+ fail("Setting selection should fail without ACCESS_ALL_EPG_DATA permission for " + uri);
+ } catch (SecurityException e) {
+ // Expected exception
+ }
+ }
+
+ private void verifyDeleteWithSelection(Uri uri, String selection) throws Exception {
+ try {
+ getContext().getContentResolver().delete(uri, selection, null);
+ fail("Setting selection should fail without ACCESS_ALL_EPG_DATA permission for " + uri);
+ } catch (SecurityException e) {
+ // Expected exception
+ }
+ }
+
+ public void testAllEpgPermissionBlocksSortOrderOnQuery_Channels() throws Exception {
+ if (!Utils.hasTvInputFramework(getContext())) {
+ return;
+ }
+ final String[] projection = { TvContract.Channels._ID };
+ verifyQueryWithSortOrder(TvContract.Channels.CONTENT_URI, projection,
+ TvContract.Channels._ID + " ASC");
+ }
+
+ public void testAllEpgPermissionBlocksSelectionOnQuery_Channels() throws Exception {
+ if (!Utils.hasTvInputFramework(getContext())) {
+ return;
+ }
+ final String[] projection = { TvContract.Channels._ID };
+ verifyQueryWithSelection(TvContract.Channels.CONTENT_URI, projection,
+ TvContract.Channels._ID + ">0");
+ }
+
+ public void testAllEpgPermissionBlocksSelectionOnUpdate_Channels() throws Exception {
+ if (!Utils.hasTvInputFramework(getContext())) {
+ return;
+ }
+ verifyUpdateWithSelection(TvContract.Channels.CONTENT_URI,
+ TvContract.Channels._ID + ">0");
+ }
+
+ public void testAllEpgPermissionBlocksSelectionOnDelete_Channels() throws Exception {
+ if (!Utils.hasTvInputFramework(getContext())) {
+ return;
+ }
+ verifyDeleteWithSelection(TvContract.Channels.CONTENT_URI,
+ TvContract.Channels._ID + ">0");
+ }
+
+ public void testAllEpgPermissionBlocksSortOrderOnQuery_Programs() throws Exception {
+ if (!Utils.hasTvInputFramework(getContext())) {
+ return;
+ }
+ final String[] projection = { TvContract.Programs._ID };
+ verifyQueryWithSortOrder(TvContract.Programs.CONTENT_URI, projection,
+ TvContract.Programs._ID + " ASC");
+ }
+
+ public void testAllEpgPermissionBlocksSelectionOnQuery_Programs() throws Exception {
+ if (!Utils.hasTvInputFramework(getContext())) {
+ return;
+ }
+ final String[] projection = { TvContract.Channels._ID };
+ verifyQueryWithSelection(TvContract.Programs.CONTENT_URI, projection,
+ TvContract.Programs._ID + ">0");
+ }
+
+ public void testAllEpgPermissionBlocksSelectionOnUpdate_Programs() throws Exception {
+ if (!Utils.hasTvInputFramework(getContext())) {
+ return;
+ }
+ verifyUpdateWithSelection(TvContract.Programs.CONTENT_URI,
+ TvContract.Programs._ID + ">0");
+ }
+
+ public void testAllEpgPermissionBlocksSelectionOnDelete_Programs() throws Exception {
+ if (!Utils.hasTvInputFramework(getContext())) {
+ return;
+ }
+ verifyDeleteWithSelection(TvContract.Programs.CONTENT_URI,
+ TvContract.Programs._ID + ">0");
+ }
+
+ public void testDefaultValues() throws Exception {
+ if (!Utils.hasTvInputFramework(getContext())) {
+ return;
+ }
+ ContentValues values = new ContentValues();
+ values.put(TvContract.Channels.COLUMN_INPUT_ID, mInputId);
+ Uri channelUri = mContentResolver.insert(mChannelsUri, values);
+ assertNotNull(channelUri);
+ long channelId = ContentUris.parseId(channelUri);
+ try (Cursor cursor = mContentResolver.query(
+ channelUri, CHANNELS_PROJECTION, null, null, null)) {
+ cursor.moveToNext();
+ assertEquals(TvContract.Channels.TYPE_OTHER,
+ cursor.getString(cursor.getColumnIndex(TvContract.Channels.COLUMN_TYPE)));
+ assertEquals(TvContract.Channels.SERVICE_TYPE_AUDIO_VIDEO,
+ cursor.getString(cursor.getColumnIndex(
+ TvContract.Channels.COLUMN_SERVICE_TYPE)));
+ }
+ values.clear();
+ }
}
diff --git a/tests/tests/view/res/anim-land/changing_reset_state_anim.xml b/tests/tests/view/res/anim-land/changing_reset_state_anim.xml
new file mode 100644
index 0000000..0b3279a
--- /dev/null
+++ b/tests/tests/view/res/anim-land/changing_reset_state_anim.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="100dp" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="100dp" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="100dp" android:valueType="floatType"/>
+</set>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim-land/changing_state_list_animator.xml b/tests/tests/view/res/anim-land/changing_state_list_animator.xml
new file mode 100644
index 0000000..4c1c41e
--- /dev/null
+++ b/tests/tests/view/res/anim-land/changing_state_list_animator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="10" android:valueType="floatType"/>
+ </item>
+ <!-- base state-->
+ <item>
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="200dp" android:valueType="floatType"/>
+ </item>
+</selector>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim-land/changing_test_animator.xml b/tests/tests/view/res/anim-land/changing_test_animator.xml
new file mode 100644
index 0000000..d5c83cd
--- /dev/null
+++ b/tests/tests/view/res/anim-land/changing_test_animator.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<!-- if you change this, you should also change AnimatorInflaterTest#testLoadAnimator-->
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="x" android:duration="100"
+ android:interpolator="@android:anim/bounce_interpolator"
+ android:valueTo="1" android:valueType="floatType"/>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/changing_reset_state_anim.xml b/tests/tests/view/res/anim/changing_reset_state_anim.xml
new file mode 100644
index 0000000..dd2b233
--- /dev/null
+++ b/tests/tests/view/res/anim/changing_reset_state_anim.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="50dp" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="50dp" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="50dp" android:valueType="floatType"/>
+</set>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/changing_state_list_animator.xml b/tests/tests/view/res/anim/changing_state_list_animator.xml
new file mode 100644
index 0000000..6bcc0d9
--- /dev/null
+++ b/tests/tests/view/res/anim/changing_state_list_animator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="10" android:valueType="floatType"/>
+ </item>
+ <!-- base state-->
+ <item>
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="100dp" android:valueType="floatType"/>
+ </item>
+</selector>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/changing_test_animator.xml b/tests/tests/view/res/anim/changing_test_animator.xml
new file mode 100644
index 0000000..739a71b
--- /dev/null
+++ b/tests/tests/view/res/anim/changing_test_animator.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<!-- if you change this, you should also change AnimatorInflaterTest#testLoadAnimator-->
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="x" android:duration="100"
+ android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+ android:valueTo="1" android:valueType="floatType"/>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/reset_state_anim.xml b/tests/tests/view/res/anim/reset_state_anim.xml
new file mode 100644
index 0000000..4bbbe62
--- /dev/null
+++ b/tests/tests/view/res/anim/reset_state_anim.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+</set>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/test_animator.xml b/tests/tests/view/res/anim/test_animator.xml
new file mode 100644
index 0000000..94e9ec8
--- /dev/null
+++ b/tests/tests/view/res/anim/test_animator.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- if you change this, you should also change AnimatorInflaterTest#testLoadAnimator-->
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="@dimen/test_animator_target_x" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="@dimen/test_animator_target_y" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="left" android:duration="100" android:valueTo="2" android:valueType="intType"/>
+</set>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/test_state_list_animator.xml b/tests/tests/view/res/anim/test_state_list_animator.xml
new file mode 100644
index 0000000..b6a4822
--- /dev/null
+++ b/tests/tests/view/res/anim/test_state_list_animator.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <set>
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="10" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="20" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="20" android:valueType="floatType"/>
+ </set>
+ </item>
+ <item android:state_enabled="true" android:state_pressed="false">
+ <set>
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </item>
+ <!-- base state-->
+ <item android:animation="@anim/reset_state_anim"/>
+</selector>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/test_state_list_animator_2.xml b/tests/tests/view/res/anim/test_state_list_animator_2.xml
new file mode 100644
index 0000000..6aeb41f
--- /dev/null
+++ b/tests/tests/view/res/anim/test_state_list_animator_2.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="10" android:valueType="floatType"/>
+ </item>
+ <!-- base state-->
+ <item android:animation="@anim/changing_reset_state_anim"/>
+</selector>
\ No newline at end of file
diff --git a/tests/tests/view/res/values-land/dimens.xml b/tests/tests/view/res/values-land/dimens.xml
new file mode 100644
index 0000000..17b5395
--- /dev/null
+++ b/tests/tests/view/res/values-land/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+ <dimen name="test_animator_target_y">30dp</dimen>
+ <!-- this value is equal to the value in changing_reset_state_anim. It is NOT referenced
+ in the XML on purpose-->
+ <dimen name="reset_state_value">100dp</dimen>
+ <!-- this value is equal to the value in changing_state_list_animator. It is NOT referenced in the XML on purpose-->
+ <dimen name="changing_state_list_anim_target_x_value">200dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/view/res/values/dimens.xml b/tests/tests/view/res/values/dimens.xml
new file mode 100644
index 0000000..16e5084
--- /dev/null
+++ b/tests/tests/view/res/values/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+ <dimen name="test_animator_target_x">10dp</dimen>
+ <dimen name="test_animator_target_y">20dp</dimen>
+ <!-- this value is equal to the value in changing_reset_state_anim. It is NOT referenced in the XML on purpose-->
+ <dimen name="reset_state_value">50dp</dimen>
+ <!-- this value is equal to the value in changing_state_list_animator. It is NOT referenced in the XML on purpose-->
+ <dimen name="changing_state_list_anim_target_x_value">100dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java b/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
new file mode 100644
index 0000000..eeda5a3
--- /dev/null
+++ b/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
@@ -0,0 +1,271 @@
+/*
+* Copyright (C) 2014 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.view.animation.cts;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.StateListAnimator;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.os.Debug;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.View;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import com.android.cts.view.R;
+
+public class AnimatorInflaterTest
+ extends ActivityInstrumentationTestCase2<AnimationTestCtsActivity> {
+
+ Set<Integer> identityHashes = new HashSet<Integer>();
+
+ public AnimatorInflaterTest() {
+ super("com.android.cts.view", AnimationTestCtsActivity.class);
+ }
+
+ private void assertUnique(Object object) {
+ assertUnique(object, "");
+ }
+
+ private void assertUnique(Object object, String msg) {
+ final int code = System.identityHashCode(object);
+ assertTrue("object should be unique " + msg + ", obj:" + object, identityHashes.add(code));
+
+ }
+
+ public void testLoadAnimatorWithDifferentInterpolators() throws Throwable {
+ Animator anim1 = AnimatorInflater
+ .loadAnimator(getActivity(), R.anim.changing_test_animator);
+ rotate();
+ Animator anim2 = AnimatorInflater
+ .loadAnimator(getActivity(), R.anim.changing_test_animator);
+ assertNotSame(anim1, anim2);
+ assertNotSame("interpolater is orientation dependent, should change",
+ anim1.getInterpolator(), anim2.getInterpolator());
+ }
+
+ /**
+ * Tests animators with dimension references.
+ */
+ public void testLoadAnimator() throws Throwable {
+ // to identify objects
+ Animator anim1 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ Animator anim2 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ assertNotSame("a different animation should be returned", anim1, anim2);
+ assertSame("interpolator should be shallow cloned", anim1.getInterpolator(),
+ anim2.getInterpolator());
+ for (int i = 0; i < 2; i++) {
+ float targetX = getActivity().getResources()
+ .getDimension(R.dimen.test_animator_target_x);
+ // y value changes in landscape orientation
+ float targetY = getActivity().getResources()
+ .getDimension(R.dimen.test_animator_target_y);
+ for (Animator anim : new Animator[]{anim1, anim2}) {
+ assertTrue(anim instanceof AnimatorSet);
+ assertUnique(anim);
+ AnimatorSet set = (AnimatorSet) anim;
+ assertEquals("should have 3 sub animations", 3, set.getChildAnimations().size());
+ for (Animator subAnim : set.getChildAnimations()) {
+ assertUnique(subAnim);
+ assertTrue(subAnim instanceof ObjectAnimator);
+ }
+ final ObjectAnimator child1 = (ObjectAnimator) set.getChildAnimations().get(0);
+ final ObjectAnimator child2 = (ObjectAnimator) set.getChildAnimations().get(1);
+ final DummyObject dummyObject = new DummyObject();
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ for (ObjectAnimator animator : new ObjectAnimator[]{child1, child2}) {
+ animator.setTarget(dummyObject);
+ animator.setupStartValues();
+ animator.start();
+ animator.end();
+ }
+ }
+ });
+ assertEquals(targetX, dummyObject.x);
+ assertEquals(targetY, dummyObject.y);
+ }
+ if (i == 0) {
+ rotate();
+ }
+ anim1 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ anim2 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+
+ }
+ }
+
+ private void rotate() throws Throwable {
+ final Activity activity = getActivity();
+ int orientation = activity.getResources().getConfiguration().orientation;
+ final int nextOrientation = orientation == Configuration.ORIENTATION_LANDSCAPE
+ ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+ : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+ Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(
+ activity.getClass().getName(), null, false);
+ getInstrumentation().addMonitor(monitor);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ activity.setRequestedOrientation(nextOrientation);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ Activity newAct = getInstrumentation()
+ .waitForMonitorWithTimeout(monitor, TimeUnit.SECONDS.toMillis(2));
+ if (newAct != null) {
+ setActivity(newAct);
+ }
+ }
+
+ /**
+ * Simple state list animator test that checks for cloning
+ */
+ public void testLoadStateListAnimator() {
+ StateListAnimator sla1 = AnimatorInflater.loadStateListAnimator(getActivity(),
+ R.anim.test_state_list_animator);
+ StateListAnimator sla2 = AnimatorInflater.loadStateListAnimator(getActivity(),
+ R.anim.test_state_list_animator);
+ assertUnique(sla1);
+ assertUnique(sla2);
+ }
+
+ /**
+ * Tests a state list animator which has an @anim reference that has different xmls per
+ * orientation
+ */
+ public void testLoadStateListAnimatorWithChangingResetState() throws Throwable {
+ loadStateListAnimatorWithChangingResetStateTest();
+ rotate();
+ loadStateListAnimatorWithChangingResetStateTest();
+ }
+
+ private void loadStateListAnimatorWithChangingResetStateTest() throws Throwable {
+ final StateListAnimator sla = AnimatorInflater.loadStateListAnimator(getActivity(),
+ R.anim.test_state_list_animator_2);
+ final View testView = getTestView();
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ testView.setStateListAnimator(sla);
+ testView.jumpDrawablesToCurrentState();
+ }
+ });
+ float resetValue = getActivity().getResources().getDimension(R.dimen.reset_state_value);
+ getInstrumentation().waitForIdleSync();
+ assertEquals(resetValue, testView.getX());
+ assertEquals(resetValue, testView.getY());
+ assertEquals(resetValue, testView.getZ());
+ }
+
+ /**
+ * Tests a state list animator which has different xml descriptions per orientation.
+ */
+ public void testLoadChangingStateListAnimator() throws Throwable {
+ loadChangingStateListAnimatorTest();
+ rotate();
+ loadChangingStateListAnimatorTest();
+ }
+
+ private void loadChangingStateListAnimatorTest() throws Throwable {
+ final StateListAnimator sla = AnimatorInflater.loadStateListAnimator(getActivity(),
+ R.anim.changing_state_list_animator);
+ final View testView = getTestView();
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ testView.setStateListAnimator(sla);
+ testView.jumpDrawablesToCurrentState();
+ }
+ });
+ float targetValue = getActivity().getResources()
+ .getDimension(R.dimen.changing_state_list_anim_target_x_value);
+ getInstrumentation().waitForIdleSync();
+ assertEquals(targetValue, testView.getX());
+ }
+
+ /**
+ * Tests that makes sure that reloaded animator is not affected by previous changes
+ */
+ public void testReloadedAnimatorIsNotModified() throws Throwable {
+ final Animator anim1 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ final CountDownLatch mStarted = new CountDownLatch(1);
+ final AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ mStarted.countDown();
+ }
+ };
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ anim1.setTarget(getTestView());
+ anim1.addListener(listener);
+ anim1.start();
+ }
+ });
+ Animator anim2 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ assertTrue(anim1.isStarted());
+ assertFalse(anim2.isStarted());
+ assertFalse("anim2 should not include the listener",
+ anim2.getListeners() != null && anim2.getListeners().contains(listener));
+ assertTrue("animator should start", mStarted.await(10, TimeUnit.SECONDS));
+ assertFalse(anim2.isRunning());
+
+ }
+
+ public View getTestView() {
+ return getActivity().findViewById(R.id.anim_window);
+ }
+
+ class DummyObject {
+
+ float x;
+ float y;
+
+ public float getX() {
+ return x;
+ }
+
+ public void setX(float x) {
+ this.x = x;
+ }
+
+ public float getY() {
+ return y;
+ }
+
+ public void setY(float y) {
+ this.y = y;
+ }
+ }
+}
+
diff --git a/tests/tests/widget/src/android/widget/cts/VideoViewTest.java b/tests/tests/widget/src/android/widget/cts/VideoViewTest.java
index 6e514f8..d9af514 100644
--- a/tests/tests/widget/src/android/widget/cts/VideoViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/VideoViewTest.java
@@ -21,6 +21,7 @@
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
+import android.cts.util.MediaUtils;
import android.cts.util.PollingCheck;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
@@ -53,8 +54,6 @@
private static final int TEST_VIDEO_DURATION = 11047;
/** The full name of R.raw.testvideo. */
private static final String VIDEO_NAME = "testvideo.3gp";
- /** The MIME type. */
- private static final String MIME_TYPE = "video/3gpp";
/** delta for duration in case user uses different decoders on different
hardware that report a duration that's different by a few milliseconds */
private static final int DURATION_DELTA = 100;
@@ -101,26 +100,8 @@
}
}
- // TODO: Make a public method selectCodec() in common libraries (e.g. cts/libs/), to avoid
- // redundant function definitions in this and other media related test files.
- private static boolean hasCodec(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 true;
- }
- }
- }
- return false;
+ private boolean hasCodec() {
+ return MediaUtils.hasCodecsForResource(mActivity, R.raw.testvideo);
}
/**
@@ -204,8 +185,8 @@
public void testPlayVideo1() throws Throwable {
makeVideoView();
// Don't run the test if the codec isn't supported.
- if (!hasCodec(MIME_TYPE)) {
- Log.w(TAG, "Codec " + MIME_TYPE + " not supported. Return from testPlayVideo1.");
+ if (!hasCodec()) {
+ Log.i(TAG, "SKIPPING testPlayVideo1(): codec is not supported");
return;
}
@@ -266,8 +247,8 @@
public void testGetBufferPercentage() throws Throwable {
makeVideoView();
// Don't run the test if the codec isn't supported.
- if (!hasCodec(MIME_TYPE)) {
- Log.w(TAG, MIME_TYPE + " not supported. Return from testGetBufferPercentage.");
+ if (!hasCodec()) {
+ Log.i(TAG, "SKIPPING testGetBufferPercentage(): codec is not supported");
return;
}
@@ -309,8 +290,8 @@
public void testGetDuration() throws Throwable {
// Don't run the test if the codec isn't supported.
- if (!hasCodec(MIME_TYPE)) {
- Log.w(TAG, "Codec " + MIME_TYPE + " not supported. Return from testGetDuration.");
+ if (!hasCodec()) {
+ Log.i(TAG, "SKIPPING testGetDuration(): codec is not supported");
return;
}
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java
index a843fc6..fc774e9 100644
--- a/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java
+++ b/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java
@@ -16,7 +16,9 @@
package com.android.cts.javascanner;
import java.io.File;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
* Class that searches a source directory for native gTests and outputs a
@@ -31,12 +33,12 @@
}
public static void main(String[] args) throws Exception {
- File sourceDir = null;
+ List<File> sourceDirs = new ArrayList<File>();
File docletPath = null;
for (int i = 0; i < args.length; i++) {
if ("-s".equals(args[i])) {
- sourceDir = new File(getArg(args, ++i, "Missing value for source directory"));
+ sourceDirs.add(new File(getArg(args, ++i, "Missing value for source directory")));
} else if ("-d".equals(args[i])) {
docletPath = new File(getArg(args, ++i, "Missing value for docletPath"));
} else {
@@ -45,7 +47,7 @@
}
}
- if (sourceDir == null) {
+ if (sourceDirs.isEmpty()) {
System.err.println("Source directory is required");
usage(args);
}
@@ -55,7 +57,7 @@
usage(args);
}
- DocletRunner runner = new DocletRunner(sourceDir, docletPath);
+ DocletRunner runner = new DocletRunner(sourceDirs, docletPath);
System.exit(runner.runJavaDoc());
}
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
index 06951b9a..94761fb 100644
--- a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
+++ b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
@@ -25,11 +25,11 @@
class DocletRunner {
- private final File mSourceDir;
+ private final List<File> mSourceDirs;
private final File mDocletPath;
- DocletRunner(File sourceDir, File docletPath) {
- mSourceDir = sourceDir;
+ DocletRunner(List<File> sourceDirs, File docletPath) {
+ mSourceDirs = sourceDirs;
mDocletPath = docletPath;
}
@@ -41,10 +41,12 @@
args.add("-docletpath");
args.add(mDocletPath.toString());
args.add("-sourcepath");
- args.add(getSourcePath(mSourceDir));
+ args.add(getSourcePath(mSourceDirs));
args.add("-classpath");
args.add(getClassPath());
- args.addAll(getSourceFiles(mSourceDir));
+ for (File sourceDir : mSourceDirs) {
+ args.addAll(getSourceFiles(sourceDir));
+ }
// NOTE: We redirect the error stream to make sure the child process
@@ -67,7 +69,7 @@
return process.waitFor();
}
- private String getSourcePath(File sourceDir) {
+ private String getSourcePath(List<File> sourceDirs) {
List<String> sourcePath = new ArrayList<String>();
sourcePath.add("./frameworks/base/core/java");
sourcePath.add("./frameworks/base/test-runner/src");
@@ -77,7 +79,9 @@
sourcePath.add("./cts/tests/src");
sourcePath.add("./cts/libs/commonutil/src");
sourcePath.add("./cts/libs/deviceutil/src");
- sourcePath.add(sourceDir.toString());
+ for (File sourceDir : sourceDirs) {
+ sourcePath.add(sourceDir.toString());
+ }
return join(sourcePath, ":");
}
diff --git a/tools/selinux/SELinuxNeverallowTestFrame.py b/tools/selinux/SELinuxNeverallowTestFrame.py
new file mode 100644
index 0000000..932014a
--- /dev/null
+++ b/tools/selinux/SELinuxNeverallowTestFrame.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+
+src_header = """/*
+ * Copyright (C) 2014 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.cts.security;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.FileOutputStream;
+import java.lang.String;
+import java.net.URL;
+import java.util.Scanner;
+
+/**
+ * Neverallow Rules SELinux tests.
+ */
+public class SELinuxNeverallowRulesTest extends DeviceTestCase {
+ private File sepolicyAnalyze;
+ private File devicePolicyFile;
+
+ /**
+ * A reference to the device under test.
+ */
+ private ITestDevice mDevice;
+
+ private File copyResourceToTempFile(String resName) throws IOException {
+ InputStream is = this.getClass().getResourceAsStream(resName);
+ File tempFile = File.createTempFile("SELinuxHostTest", ".tmp");
+ FileOutputStream os = new FileOutputStream(tempFile);
+ int rByte = 0;
+ while ((rByte = is.read()) != -1) {
+ os.write(rByte);
+ }
+ os.flush();
+ os.close();
+ tempFile.deleteOnExit();
+ return tempFile;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mDevice = getDevice();
+
+ /* retrieve the sepolicy-analyze executable from jar */
+ sepolicyAnalyze = copyResourceToTempFile("/sepolicy-analyze");
+ sepolicyAnalyze.setExecutable(true);
+
+ /* obtain sepolicy file from running device */
+ devicePolicyFile = File.createTempFile("sepolicy", ".tmp");
+ devicePolicyFile.deleteOnExit();
+ mDevice.executeAdbCommand("pull", "/sys/fs/selinux/policy",
+ devicePolicyFile.getAbsolutePath());
+ }
+"""
+src_body = ""
+src_footer = """}
+"""
+
+src_method = """
+ public void testNeverallowRules() throws Exception {
+ String neverallowRule = "$NEVERALLOW_RULE_HERE$";
+
+ /* run sepolicy-analyze neverallow check on policy file using given neverallow rules */
+ ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
+ devicePolicyFile.getAbsolutePath(), "neverallow", "-n",
+ neverallowRule);
+ pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+ p.waitFor();
+ BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line;
+ StringBuilder errorString = new StringBuilder();
+ while ((line = result.readLine()) != null) {
+ errorString.append(line);
+ errorString.append("\\n");
+ }
+ assertTrue("The following errors were encountered when validating the SELinux"
+ + "neverallow rule:\\n" + neverallowRule + "\\n" + errorString,
+ errorString.length() == 0);
+ }
+"""
diff --git a/tools/selinux/SELinuxNeverallowTestGen.py b/tools/selinux/SELinuxNeverallowTestGen.py
new file mode 100755
index 0000000..9cb1e24
--- /dev/null
+++ b/tools/selinux/SELinuxNeverallowTestGen.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+
+import re
+import sys
+import SELinuxNeverallowTestFrame
+
+usage = "Usage: ./gen_SELinux_CTS_neverallows.py <input policy file> <output cts java source>"
+
+# extract_neverallow_rules - takes an intermediate policy file and pulls out the
+# neverallow rules by taking all of the non-commented text between the 'neverallow'
+# keyword and a terminating ';'
+# returns: a list of strings representing these rules
+def extract_neverallow_rules(policy_file):
+ with open(policy_file, 'r') as in_file:
+ policy_str = in_file.read()
+ # remove comments
+ no_comments = re.sub(r'#.+?$', r'', policy_str, flags = re.M)
+ # match neverallow rules
+ return re.findall(r'(^neverallow\s.+?;)', no_comments, flags = re.M |re.S);
+
+# neverallow_rule_to_test - takes a neverallow statement and transforms it into
+# the output necessary to form a cts unit test in a java source file.
+# returns: a string representing a generic test method based on this rule.
+def neverallow_rule_to_test(neverallow_rule, test_num):
+ squashed_neverallow = neverallow_rule.replace("\n", " ")
+ method = SELinuxNeverallowTestFrame.src_method
+ method = method.replace("testNeverallowRules()",
+ "testNeverallowRules" + str(test_num) + "()")
+ return method.replace("$NEVERALLOW_RULE_HERE$", squashed_neverallow)
+
+if __name__ == "__main__":
+ # check usage
+ if len(sys.argv) != 3:
+ print usage
+ exit()
+ input_file = sys.argv[1]
+ output_file = sys.argv[2]
+
+ src_header = SELinuxNeverallowTestFrame.src_header
+ src_body = SELinuxNeverallowTestFrame.src_body
+ src_footer = SELinuxNeverallowTestFrame.src_footer
+
+ # grab the neverallow rules from the policy file and transform into tests
+ neverallow_rules = extract_neverallow_rules(input_file)
+ i = 0
+ for rule in neverallow_rules:
+ src_body += neverallow_rule_to_test(rule, i)
+ i += 1
+
+ with open(output_file, 'w') as out_file:
+ out_file.write(src_header)
+ out_file.write(src_body)
+ out_file.write(src_footer)
diff --git a/tools/selinux/src/SELinux_CTS.py b/tools/selinux/src/SELinux_CTS.py
deleted file mode 100644
index ec12be0e..0000000
--- a/tools/selinux/src/SELinux_CTS.py
+++ /dev/null
@@ -1,542 +0,0 @@
-import pdb
-import re
-from xml.etree.ElementTree import Element, SubElement, tostring
-
-#define equivalents
-TYPE = 0
-ATTRIBUTE = 1
-TYPEATTRIBUTE = 2
-CLASS = 3
-COMMON = 4
-ALLOW_RULE = 5
-NEVERALLOW_RULE = 6
-OTHER = 7
-
-#define helper methods
-# advance_past_whitespace(): helper function to skip whitespace at current
-# position in file.
-# returns: the non-whitespace character at the file's new position
-#TODO: should I deal with comments here as well?
-def advance_past_whitespace(file_obj):
- c = file_obj.read(1)
- while c.isspace():
- c = file_obj.read(1)
- file_obj.seek(-1, 1)
- return c
-
-# advance_until_whitespace(): helper function to grab the string represented
-# by the current position in file until next whitespace.
-# returns: string until next whitespace. overlooks comments.
-def advance_until_whitespace(file_obj):
- ret_string = ""
- c = file_obj.read(1)
- #TODO: make a better way to deal with ':' and ';'
- while not (c.isspace() or c == ':' or c == '' or c == ';'):
- #don't count comments
- if c == '#':
- file_obj.readline()
- return ret_string
- else:
- ret_string+=c
- c = file_obj.read(1)
- if not c == ':':
- file_obj.seek(-1, 1)
- return ret_string
-
-# expand_avc_rule - takes a processed avc rule and converts it into a list of
-# 4-tuples for use in an access check of form:
- # (source_type, target_type, class, permission)
-def expand_avc_rule(policy, avc_rule):
- ret_list = [ ]
-
- #expand source_types
- source_types = avc_rule['source_types']['set']
- source_types = policy.expand_types(source_types)
- if(avc_rule['source_types']['flags']['complement']):
- #TODO: deal with negated 'self', not present in current policy.conf, though (I think)
- source_types = policy.types - source_types #complement these types
- if len(source_types) == 0:
- print "ERROR: source_types empty after expansion"
- print "Before: "
- print avc_rule['source_types']['set']
- return
-
- #expand target_types
- target_types = avc_rule['target_types']['set']
- target_types = policy.expand_types(target_types)
- if(avc_rule['target_types']['flags']['complement']):
- #TODO: deal with negated 'self', not present in current policy.conf, though (I think)
- target_types = policy.types - target_types #complement these types
- if len(target_types) == 0:
- print "ERROR: target_types empty after expansion"
- print "Before: "
- print avc_rule['target_types']['set']
- return
-
- # get classes
- rule_classes = avc_rule['classes']['set']
- if '' in rule_classes:
- print "FOUND EMPTY STRING IN CLASSES"
- print "Total sets:"
- print avc_rule['source_types']['set']
- print avc_rule['target_types']['set']
- print rule_classes
- print avc_rule['permissions']['set']
-
- if len(rule_classes) == 0:
- print "ERROR: empy set of object classes in avc rule"
- return
-
- # get permissions
- permissions = avc_rule['permissions']['set']
- if len(permissions) == 0:
- print "ERROR: empy set of permissions in avc rule\n"
- return
-
- #create the list with collosal nesting, n^4 baby!
- for s in source_types:
- for t in target_types:
- for c in rule_classes:
- if c == '':
- continue
- #expand permissions on a per-class basis
- exp_permissions = policy.expand_permissions(c, permissions)
- if(avc_rule['permissions']['flags']['complement']):
- exp_permissions = policy.classes[c] - exp_permissions
- if len(exp_permissions) == 0:
- print "ERROR: permissions empty after expansion\n"
- print "Before: "
- print avc_rule['permissions']['set']
- return
- for p in exp_permissions:
- source = s
- if t == 'self':
- target = s
- else:
- target = t
- obj_class = c
- permission = p
- ret_list.append((source, target, obj_class, permission))
- return ret_list
-
-# expand_avc_rule - takes a processed avc rule and converts it into an xml
-# representation with the information needed in a checkSELinuxAccess() call.
-# (source_type, target_type, class, permission)
-def expand_avc_rule_to_xml(policy, avc_rule, rule_name, rule_type):
- rule_xml = Element('avc_rule')
- rule_xml.set('name', rule_name)
- rule_xml.set('type', rule_type)
-
- #expand source_types
- source_types = avc_rule['source_types']['set']
- source_types = policy.expand_types(source_types)
- if(avc_rule['source_types']['flags']['complement']):
- #TODO: deal with negated 'self', not present in current policy.conf, though (I think)
- source_types = policy.types - source_types #complement these types
- if len(source_types) == 0:
- print "ERROR: source_types empty after expansion"
- print "Before: "
- print avc_rule['source_types']['set']
- return
- for s in source_types:
- elem = SubElement(rule_xml, 'type')
- elem.set('type', 'source')
- elem.text = s
-
- #expand target_types
- target_types = avc_rule['target_types']['set']
- target_types = policy.expand_types(target_types)
- if(avc_rule['target_types']['flags']['complement']):
- #TODO: deal with negated 'self', not present in current policy.conf, though (I think)
- target_types = policy.types - target_types #complement these types
- if len(target_types) == 0:
- print "ERROR: target_types empty after expansion"
- print "Before: "
- print avc_rule['target_types']['set']
- return
- for t in target_types:
- elem = SubElement(rule_xml, 'type')
- elem.set('type', 'target')
- elem.text = t
-
- # get classes
- rule_classes = avc_rule['classes']['set']
-
- if len(rule_classes) == 0:
- print "ERROR: empy set of object classes in avc rule"
- return
-
- # get permissions
- permissions = avc_rule['permissions']['set']
- if len(permissions) == 0:
- print "ERROR: empy set of permissions in avc rule\n"
- return
-
- # permissions are class-dependent, so bundled together
- for c in rule_classes:
- if c == '':
- print "AH!!! empty class found!\n"
- continue
- c_elem = SubElement(rule_xml, 'obj_class')
- c_elem.set('name', c)
- #expand permissions on a per-class basis
- exp_permissions = policy.expand_permissions(c, permissions)
- if(avc_rule['permissions']['flags']['complement']):
- exp_permissions = policy.classes[c] - exp_permissions
- if len(exp_permissions) == 0:
- print "ERROR: permissions empty after expansion\n"
- print "Before: "
- print avc_rule['permissions']['set']
- return
-
- for p in exp_permissions:
- p_elem = SubElement(c_elem, 'permission')
- p_elem.text = p
-
- return rule_xml
-
-# expand_brackets - helper function which reads a file into a string until '{ }'s
-# are balanced. Brackets are removed from the string. This function is based
-# on the understanding that nested brackets in our policy.conf file occur only due
-# to macro expansion, and we just need to know how much is included in a given
-# policy sub-component.
-def expand_brackets(file_obj):
- ret_string = ""
- c = file_obj.read(1)
- if not c == '{':
- print "Invalid bracket expression: " + c + "\n"
- file_obj.seek(-1, 1)
- return ""
- else:
- bracket_count = 1
- while bracket_count > 0:
- c = file_obj.read(1)
- if c == '{':
- bracket_count+=1
- elif c == '}':
- bracket_count-=1
- elif c == '#':
- #get rid of comment and replace with whitespace
- file_obj.readline()
- ret_string+=' '
- else:
- ret_string+=c
- return ret_string
-
-# get_avc_rule_component - grabs the next component from an avc rule. Basically,
-# just reads the next word or bracketed set of words.
-# returns - a set of the word, or words with metadata
-def get_avc_rule_component(file_obj):
- ret_dict = { 'flags': {}, 'set': set() }
- c = advance_past_whitespace(file_obj)
- if c == '~':
- ret_dict['flags']['complement'] = True
- file_obj.read(1) #move to next char
- c = advance_past_whitespace(file_obj)
- else:
- ret_dict['flags']['complement'] = False
- if not c == '{':
- #TODO: change operations on file to operations on string?
- single_type = advance_until_whitespace(file_obj)
- ret_dict['set'].add(single_type)
- else:
- mult_types = expand_brackets(file_obj)
- mult_types = mult_types.split()
- for t in mult_types:
- ret_dict['set'].add(t)
- return ret_dict
-
-def get_line_type(line):
- if re.search(r'^type\s', line):
- return TYPE
- if re.search(r'^attribute\s', line):
- return ATTRIBUTE
- if re.search(r'^typeattribute\s', line):
- return TYPEATTRIBUTE
- if re.search(r'^class\s', line):
- return CLASS
- if re.search(r'^common\s', line):
- return COMMON
- if re.search(r'^allow\s', line):
- return ALLOW_RULE
- if re.search(r'^neverallow\s', line):
- return NEVERALLOW_RULE
- else:
- return OTHER
-
-def is_multi_line(line_type):
- if line_type == CLASS:
- return True
- elif line_type == COMMON:
- return True
- elif line_type == ALLOW_RULE:
- return True
- elif line_type == NEVERALLOW_RULE:
- return True
- else:
- return False
-
-
-#should only be called with file pointing to the 'i' in 'inherits' segment
-def process_inherits_segment(file_obj):
- inherit_keyword = file_obj.read(8)
- if not inherit_keyword == 'inherits':
- #TODO: handle error, invalid class statement
- print "ERROR: invalid inherits statement"
- return
- else:
- advance_past_whitespace(file_obj)
- ret_inherited_common = advance_until_whitespace(file_obj)
- return ret_inherited_common
-
-class SELinuxPolicy:
-
- def __init__(self):
- self.types = set()
- self.attributes = { }
- self.classes = { }
- self.common_classes = { }
- self.allow_rules = [ ]
- self.neverallow_rules = [ ]
-
- # create policy directly from policy file
- #@classmethod
- def from_file_name(self, policy_file_name):
- self.types = set()
- self.attributes = { }
- self.classes = { }
- self.common_classes = { }
- self.allow_rules = [ ]
- self.neverallow_rules = [ ]
- with open(policy_file_name, 'r') as policy_file:
- line = policy_file.readline()
- while line:
- line_type = get_line_type(line)
- if is_multi_line(line_type):
- self.parse_multi_line(line, line_type, policy_file)
- else:
- self.parse_single_line(line, line_type)
- line = policy_file.readline()
-
- # expand_permissions - generates the actual permission set based on the listed
- # permissions with wildcards and the given class on which they're based.
- def expand_permissions(self, obj_class, permission_set):
- ret_set = set()
- neg_set = set()
- for p in permission_set:
- if p[0] == '-':
- real_p = p[1:]
- if real_p in self.classes[obj_class]:
- neg_set.add(real_p)
- else:
- print "ERROR: invalid permission in avc rule " + real_t + "\n"
- return
- else:
- if p in self.classes[obj_class]:
- ret_set.add(p)
- elif p == '*': #pretty sure this can't be negated? eg -*
- ret_set |= self.classes[obj_class] #All of the permissions
- else:
- print "ERROR: invalid permission in avc rule " + p + "\n"
- return
- return ret_set - neg_set
-
- # expand_types - generates the actual type set based on the listed types,
- # attributes, wildcards and negation. self is left as-is, and is processed
- # specially when generating checkAccess() 4-tuples
- def expand_types(self, type_set):
- ret_set = set()
- neg_set = set()
- for t in type_set:
- if t[0] == '-':
- real_t = t[1:]
- if real_t in self.attributes:
- neg_set |= self.attributes[real_t]
- elif real_t in self.types:
- neg_set.add(real_t)
- elif real_t == 'self':
- ret_set |= real_t
- else:
- print "ERROR: invalid type in avc rule " + real_t + "\nTYPE SET:"
- print type_set
- return
- else:
- if t in self.attributes:
- ret_set |= self.attributes[t]
- elif t in self.types:
- ret_set.add(t)
- elif t == 'self':
- ret_set.add(t)
- elif t == '*': #pretty sure this can't be negated?
- ret_set |= self.types #All of the types
- else:
- print "ERROR: invalid type in avc rule " + t + "\nTYPE SET"
- print type_set
- return
- return ret_set - neg_set
-
- def parse_multi_line(self, line, line_type, file_obj):
- if line_type == CLASS:
- self.process_class_line(line, file_obj)
- elif line_type == COMMON:
- self.process_common_line(line, file_obj)
- elif line_type == ALLOW_RULE:
- self.process_avc_rule_line(line, file_obj)
- elif line_type == NEVERALLOW_RULE:
- self.process_avc_rule_line(line, file_obj)
- else:
- print "Error: This is not a multi-line input"
-
- def parse_single_line(self, line, line_type):
- if line_type == TYPE:
- self.process_type_line(line)
- elif line_type == ATTRIBUTE:
- self.process_attribute_line(line)
- elif line_type == TYPEATTRIBUTE:
- self.process_typeattribute_line(line)
- return
-
- def process_attribute_line(self, line):
- match = re.search(r'^attribute\s+(.+);', line)
- if match:
- declared_attribute = match.group(1)
- self.attributes[declared_attribute] = set()
- else:
- #TODO: handle error? (no state changed)
- return
-
- def process_class_line(self, line, file_obj):
- match = re.search(r'^class\s([^\s]+)\s(.*$)', line)
- if match:
- declared_class = match.group(1)
- #first class declaration has no perms
- if not declared_class in self.classes:
- self.classes[declared_class] = set()
- return
- else:
- #need to parse file from after class name until end of '{ }'s
- file_obj.seek(-(len(match.group(2)) + 1), 1)
- c = advance_past_whitespace(file_obj)
- if not (c == 'i' or c == '{'):
- print "ERROR: invalid class statement"
- return
- elif c == 'i':
- #add inherited permissions
- inherited = process_inherits_segment(file_obj)
- self.classes[declared_class] |= self.common_classes[inherited]
- c = advance_past_whitespace(file_obj)
- if c == '{':
- permissions = expand_brackets(file_obj)
- permissions = re.sub(r'#[^\n]*\n','\n' , permissions) #get rid of all comments
- permissions = permissions.split()
- for p in permissions:
- self.classes[declared_class].add(p)
-
- def process_common_line(self, line, file_obj):
- match = re.search(r'^common\s([^\s]+)(.*$)', line)
- if match:
- declared_common_class = match.group(1)
- #TODO: common classes should only be declared once...
- if not declared_common_class in self.common_classes:
- self.common_classes[declared_common_class] = set()
- #need to parse file from after common_class name until end of '{ }'s
- file_obj.seek(-(len(match.group(2)) + 1), 1)
- c = advance_past_whitespace(file_obj)
- if not c == '{':
- print "ERROR: invalid common statement"
- return
- permissions = expand_brackets(file_obj)
- permissions = permissions.split()
- for p in permissions:
- self.common_classes[declared_common_class].add(p)
- return
-
- def process_avc_rule_line(self, line, file_obj):
- match = re.search(r'^(never)?allow\s(.*$)', line)
- if match:
- if(match.group(1)):
- rule_type = 'neverallow'
- else:
- rule_type = 'allow'
- #need to parse file from after class name until end of '{ }'s
- file_obj.seek(-(len(match.group(2)) + 1), 1)
-
- #grab source type(s)
- source_types = get_avc_rule_component(file_obj)
- if len(source_types['set']) == 0:
- print "ERROR: no source types for avc rule at line: " + line
- return
-
- #grab target type(s)
- target_types = get_avc_rule_component(file_obj)
- if len(target_types['set']) == 0:
- print "ERROR: no target types for avc rule at line: " + line
- return
-
- #skip ':' potentially already handled by advance_until_whitespace
- c = advance_past_whitespace(file_obj)
- if c == ':':
- file_obj.read(1)
-
- #grab class(es)
- classes = get_avc_rule_component(file_obj)
- if len(classes['set']) == 0:
- print "ERROR: no classes for avc rule at line: " + line
- return
-
- #grab permission(s)
- permissions = get_avc_rule_component(file_obj)
- if len(permissions['set']) == 0:
- print "ERROR: no permissions for avc rule at line: " + line
- return
- rule_dict = {
- 'source_types': source_types,
- 'target_types': target_types,
- 'classes': classes,
- 'permissions': permissions }
-
- if rule_type == 'allow':
- self.allow_rules.append(rule_dict)
- elif rule_type == 'neverallow':
- self.neverallow_rules.append(rule_dict)
-
- def process_type_line(self, line):
- #TODO: add support for aliases (not yet in current policy.conf)
- match = re.search(r'^type\s([^,]+),?(.*);', line)
- if match:
- declared_type = match.group(1)
- self.types.add(declared_type)
- if match.group(2):
- declared_attributes = match.group(2)
- declared_attributes = declared_attributes.replace(" ", "") #remove whitespace
- declared_attributes = declared_attributes.split(',') #separate based on delimiter
- for a in declared_attributes:
- if not a in self.attributes:
- #TODO: hanlde error? attribute should already exist
- self.attributes[a] = set()
- self.attributes[a].add(declared_type)
- else:
- #TODO: handle error? (no state changed)
- return
-
- def process_typeattribute_line(self, line):
- match = re.search(r'^typeattribute\s([^\s]+)\s(.*);', line)
- if match:
- declared_type = match.group(1)
- if not declared_type in self.types:
- #TODO: handle error? type should already exist
- self.types.add(declared_type)
- if match.group(2):
- declared_attributes = match.group(2)
- declared_attributes = declared_attributes.replace(" ", "") #remove whitespace
- declared_attributes = declared_attributes.split(',') #separate based on delimiter
- for a in declared_attributes:
- if not a in self.attributes:
- #TODO: hanlde error? attribute should already exist
- self.attributes[a] = set()
- self.attributes[a].add(declared_type)
- else:
- return
- else:
- #TODO: handle error? (no state changed)
- return
diff --git a/tools/selinux/src/example_input_policy.conf b/tools/selinux/src/example_input_policy.conf
deleted file mode 100644
index aeef5f8..0000000
--- a/tools/selinux/src/example_input_policy.conf
+++ /dev/null
@@ -1,9850 +0,0 @@
-#line 1 "external/sepolicy/security_classes"
-# FLASK
-
-#
-# Define the security object classes
-#
-
-# Classes marked as userspace are classes
-# for userspace object managers
-
-class security
-class process
-class system
-class capability
-
-# file-related classes
-class filesystem
-class file
-class dir
-class fd
-class lnk_file
-class chr_file
-class blk_file
-class sock_file
-class fifo_file
-
-# network-related classes
-class socket
-class tcp_socket
-class udp_socket
-class rawip_socket
-class node
-class netif
-class netlink_socket
-class packet_socket
-class key_socket
-class unix_stream_socket
-class unix_dgram_socket
-
-# sysv-ipc-related classes
-class sem
-class msg
-class msgq
-class shm
-class ipc
-
-#
-# userspace object manager classes
-#
-
-# passwd/chfn/chsh
-class passwd # userspace
-
-# SE-X Windows stuff (more classes below)
-class x_drawable # userspace
-class x_screen # userspace
-class x_gc # userspace
-class x_font # userspace
-class x_colormap # userspace
-class x_property # userspace
-class x_selection # userspace
-class x_cursor # userspace
-class x_client # userspace
-class x_device # userspace
-class x_server # userspace
-class x_extension # userspace
-
-# extended netlink sockets
-class netlink_route_socket
-class netlink_firewall_socket
-class netlink_tcpdiag_socket
-class netlink_nflog_socket
-class netlink_xfrm_socket
-class netlink_selinux_socket
-class netlink_audit_socket
-class netlink_ip6fw_socket
-class netlink_dnrt_socket
-
-class dbus # userspace
-class nscd # userspace
-
-# IPSec association
-class association
-
-# Updated Netlink class for KOBJECT_UEVENT family.
-class netlink_kobject_uevent_socket
-
-class appletalk_socket
-
-class packet
-
-# Kernel access key retention
-class key
-
-class context # userspace
-
-class dccp_socket
-
-class memprotect
-
-class db_database # userspace
-class db_table # userspace
-class db_procedure # userspace
-class db_column # userspace
-class db_tuple # userspace
-class db_blob # userspace
-
-# network peer labels
-class peer
-
-# Capabilities >= 32
-class capability2
-
-# More SE-X Windows stuff
-class x_resource # userspace
-class x_event # userspace
-class x_synthetic_event # userspace
-class x_application_data # userspace
-
-# kernel services that need to override task security, e.g. cachefiles
-class kernel_service
-
-class tun_socket
-
-# Still More SE-X Windows stuff
-class x_pointer # userspace
-class x_keyboard # userspace
-
-# More Database stuff
-class db_schema # userspace
-class db_view # userspace
-class db_sequence # userspace
-class db_language # userspace
-
-class binder
-class zygote
-
-# Property service
-class property_service # userspace
-
-# FLASK
-#line 1 "external/sepolicy/initial_sids"
-# FLASK
-
-#
-# Define initial security identifiers
-#
-
-sid kernel
-sid security
-sid unlabeled
-sid fs
-sid file
-sid file_labels
-sid init
-sid any_socket
-sid port
-sid netif
-sid netmsg
-sid node
-sid igmp_packet
-sid icmp_socket
-sid tcp_socket
-sid sysctl_modprobe
-sid sysctl
-sid sysctl_fs
-sid sysctl_kernel
-sid sysctl_net
-sid sysctl_net_unix
-sid sysctl_vm
-sid sysctl_dev
-sid kmod
-sid policy
-sid scmp_packet
-sid devnull
-
-# FLASK
-#line 1 "external/sepolicy/access_vectors"
-#
-# Define common prefixes for access vectors
-#
-# common common_name { permission_name ... }
-
-
-#
-# Define a common prefix for file access vectors.
-#
-
-common file
-{
- ioctl
- read
- write
- create
- getattr
- setattr
- lock
- relabelfrom
- relabelto
- append
- unlink
- link
- rename
- execute
- swapon
- quotaon
- mounton
-}
-
-
-#
-# Define a common prefix for socket access vectors.
-#
-
-common socket
-{
-# inherited from file
- ioctl
- read
- write
- create
- getattr
- setattr
- lock
- relabelfrom
- relabelto
- append
-# socket-specific
- bind
- connect
- listen
- accept
- getopt
- setopt
- shutdown
- recvfrom
- sendto
- recv_msg
- send_msg
- name_bind
-}
-
-#
-# Define a common prefix for ipc access vectors.
-#
-
-common ipc
-{
- create
- destroy
- getattr
- setattr
- read
- write
- associate
- unix_read
- unix_write
-}
-
-#
-# Define a common prefix for userspace database object access vectors.
-#
-
-common database
-{
- create
- drop
- getattr
- setattr
- relabelfrom
- relabelto
-}
-
-#
-# Define a common prefix for pointer and keyboard access vectors.
-#
-
-common x_device
-{
- getattr
- setattr
- use
- read
- write
- getfocus
- setfocus
- bell
- force_cursor
- freeze
- grab
- manage
- list_property
- get_property
- set_property
- add
- remove
- create
- destroy
-}
-
-#
-# Define the access vectors.
-#
-# class class_name [ inherits common_name ] { permission_name ... }
-
-
-#
-# Define the access vector interpretation for file-related objects.
-#
-
-class filesystem
-{
- mount
- remount
- unmount
- getattr
- relabelfrom
- relabelto
- transition
- associate
- quotamod
- quotaget
-}
-
-class dir
-inherits file
-{
- add_name
- remove_name
- reparent
- search
- rmdir
- open
- audit_access
- execmod
-}
-
-class file
-inherits file
-{
- execute_no_trans
- entrypoint
- execmod
- open
- audit_access
-}
-
-class lnk_file
-inherits file
-{
- open
- audit_access
- execmod
-}
-
-class chr_file
-inherits file
-{
- execute_no_trans
- entrypoint
- execmod
- open
- audit_access
-}
-
-class blk_file
-inherits file
-{
- open
- audit_access
- execmod
-}
-
-class sock_file
-inherits file
-{
- open
- audit_access
- execmod
-}
-
-class fifo_file
-inherits file
-{
- open
- audit_access
- execmod
-}
-
-class fd
-{
- use
-}
-
-
-#
-# Define the access vector interpretation for network-related objects.
-#
-
-class socket
-inherits socket
-
-class tcp_socket
-inherits socket
-{
- connectto
- newconn
- acceptfrom
- node_bind
- name_connect
-}
-
-class udp_socket
-inherits socket
-{
- node_bind
-}
-
-class rawip_socket
-inherits socket
-{
- node_bind
-}
-
-class node
-{
- tcp_recv
- tcp_send
- udp_recv
- udp_send
- rawip_recv
- rawip_send
- enforce_dest
- dccp_recv
- dccp_send
- recvfrom
- sendto
-}
-
-class netif
-{
- tcp_recv
- tcp_send
- udp_recv
- udp_send
- rawip_recv
- rawip_send
- dccp_recv
- dccp_send
- ingress
- egress
-}
-
-class netlink_socket
-inherits socket
-
-class packet_socket
-inherits socket
-
-class key_socket
-inherits socket
-
-class unix_stream_socket
-inherits socket
-{
- connectto
- newconn
- acceptfrom
-}
-
-class unix_dgram_socket
-inherits socket
-
-#
-# Define the access vector interpretation for process-related objects
-#
-
-class process
-{
- fork
- transition
- sigchld # commonly granted from child to parent
- sigkill # cannot be caught or ignored
- sigstop # cannot be caught or ignored
- signull # for kill(pid, 0)
- signal # all other signals
- ptrace
- getsched
- setsched
- getsession
- getpgid
- setpgid
- getcap
- setcap
- share
- getattr
- setexec
- setfscreate
- noatsecure
- siginh
- setrlimit
- rlimitinh
- dyntransition
- setcurrent
- execmem
- execstack
- execheap
- setkeycreate
- setsockcreate
-}
-
-
-#
-# Define the access vector interpretation for ipc-related objects
-#
-
-class ipc
-inherits ipc
-
-class sem
-inherits ipc
-
-class msgq
-inherits ipc
-{
- enqueue
-}
-
-class msg
-{
- send
- receive
-}
-
-class shm
-inherits ipc
-{
- lock
-}
-
-
-#
-# Define the access vector interpretation for the security server.
-#
-
-class security
-{
- compute_av
- compute_create
- compute_member
- check_context
- load_policy
- compute_relabel
- compute_user
- setenforce # was avc_toggle in system class
- setbool
- setsecparam
- setcheckreqprot
- read_policy
-}
-
-
-#
-# Define the access vector interpretation for system operations.
-#
-
-class system
-{
- ipc_info
- syslog_read
- syslog_mod
- syslog_console
- module_request
-}
-
-#
-# Define the access vector interpretation for controling capabilies
-#
-
-class capability
-{
- # The capabilities are defined in include/linux/capability.h
- # Capabilities >= 32 are defined in the capability2 class.
- # Care should be taken to ensure that these are consistent with
- # those definitions. (Order matters)
-
- chown
- dac_override
- dac_read_search
- fowner
- fsetid
- kill
- setgid
- setuid
- setpcap
- linux_immutable
- net_bind_service
- net_broadcast
- net_admin
- net_raw
- ipc_lock
- ipc_owner
- sys_module
- sys_rawio
- sys_chroot
- sys_ptrace
- sys_pacct
- sys_admin
- sys_boot
- sys_nice
- sys_resource
- sys_time
- sys_tty_config
- mknod
- lease
- audit_write
- audit_control
- setfcap
-}
-
-class capability2
-{
- mac_override # unused by SELinux
- mac_admin # unused by SELinux
- syslog
- wake_alarm
- block_suspend
-}
-
-#
-# Define the access vector interpretation for controlling
-# changes to passwd information.
-#
-class passwd
-{
- passwd # change another user passwd
- chfn # change another user finger info
- chsh # change another user shell
- rootok # pam_rootok check (skip auth)
- crontab # crontab on another user
-}
-
-#
-# SE-X Windows stuff
-#
-class x_drawable
-{
- create
- destroy
- read
- write
- blend
- getattr
- setattr
- list_child
- add_child
- remove_child
- list_property
- get_property
- set_property
- manage
- override
- show
- hide
- send
- receive
-}
-
-class x_screen
-{
- getattr
- setattr
- hide_cursor
- show_cursor
- saver_getattr
- saver_setattr
- saver_hide
- saver_show
-}
-
-class x_gc
-{
- create
- destroy
- getattr
- setattr
- use
-}
-
-class x_font
-{
- create
- destroy
- getattr
- add_glyph
- remove_glyph
- use
-}
-
-class x_colormap
-{
- create
- destroy
- read
- write
- getattr
- add_color
- remove_color
- install
- uninstall
- use
-}
-
-class x_property
-{
- create
- destroy
- read
- write
- append
- getattr
- setattr
-}
-
-class x_selection
-{
- read
- write
- getattr
- setattr
-}
-
-class x_cursor
-{
- create
- destroy
- read
- write
- getattr
- setattr
- use
-}
-
-class x_client
-{
- destroy
- getattr
- setattr
- manage
-}
-
-class x_device
-inherits x_device
-
-class x_server
-{
- getattr
- setattr
- record
- debug
- grab
- manage
-}
-
-class x_extension
-{
- query
- use
-}
-
-class x_resource
-{
- read
- write
-}
-
-class x_event
-{
- send
- receive
-}
-
-class x_synthetic_event
-{
- send
- receive
-}
-
-#
-# Extended Netlink classes
-#
-class netlink_route_socket
-inherits socket
-{
- nlmsg_read
- nlmsg_write
-}
-
-class netlink_firewall_socket
-inherits socket
-{
- nlmsg_read
- nlmsg_write
-}
-
-class netlink_tcpdiag_socket
-inherits socket
-{
- nlmsg_read
- nlmsg_write
-}
-
-class netlink_nflog_socket
-inherits socket
-
-class netlink_xfrm_socket
-inherits socket
-{
- nlmsg_read
- nlmsg_write
-}
-
-class netlink_selinux_socket
-inherits socket
-
-class netlink_audit_socket
-inherits socket
-{
- nlmsg_read
- nlmsg_write
- nlmsg_relay
- nlmsg_readpriv
- nlmsg_tty_audit
-}
-
-class netlink_ip6fw_socket
-inherits socket
-{
- nlmsg_read
- nlmsg_write
-}
-
-class netlink_dnrt_socket
-inherits socket
-
-# Define the access vector interpretation for controlling
-# access and communication through the D-BUS messaging
-# system.
-#
-class dbus
-{
- acquire_svc
- send_msg
-}
-
-# Define the access vector interpretation for controlling
-# access through the name service cache daemon (nscd).
-#
-class nscd
-{
- getpwd
- getgrp
- gethost
- getstat
- admin
- shmempwd
- shmemgrp
- shmemhost
- getserv
- shmemserv
-}
-
-# Define the access vector interpretation for controlling
-# access to IPSec network data by association
-#
-class association
-{
- sendto
- recvfrom
- setcontext
- polmatch
-}
-
-# Updated Netlink class for KOBJECT_UEVENT family.
-class netlink_kobject_uevent_socket
-inherits socket
-
-class appletalk_socket
-inherits socket
-
-class packet
-{
- send
- recv
- relabelto
- flow_in # deprecated
- flow_out # deprecated
- forward_in
- forward_out
-}
-
-class key
-{
- view
- read
- write
- search
- link
- setattr
- create
-}
-
-class context
-{
- translate
- contains
-}
-
-class dccp_socket
-inherits socket
-{
- node_bind
- name_connect
-}
-
-class memprotect
-{
- mmap_zero
-}
-
-class db_database
-inherits database
-{
- access
- install_module
- load_module
- get_param # deprecated
- set_param # deprecated
-}
-
-class db_table
-inherits database
-{
- use # deprecated
- select
- update
- insert
- delete
- lock
-}
-
-class db_procedure
-inherits database
-{
- execute
- entrypoint
- install
-}
-
-class db_column
-inherits database
-{
- use # deprecated
- select
- update
- insert
-}
-
-class db_tuple
-{
- relabelfrom
- relabelto
- use # deprecated
- select
- update
- insert
- delete
-}
-
-class db_blob
-inherits database
-{
- read
- write
- import
- export
-}
-
-# network peer labels
-class peer
-{
- recv
-}
-
-class x_application_data
-{
- paste
- paste_after_confirm
- copy
-}
-
-class kernel_service
-{
- use_as_override
- create_files_as
-}
-
-class tun_socket
-inherits socket
-
-class x_pointer
-inherits x_device
-
-class x_keyboard
-inherits x_device
-
-class db_schema
-inherits database
-{
- search
- add_name
- remove_name
-}
-
-class db_view
-inherits database
-{
- expand
-}
-
-class db_sequence
-inherits database
-{
- get_value
- next_value
- set_value
-}
-
-class db_language
-inherits database
-{
- implement
- execute
-}
-
-class binder
-{
- impersonate
- call
- set_context_mgr
- transfer
-}
-
-class zygote
-{
- specifyids
- specifyrlimits
- specifycapabilities
- specifyinvokewith
- specifyseinfo
-}
-
-class property_service
-{
- set
-}
-#line 1 "external/sepolicy/global_macros"
-#####################################
-# Common groupings of object classes.
-#
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#####################################
-# Common groupings of permissions.
-#
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#####################################
-# Common socket permission sets.
-
-
-#line 1 "external/sepolicy/mls_macros"
-########################################
-#
-# gen_cats(N)
-#
-# declares categores c0 to c(N-1)
-#
-#line 10
-
-
-
-
-########################################
-#
-# gen_sens(N)
-#
-# declares sensitivites s0 to s(N-1) with dominance
-# in increasing numeric order with s0 lowest, s(N-1) highest
-#
-#line 24
-
-
-
-
-#line 34
-
-
-########################################
-#
-# gen_levels(N,M)
-#
-# levels from s0 to (N-1) with categories c0 to (M-1)
-#
-#line 45
-
-
-
-
-########################################
-#
-# Basic level names for system low and high
-#
-
-
-#line 1 "external/sepolicy/mls"
-#########################################
-# MLS declarations
-#
-
-# Generate the desired number of sensitivities and categories.
-
-#line 6
-# Each sensitivity has a name and zero or more aliases.
-#line 6
-sensitivity s0;
-#line 6
-
-#line 6
-
-#line 6
-# Define the ordering of the sensitivity levels (least to greatest)
-#line 6
-dominance { s0 }
-#line 6
-
-category c0;
-#line 7
-category c1;
-#line 7
-category c2;
-#line 7
-category c3;
-#line 7
-category c4;
-#line 7
-category c5;
-#line 7
-category c6;
-#line 7
-category c7;
-#line 7
-category c8;
-#line 7
-category c9;
-#line 7
-category c10;
-#line 7
-category c11;
-#line 7
-category c12;
-#line 7
-category c13;
-#line 7
-category c14;
-#line 7
-category c15;
-#line 7
-category c16;
-#line 7
-category c17;
-#line 7
-category c18;
-#line 7
-category c19;
-#line 7
-category c20;
-#line 7
-category c21;
-#line 7
-category c22;
-#line 7
-category c23;
-#line 7
-category c24;
-#line 7
-category c25;
-#line 7
-category c26;
-#line 7
-category c27;
-#line 7
-category c28;
-#line 7
-category c29;
-#line 7
-category c30;
-#line 7
-category c31;
-#line 7
-category c32;
-#line 7
-category c33;
-#line 7
-category c34;
-#line 7
-category c35;
-#line 7
-category c36;
-#line 7
-category c37;
-#line 7
-category c38;
-#line 7
-category c39;
-#line 7
-category c40;
-#line 7
-category c41;
-#line 7
-category c42;
-#line 7
-category c43;
-#line 7
-category c44;
-#line 7
-category c45;
-#line 7
-category c46;
-#line 7
-category c47;
-#line 7
-category c48;
-#line 7
-category c49;
-#line 7
-category c50;
-#line 7
-category c51;
-#line 7
-category c52;
-#line 7
-category c53;
-#line 7
-category c54;
-#line 7
-category c55;
-#line 7
-category c56;
-#line 7
-category c57;
-#line 7
-category c58;
-#line 7
-category c59;
-#line 7
-category c60;
-#line 7
-category c61;
-#line 7
-category c62;
-#line 7
-category c63;
-#line 7
-category c64;
-#line 7
-category c65;
-#line 7
-category c66;
-#line 7
-category c67;
-#line 7
-category c68;
-#line 7
-category c69;
-#line 7
-category c70;
-#line 7
-category c71;
-#line 7
-category c72;
-#line 7
-category c73;
-#line 7
-category c74;
-#line 7
-category c75;
-#line 7
-category c76;
-#line 7
-category c77;
-#line 7
-category c78;
-#line 7
-category c79;
-#line 7
-category c80;
-#line 7
-category c81;
-#line 7
-category c82;
-#line 7
-category c83;
-#line 7
-category c84;
-#line 7
-category c85;
-#line 7
-category c86;
-#line 7
-category c87;
-#line 7
-category c88;
-#line 7
-category c89;
-#line 7
-category c90;
-#line 7
-category c91;
-#line 7
-category c92;
-#line 7
-category c93;
-#line 7
-category c94;
-#line 7
-category c95;
-#line 7
-category c96;
-#line 7
-category c97;
-#line 7
-category c98;
-#line 7
-category c99;
-#line 7
-category c100;
-#line 7
-category c101;
-#line 7
-category c102;
-#line 7
-category c103;
-#line 7
-category c104;
-#line 7
-category c105;
-#line 7
-category c106;
-#line 7
-category c107;
-#line 7
-category c108;
-#line 7
-category c109;
-#line 7
-category c110;
-#line 7
-category c111;
-#line 7
-category c112;
-#line 7
-category c113;
-#line 7
-category c114;
-#line 7
-category c115;
-#line 7
-category c116;
-#line 7
-category c117;
-#line 7
-category c118;
-#line 7
-category c119;
-#line 7
-category c120;
-#line 7
-category c121;
-#line 7
-category c122;
-#line 7
-category c123;
-#line 7
-category c124;
-#line 7
-category c125;
-#line 7
-category c126;
-#line 7
-category c127;
-#line 7
-category c128;
-#line 7
-category c129;
-#line 7
-category c130;
-#line 7
-category c131;
-#line 7
-category c132;
-#line 7
-category c133;
-#line 7
-category c134;
-#line 7
-category c135;
-#line 7
-category c136;
-#line 7
-category c137;
-#line 7
-category c138;
-#line 7
-category c139;
-#line 7
-category c140;
-#line 7
-category c141;
-#line 7
-category c142;
-#line 7
-category c143;
-#line 7
-category c144;
-#line 7
-category c145;
-#line 7
-category c146;
-#line 7
-category c147;
-#line 7
-category c148;
-#line 7
-category c149;
-#line 7
-category c150;
-#line 7
-category c151;
-#line 7
-category c152;
-#line 7
-category c153;
-#line 7
-category c154;
-#line 7
-category c155;
-#line 7
-category c156;
-#line 7
-category c157;
-#line 7
-category c158;
-#line 7
-category c159;
-#line 7
-category c160;
-#line 7
-category c161;
-#line 7
-category c162;
-#line 7
-category c163;
-#line 7
-category c164;
-#line 7
-category c165;
-#line 7
-category c166;
-#line 7
-category c167;
-#line 7
-category c168;
-#line 7
-category c169;
-#line 7
-category c170;
-#line 7
-category c171;
-#line 7
-category c172;
-#line 7
-category c173;
-#line 7
-category c174;
-#line 7
-category c175;
-#line 7
-category c176;
-#line 7
-category c177;
-#line 7
-category c178;
-#line 7
-category c179;
-#line 7
-category c180;
-#line 7
-category c181;
-#line 7
-category c182;
-#line 7
-category c183;
-#line 7
-category c184;
-#line 7
-category c185;
-#line 7
-category c186;
-#line 7
-category c187;
-#line 7
-category c188;
-#line 7
-category c189;
-#line 7
-category c190;
-#line 7
-category c191;
-#line 7
-category c192;
-#line 7
-category c193;
-#line 7
-category c194;
-#line 7
-category c195;
-#line 7
-category c196;
-#line 7
-category c197;
-#line 7
-category c198;
-#line 7
-category c199;
-#line 7
-category c200;
-#line 7
-category c201;
-#line 7
-category c202;
-#line 7
-category c203;
-#line 7
-category c204;
-#line 7
-category c205;
-#line 7
-category c206;
-#line 7
-category c207;
-#line 7
-category c208;
-#line 7
-category c209;
-#line 7
-category c210;
-#line 7
-category c211;
-#line 7
-category c212;
-#line 7
-category c213;
-#line 7
-category c214;
-#line 7
-category c215;
-#line 7
-category c216;
-#line 7
-category c217;
-#line 7
-category c218;
-#line 7
-category c219;
-#line 7
-category c220;
-#line 7
-category c221;
-#line 7
-category c222;
-#line 7
-category c223;
-#line 7
-category c224;
-#line 7
-category c225;
-#line 7
-category c226;
-#line 7
-category c227;
-#line 7
-category c228;
-#line 7
-category c229;
-#line 7
-category c230;
-#line 7
-category c231;
-#line 7
-category c232;
-#line 7
-category c233;
-#line 7
-category c234;
-#line 7
-category c235;
-#line 7
-category c236;
-#line 7
-category c237;
-#line 7
-category c238;
-#line 7
-category c239;
-#line 7
-category c240;
-#line 7
-category c241;
-#line 7
-category c242;
-#line 7
-category c243;
-#line 7
-category c244;
-#line 7
-category c245;
-#line 7
-category c246;
-#line 7
-category c247;
-#line 7
-category c248;
-#line 7
-category c249;
-#line 7
-category c250;
-#line 7
-category c251;
-#line 7
-category c252;
-#line 7
-category c253;
-#line 7
-category c254;
-#line 7
-category c255;
-#line 7
-category c256;
-#line 7
-category c257;
-#line 7
-category c258;
-#line 7
-category c259;
-#line 7
-category c260;
-#line 7
-category c261;
-#line 7
-category c262;
-#line 7
-category c263;
-#line 7
-category c264;
-#line 7
-category c265;
-#line 7
-category c266;
-#line 7
-category c267;
-#line 7
-category c268;
-#line 7
-category c269;
-#line 7
-category c270;
-#line 7
-category c271;
-#line 7
-category c272;
-#line 7
-category c273;
-#line 7
-category c274;
-#line 7
-category c275;
-#line 7
-category c276;
-#line 7
-category c277;
-#line 7
-category c278;
-#line 7
-category c279;
-#line 7
-category c280;
-#line 7
-category c281;
-#line 7
-category c282;
-#line 7
-category c283;
-#line 7
-category c284;
-#line 7
-category c285;
-#line 7
-category c286;
-#line 7
-category c287;
-#line 7
-category c288;
-#line 7
-category c289;
-#line 7
-category c290;
-#line 7
-category c291;
-#line 7
-category c292;
-#line 7
-category c293;
-#line 7
-category c294;
-#line 7
-category c295;
-#line 7
-category c296;
-#line 7
-category c297;
-#line 7
-category c298;
-#line 7
-category c299;
-#line 7
-category c300;
-#line 7
-category c301;
-#line 7
-category c302;
-#line 7
-category c303;
-#line 7
-category c304;
-#line 7
-category c305;
-#line 7
-category c306;
-#line 7
-category c307;
-#line 7
-category c308;
-#line 7
-category c309;
-#line 7
-category c310;
-#line 7
-category c311;
-#line 7
-category c312;
-#line 7
-category c313;
-#line 7
-category c314;
-#line 7
-category c315;
-#line 7
-category c316;
-#line 7
-category c317;
-#line 7
-category c318;
-#line 7
-category c319;
-#line 7
-category c320;
-#line 7
-category c321;
-#line 7
-category c322;
-#line 7
-category c323;
-#line 7
-category c324;
-#line 7
-category c325;
-#line 7
-category c326;
-#line 7
-category c327;
-#line 7
-category c328;
-#line 7
-category c329;
-#line 7
-category c330;
-#line 7
-category c331;
-#line 7
-category c332;
-#line 7
-category c333;
-#line 7
-category c334;
-#line 7
-category c335;
-#line 7
-category c336;
-#line 7
-category c337;
-#line 7
-category c338;
-#line 7
-category c339;
-#line 7
-category c340;
-#line 7
-category c341;
-#line 7
-category c342;
-#line 7
-category c343;
-#line 7
-category c344;
-#line 7
-category c345;
-#line 7
-category c346;
-#line 7
-category c347;
-#line 7
-category c348;
-#line 7
-category c349;
-#line 7
-category c350;
-#line 7
-category c351;
-#line 7
-category c352;
-#line 7
-category c353;
-#line 7
-category c354;
-#line 7
-category c355;
-#line 7
-category c356;
-#line 7
-category c357;
-#line 7
-category c358;
-#line 7
-category c359;
-#line 7
-category c360;
-#line 7
-category c361;
-#line 7
-category c362;
-#line 7
-category c363;
-#line 7
-category c364;
-#line 7
-category c365;
-#line 7
-category c366;
-#line 7
-category c367;
-#line 7
-category c368;
-#line 7
-category c369;
-#line 7
-category c370;
-#line 7
-category c371;
-#line 7
-category c372;
-#line 7
-category c373;
-#line 7
-category c374;
-#line 7
-category c375;
-#line 7
-category c376;
-#line 7
-category c377;
-#line 7
-category c378;
-#line 7
-category c379;
-#line 7
-category c380;
-#line 7
-category c381;
-#line 7
-category c382;
-#line 7
-category c383;
-#line 7
-category c384;
-#line 7
-category c385;
-#line 7
-category c386;
-#line 7
-category c387;
-#line 7
-category c388;
-#line 7
-category c389;
-#line 7
-category c390;
-#line 7
-category c391;
-#line 7
-category c392;
-#line 7
-category c393;
-#line 7
-category c394;
-#line 7
-category c395;
-#line 7
-category c396;
-#line 7
-category c397;
-#line 7
-category c398;
-#line 7
-category c399;
-#line 7
-category c400;
-#line 7
-category c401;
-#line 7
-category c402;
-#line 7
-category c403;
-#line 7
-category c404;
-#line 7
-category c405;
-#line 7
-category c406;
-#line 7
-category c407;
-#line 7
-category c408;
-#line 7
-category c409;
-#line 7
-category c410;
-#line 7
-category c411;
-#line 7
-category c412;
-#line 7
-category c413;
-#line 7
-category c414;
-#line 7
-category c415;
-#line 7
-category c416;
-#line 7
-category c417;
-#line 7
-category c418;
-#line 7
-category c419;
-#line 7
-category c420;
-#line 7
-category c421;
-#line 7
-category c422;
-#line 7
-category c423;
-#line 7
-category c424;
-#line 7
-category c425;
-#line 7
-category c426;
-#line 7
-category c427;
-#line 7
-category c428;
-#line 7
-category c429;
-#line 7
-category c430;
-#line 7
-category c431;
-#line 7
-category c432;
-#line 7
-category c433;
-#line 7
-category c434;
-#line 7
-category c435;
-#line 7
-category c436;
-#line 7
-category c437;
-#line 7
-category c438;
-#line 7
-category c439;
-#line 7
-category c440;
-#line 7
-category c441;
-#line 7
-category c442;
-#line 7
-category c443;
-#line 7
-category c444;
-#line 7
-category c445;
-#line 7
-category c446;
-#line 7
-category c447;
-#line 7
-category c448;
-#line 7
-category c449;
-#line 7
-category c450;
-#line 7
-category c451;
-#line 7
-category c452;
-#line 7
-category c453;
-#line 7
-category c454;
-#line 7
-category c455;
-#line 7
-category c456;
-#line 7
-category c457;
-#line 7
-category c458;
-#line 7
-category c459;
-#line 7
-category c460;
-#line 7
-category c461;
-#line 7
-category c462;
-#line 7
-category c463;
-#line 7
-category c464;
-#line 7
-category c465;
-#line 7
-category c466;
-#line 7
-category c467;
-#line 7
-category c468;
-#line 7
-category c469;
-#line 7
-category c470;
-#line 7
-category c471;
-#line 7
-category c472;
-#line 7
-category c473;
-#line 7
-category c474;
-#line 7
-category c475;
-#line 7
-category c476;
-#line 7
-category c477;
-#line 7
-category c478;
-#line 7
-category c479;
-#line 7
-category c480;
-#line 7
-category c481;
-#line 7
-category c482;
-#line 7
-category c483;
-#line 7
-category c484;
-#line 7
-category c485;
-#line 7
-category c486;
-#line 7
-category c487;
-#line 7
-category c488;
-#line 7
-category c489;
-#line 7
-category c490;
-#line 7
-category c491;
-#line 7
-category c492;
-#line 7
-category c493;
-#line 7
-category c494;
-#line 7
-category c495;
-#line 7
-category c496;
-#line 7
-category c497;
-#line 7
-category c498;
-#line 7
-category c499;
-#line 7
-category c500;
-#line 7
-category c501;
-#line 7
-category c502;
-#line 7
-category c503;
-#line 7
-category c504;
-#line 7
-category c505;
-#line 7
-category c506;
-#line 7
-category c507;
-#line 7
-category c508;
-#line 7
-category c509;
-#line 7
-category c510;
-#line 7
-category c511;
-#line 7
-category c512;
-#line 7
-category c513;
-#line 7
-category c514;
-#line 7
-category c515;
-#line 7
-category c516;
-#line 7
-category c517;
-#line 7
-category c518;
-#line 7
-category c519;
-#line 7
-category c520;
-#line 7
-category c521;
-#line 7
-category c522;
-#line 7
-category c523;
-#line 7
-category c524;
-#line 7
-category c525;
-#line 7
-category c526;
-#line 7
-category c527;
-#line 7
-category c528;
-#line 7
-category c529;
-#line 7
-category c530;
-#line 7
-category c531;
-#line 7
-category c532;
-#line 7
-category c533;
-#line 7
-category c534;
-#line 7
-category c535;
-#line 7
-category c536;
-#line 7
-category c537;
-#line 7
-category c538;
-#line 7
-category c539;
-#line 7
-category c540;
-#line 7
-category c541;
-#line 7
-category c542;
-#line 7
-category c543;
-#line 7
-category c544;
-#line 7
-category c545;
-#line 7
-category c546;
-#line 7
-category c547;
-#line 7
-category c548;
-#line 7
-category c549;
-#line 7
-category c550;
-#line 7
-category c551;
-#line 7
-category c552;
-#line 7
-category c553;
-#line 7
-category c554;
-#line 7
-category c555;
-#line 7
-category c556;
-#line 7
-category c557;
-#line 7
-category c558;
-#line 7
-category c559;
-#line 7
-category c560;
-#line 7
-category c561;
-#line 7
-category c562;
-#line 7
-category c563;
-#line 7
-category c564;
-#line 7
-category c565;
-#line 7
-category c566;
-#line 7
-category c567;
-#line 7
-category c568;
-#line 7
-category c569;
-#line 7
-category c570;
-#line 7
-category c571;
-#line 7
-category c572;
-#line 7
-category c573;
-#line 7
-category c574;
-#line 7
-category c575;
-#line 7
-category c576;
-#line 7
-category c577;
-#line 7
-category c578;
-#line 7
-category c579;
-#line 7
-category c580;
-#line 7
-category c581;
-#line 7
-category c582;
-#line 7
-category c583;
-#line 7
-category c584;
-#line 7
-category c585;
-#line 7
-category c586;
-#line 7
-category c587;
-#line 7
-category c588;
-#line 7
-category c589;
-#line 7
-category c590;
-#line 7
-category c591;
-#line 7
-category c592;
-#line 7
-category c593;
-#line 7
-category c594;
-#line 7
-category c595;
-#line 7
-category c596;
-#line 7
-category c597;
-#line 7
-category c598;
-#line 7
-category c599;
-#line 7
-category c600;
-#line 7
-category c601;
-#line 7
-category c602;
-#line 7
-category c603;
-#line 7
-category c604;
-#line 7
-category c605;
-#line 7
-category c606;
-#line 7
-category c607;
-#line 7
-category c608;
-#line 7
-category c609;
-#line 7
-category c610;
-#line 7
-category c611;
-#line 7
-category c612;
-#line 7
-category c613;
-#line 7
-category c614;
-#line 7
-category c615;
-#line 7
-category c616;
-#line 7
-category c617;
-#line 7
-category c618;
-#line 7
-category c619;
-#line 7
-category c620;
-#line 7
-category c621;
-#line 7
-category c622;
-#line 7
-category c623;
-#line 7
-category c624;
-#line 7
-category c625;
-#line 7
-category c626;
-#line 7
-category c627;
-#line 7
-category c628;
-#line 7
-category c629;
-#line 7
-category c630;
-#line 7
-category c631;
-#line 7
-category c632;
-#line 7
-category c633;
-#line 7
-category c634;
-#line 7
-category c635;
-#line 7
-category c636;
-#line 7
-category c637;
-#line 7
-category c638;
-#line 7
-category c639;
-#line 7
-category c640;
-#line 7
-category c641;
-#line 7
-category c642;
-#line 7
-category c643;
-#line 7
-category c644;
-#line 7
-category c645;
-#line 7
-category c646;
-#line 7
-category c647;
-#line 7
-category c648;
-#line 7
-category c649;
-#line 7
-category c650;
-#line 7
-category c651;
-#line 7
-category c652;
-#line 7
-category c653;
-#line 7
-category c654;
-#line 7
-category c655;
-#line 7
-category c656;
-#line 7
-category c657;
-#line 7
-category c658;
-#line 7
-category c659;
-#line 7
-category c660;
-#line 7
-category c661;
-#line 7
-category c662;
-#line 7
-category c663;
-#line 7
-category c664;
-#line 7
-category c665;
-#line 7
-category c666;
-#line 7
-category c667;
-#line 7
-category c668;
-#line 7
-category c669;
-#line 7
-category c670;
-#line 7
-category c671;
-#line 7
-category c672;
-#line 7
-category c673;
-#line 7
-category c674;
-#line 7
-category c675;
-#line 7
-category c676;
-#line 7
-category c677;
-#line 7
-category c678;
-#line 7
-category c679;
-#line 7
-category c680;
-#line 7
-category c681;
-#line 7
-category c682;
-#line 7
-category c683;
-#line 7
-category c684;
-#line 7
-category c685;
-#line 7
-category c686;
-#line 7
-category c687;
-#line 7
-category c688;
-#line 7
-category c689;
-#line 7
-category c690;
-#line 7
-category c691;
-#line 7
-category c692;
-#line 7
-category c693;
-#line 7
-category c694;
-#line 7
-category c695;
-#line 7
-category c696;
-#line 7
-category c697;
-#line 7
-category c698;
-#line 7
-category c699;
-#line 7
-category c700;
-#line 7
-category c701;
-#line 7
-category c702;
-#line 7
-category c703;
-#line 7
-category c704;
-#line 7
-category c705;
-#line 7
-category c706;
-#line 7
-category c707;
-#line 7
-category c708;
-#line 7
-category c709;
-#line 7
-category c710;
-#line 7
-category c711;
-#line 7
-category c712;
-#line 7
-category c713;
-#line 7
-category c714;
-#line 7
-category c715;
-#line 7
-category c716;
-#line 7
-category c717;
-#line 7
-category c718;
-#line 7
-category c719;
-#line 7
-category c720;
-#line 7
-category c721;
-#line 7
-category c722;
-#line 7
-category c723;
-#line 7
-category c724;
-#line 7
-category c725;
-#line 7
-category c726;
-#line 7
-category c727;
-#line 7
-category c728;
-#line 7
-category c729;
-#line 7
-category c730;
-#line 7
-category c731;
-#line 7
-category c732;
-#line 7
-category c733;
-#line 7
-category c734;
-#line 7
-category c735;
-#line 7
-category c736;
-#line 7
-category c737;
-#line 7
-category c738;
-#line 7
-category c739;
-#line 7
-category c740;
-#line 7
-category c741;
-#line 7
-category c742;
-#line 7
-category c743;
-#line 7
-category c744;
-#line 7
-category c745;
-#line 7
-category c746;
-#line 7
-category c747;
-#line 7
-category c748;
-#line 7
-category c749;
-#line 7
-category c750;
-#line 7
-category c751;
-#line 7
-category c752;
-#line 7
-category c753;
-#line 7
-category c754;
-#line 7
-category c755;
-#line 7
-category c756;
-#line 7
-category c757;
-#line 7
-category c758;
-#line 7
-category c759;
-#line 7
-category c760;
-#line 7
-category c761;
-#line 7
-category c762;
-#line 7
-category c763;
-#line 7
-category c764;
-#line 7
-category c765;
-#line 7
-category c766;
-#line 7
-category c767;
-#line 7
-category c768;
-#line 7
-category c769;
-#line 7
-category c770;
-#line 7
-category c771;
-#line 7
-category c772;
-#line 7
-category c773;
-#line 7
-category c774;
-#line 7
-category c775;
-#line 7
-category c776;
-#line 7
-category c777;
-#line 7
-category c778;
-#line 7
-category c779;
-#line 7
-category c780;
-#line 7
-category c781;
-#line 7
-category c782;
-#line 7
-category c783;
-#line 7
-category c784;
-#line 7
-category c785;
-#line 7
-category c786;
-#line 7
-category c787;
-#line 7
-category c788;
-#line 7
-category c789;
-#line 7
-category c790;
-#line 7
-category c791;
-#line 7
-category c792;
-#line 7
-category c793;
-#line 7
-category c794;
-#line 7
-category c795;
-#line 7
-category c796;
-#line 7
-category c797;
-#line 7
-category c798;
-#line 7
-category c799;
-#line 7
-category c800;
-#line 7
-category c801;
-#line 7
-category c802;
-#line 7
-category c803;
-#line 7
-category c804;
-#line 7
-category c805;
-#line 7
-category c806;
-#line 7
-category c807;
-#line 7
-category c808;
-#line 7
-category c809;
-#line 7
-category c810;
-#line 7
-category c811;
-#line 7
-category c812;
-#line 7
-category c813;
-#line 7
-category c814;
-#line 7
-category c815;
-#line 7
-category c816;
-#line 7
-category c817;
-#line 7
-category c818;
-#line 7
-category c819;
-#line 7
-category c820;
-#line 7
-category c821;
-#line 7
-category c822;
-#line 7
-category c823;
-#line 7
-category c824;
-#line 7
-category c825;
-#line 7
-category c826;
-#line 7
-category c827;
-#line 7
-category c828;
-#line 7
-category c829;
-#line 7
-category c830;
-#line 7
-category c831;
-#line 7
-category c832;
-#line 7
-category c833;
-#line 7
-category c834;
-#line 7
-category c835;
-#line 7
-category c836;
-#line 7
-category c837;
-#line 7
-category c838;
-#line 7
-category c839;
-#line 7
-category c840;
-#line 7
-category c841;
-#line 7
-category c842;
-#line 7
-category c843;
-#line 7
-category c844;
-#line 7
-category c845;
-#line 7
-category c846;
-#line 7
-category c847;
-#line 7
-category c848;
-#line 7
-category c849;
-#line 7
-category c850;
-#line 7
-category c851;
-#line 7
-category c852;
-#line 7
-category c853;
-#line 7
-category c854;
-#line 7
-category c855;
-#line 7
-category c856;
-#line 7
-category c857;
-#line 7
-category c858;
-#line 7
-category c859;
-#line 7
-category c860;
-#line 7
-category c861;
-#line 7
-category c862;
-#line 7
-category c863;
-#line 7
-category c864;
-#line 7
-category c865;
-#line 7
-category c866;
-#line 7
-category c867;
-#line 7
-category c868;
-#line 7
-category c869;
-#line 7
-category c870;
-#line 7
-category c871;
-#line 7
-category c872;
-#line 7
-category c873;
-#line 7
-category c874;
-#line 7
-category c875;
-#line 7
-category c876;
-#line 7
-category c877;
-#line 7
-category c878;
-#line 7
-category c879;
-#line 7
-category c880;
-#line 7
-category c881;
-#line 7
-category c882;
-#line 7
-category c883;
-#line 7
-category c884;
-#line 7
-category c885;
-#line 7
-category c886;
-#line 7
-category c887;
-#line 7
-category c888;
-#line 7
-category c889;
-#line 7
-category c890;
-#line 7
-category c891;
-#line 7
-category c892;
-#line 7
-category c893;
-#line 7
-category c894;
-#line 7
-category c895;
-#line 7
-category c896;
-#line 7
-category c897;
-#line 7
-category c898;
-#line 7
-category c899;
-#line 7
-category c900;
-#line 7
-category c901;
-#line 7
-category c902;
-#line 7
-category c903;
-#line 7
-category c904;
-#line 7
-category c905;
-#line 7
-category c906;
-#line 7
-category c907;
-#line 7
-category c908;
-#line 7
-category c909;
-#line 7
-category c910;
-#line 7
-category c911;
-#line 7
-category c912;
-#line 7
-category c913;
-#line 7
-category c914;
-#line 7
-category c915;
-#line 7
-category c916;
-#line 7
-category c917;
-#line 7
-category c918;
-#line 7
-category c919;
-#line 7
-category c920;
-#line 7
-category c921;
-#line 7
-category c922;
-#line 7
-category c923;
-#line 7
-category c924;
-#line 7
-category c925;
-#line 7
-category c926;
-#line 7
-category c927;
-#line 7
-category c928;
-#line 7
-category c929;
-#line 7
-category c930;
-#line 7
-category c931;
-#line 7
-category c932;
-#line 7
-category c933;
-#line 7
-category c934;
-#line 7
-category c935;
-#line 7
-category c936;
-#line 7
-category c937;
-#line 7
-category c938;
-#line 7
-category c939;
-#line 7
-category c940;
-#line 7
-category c941;
-#line 7
-category c942;
-#line 7
-category c943;
-#line 7
-category c944;
-#line 7
-category c945;
-#line 7
-category c946;
-#line 7
-category c947;
-#line 7
-category c948;
-#line 7
-category c949;
-#line 7
-category c950;
-#line 7
-category c951;
-#line 7
-category c952;
-#line 7
-category c953;
-#line 7
-category c954;
-#line 7
-category c955;
-#line 7
-category c956;
-#line 7
-category c957;
-#line 7
-category c958;
-#line 7
-category c959;
-#line 7
-category c960;
-#line 7
-category c961;
-#line 7
-category c962;
-#line 7
-category c963;
-#line 7
-category c964;
-#line 7
-category c965;
-#line 7
-category c966;
-#line 7
-category c967;
-#line 7
-category c968;
-#line 7
-category c969;
-#line 7
-category c970;
-#line 7
-category c971;
-#line 7
-category c972;
-#line 7
-category c973;
-#line 7
-category c974;
-#line 7
-category c975;
-#line 7
-category c976;
-#line 7
-category c977;
-#line 7
-category c978;
-#line 7
-category c979;
-#line 7
-category c980;
-#line 7
-category c981;
-#line 7
-category c982;
-#line 7
-category c983;
-#line 7
-category c984;
-#line 7
-category c985;
-#line 7
-category c986;
-#line 7
-category c987;
-#line 7
-category c988;
-#line 7
-category c989;
-#line 7
-category c990;
-#line 7
-category c991;
-#line 7
-category c992;
-#line 7
-category c993;
-#line 7
-category c994;
-#line 7
-category c995;
-#line 7
-category c996;
-#line 7
-category c997;
-#line 7
-category c998;
-#line 7
-category c999;
-#line 7
-category c1000;
-#line 7
-category c1001;
-#line 7
-category c1002;
-#line 7
-category c1003;
-#line 7
-category c1004;
-#line 7
-category c1005;
-#line 7
-category c1006;
-#line 7
-category c1007;
-#line 7
-category c1008;
-#line 7
-category c1009;
-#line 7
-category c1010;
-#line 7
-category c1011;
-#line 7
-category c1012;
-#line 7
-category c1013;
-#line 7
-category c1014;
-#line 7
-category c1015;
-#line 7
-category c1016;
-#line 7
-category c1017;
-#line 7
-category c1018;
-#line 7
-category c1019;
-#line 7
-category c1020;
-#line 7
-category c1021;
-#line 7
-category c1022;
-#line 7
-category c1023;
-#line 7
-
-
-# Generate level definitions for each sensitivity and category.
-level s0:c0.c1023;
-#line 10
-
-
-
-#################################################
-# MLS policy constraints
-#
-
-#
-# Process constraints
-#
-
-# Process transition: Require equivalence unless the subject is trusted.
-mlsconstrain process { transition dyntransition }
- ((h1 eq h2 and l1 eq l2) or t1 == mlstrustedsubject);
-
-# Process read operations: No read up unless trusted.
-mlsconstrain process { getsched getsession getpgid getcap getattr ptrace share }
- (l1 dom l2 or t1 == mlstrustedsubject);
-
-# Process write operations: No write down unless trusted.
-mlsconstrain process { sigkill sigstop signal setsched setpgid setcap setrlimit ptrace share }
- (l1 domby l2 or t1 == mlstrustedsubject);
-
-#
-# Socket constraints
-#
-
-# Create/relabel operations: Subject must be equivalent to object unless
-# the subject is trusted. Sockets inherit the range of their creator.
-mlsconstrain { socket tcp_socket udp_socket rawip_socket netlink_socket packet_socket key_socket unix_stream_socket unix_dgram_socket appletalk_socket netlink_route_socket netlink_firewall_socket netlink_tcpdiag_socket netlink_nflog_socket netlink_xfrm_socket netlink_selinux_socket netlink_audit_socket netlink_ip6fw_socket netlink_dnrt_socket netlink_kobject_uevent_socket tun_socket } { create relabelfrom relabelto }
- ((h1 eq h2 and l1 eq l2) or t1 == mlstrustedsubject);
-
-# Datagram send: Sender must be dominated by receiver unless one of them is
-# trusted.
-mlsconstrain unix_dgram_socket { sendto }
- (l1 domby l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);
-
-# Stream connect: Client must be equivalent to server unless one of them
-# is trusted.
-mlsconstrain unix_stream_socket { connectto }
- (l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);
-
-#
-# Directory/file constraints
-#
-
-# Create/relabel operations: Subject must be equivalent to object unless
-# the subject is trusted. Also, files should always be single-level.
-# Do NOT exempt mlstrustedobject types from this constraint.
-mlsconstrain { dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } { create relabelfrom relabelto }
- (l2 eq h2 and (l1 eq l2 or t1 == mlstrustedsubject));
-
-#
-# Constraints for app data files only.
-#
-
-# Only constrain open, not read/write.
-# Also constrain other forms of manipulation, e.g. chmod/chown, unlink, rename, etc.
-# Subject must be equivalent to object unless the subject is trusted.
-mlsconstrain dir { open search setattr rename add_name remove_name reparent rmdir }
- (t2 != app_data_file or l1 eq l2 or t1 == mlstrustedsubject);
-mlsconstrain { file lnk_file sock_file } { open setattr unlink link rename }
- (t2 != app_data_file or l1 eq l2 or t1 == mlstrustedsubject);
-
-#
-# Constraints for file types other than app data files.
-#
-
-# Read operations: Subject must dominate object unless the subject
-# or the object is trusted.
-mlsconstrain dir { read getattr search }
- (t2 == app_data_file or l1 dom l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
-
-mlsconstrain { file lnk_file sock_file chr_file blk_file } { read getattr execute }
- (t2 == app_data_file or l1 dom l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
-
-# Write operations: Subject must be dominated by the object unless the
-# subject or the object is trusted.
-mlsconstrain dir { write setattr rename add_name remove_name reparent rmdir }
- (t2 == app_data_file or l1 domby l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
-
-mlsconstrain { file lnk_file sock_file chr_file blk_file } { write setattr append unlink link rename }
- (t2 == app_data_file or l1 domby l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
-
-# Special case for FIFOs.
-# These can be unnamed pipes, in which case they will be labeled with the
-# creating process' label. Thus we also have an exemption when the "object"
-# is a MLS trusted subject and can receive data at any level.
-mlsconstrain fifo_file { read getattr }
- (l1 dom l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject or t2 == mlstrustedsubject);
-
-mlsconstrain fifo_file { write setattr append unlink link rename }
- (l1 domby l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject or t2 == mlstrustedsubject);
-
-#
-# IPC constraints
-#
-
-# Create/destroy: equivalence or trusted.
-mlsconstrain { sem msgq shm ipc } { create destroy }
- (l2 eq h2 and (l1 eq l2 or t1 == mlstrustedsubject));
-
-# Read ops: No read up unless trusted.
-mlsconstrain { sem msgq shm ipc } { getattr read associate unix_read }
- (l1 dom l2 or t1 == mlstrustedsubject);
-
-# Write ops: No write down unless trusted.
-mlsconstrain { sem msgq shm ipc } { write unix_write }
- (l1 domby l2 or t1 == mlstrustedsubject);
-
-#
-# Binder IPC constraints
-#
-# Presently commented out, as apps are expected to call one another.
-# This would only make sense if apps were assigned categories
-# based on allowable communications rather than per-app categories.
-#mlsconstrain binder call
-# (l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);
-#line 1 "external/sepolicy/policy_capabilities"
-# Enable new networking controls.
-policycap network_peer_controls;
-
-# Enable open permission check.
-policycap open_perms;
-#line 1 "external/sepolicy/te_macros"
-#####################################
-# domain_trans(olddomain, type, newdomain)
-# Allow a transition from olddomain to newdomain
-# upon executing a file labeled with type.
-# This only allows the transition; it does not
-# cause it to occur automatically - use domain_auto_trans
-# if that is what you want.
-#
-#line 21
-
-
-#####################################
-# domain_auto_trans(olddomain, type, newdomain)
-# Automatically transition from olddomain to newdomain
-# upon executing a file labeled with type.
-#
-#line 33
-
-
-#####################################
-# file_type_trans(domain, dir_type, file_type)
-# Allow domain to create a file labeled file_type in a
-# directory labeled dir_type.
-# This only allows the transition; it does not
-# cause it to occur automatically - use file_type_auto_trans
-# if that is what you want.
-#
-#line 49
-
-
-#####################################
-# file_type_auto_trans(domain, dir_type, file_type)
-# Automatically label new files with file_type when
-# they are created by domain in directories labeled dir_type.
-#
-#line 62
-
-
-#####################################
-# r_dir_file(domain, type)
-# Allow the specified domain to read directories, files
-# and symbolic links of the specified type.
-#line 71
-
-
-#####################################
-# unconfined_domain(domain)
-# Allow the specified domain to perform more privileged operations
-# than would be typically allowed. Please see the comments at the
-# top of unconfined.te.
-#
-#line 82
-
-
-#####################################
-# tmpfs_domain(domain)
-# Define and allow access to a unique type for
-# this domain when creating tmpfs / shmem / ashmem files.
-#line 92
-
-
-#####################################
-# init_daemon_domain(domain)
-# Set up a transition from init to the daemon domain
-# upon executing its binary.
-#line 101
-
-
-#####################################
-# app_domain(domain)
-# Allow a base set of permissions required for all apps.
-#line 112
-
-
-#####################################
-# relabelto_domain(domain)
-# Allows this domain to use the relabelto permission
-#line 119
-
-
-#####################################
-# platform_app_domain(domain)
-# Allow permissions specific to platform apps.
-#line 127
-
-
-#####################################
-# net_domain(domain)
-# Allow a base set of permissions required for network access.
-#line 134
-
-
-#####################################
-# bluetooth_domain(domain)
-# Allow a base set of permissions required for bluetooth access.
-#line 141
-
-
-#####################################
-# unix_socket_connect(clientdomain, socket, serverdomain)
-# Allow a local socket connection from clientdomain via
-# socket to serverdomain.
-#line 150
-
-
-#####################################
-# unix_socket_send(clientdomain, socket, serverdomain)
-# Allow a local socket send from clientdomain via
-# socket to serverdomain.
-#line 159
-
-
-#####################################
-# binder_use(domain)
-# Allow domain to use Binder IPC.
-#line 169
-
-
-#####################################
-# binder_call(clientdomain, serverdomain)
-# Allow clientdomain to perform binder IPC to serverdomain.
-#line 181
-
-
-#####################################
-# binder_service(domain)
-# Mark a domain as being a Binder service domain.
-# Used to allow binder IPC to the various system services.
-#line 189
-
-
-#####################################
-# selinux_check_access(domain)
-# Allow domain to check SELinux permissions via selinuxfs.
-#line 199
-
-
-#####################################
-# selinux_check_context(domain)
-# Allow domain to check SELinux contexts via selinuxfs.
-#line 208
-
-
-#####################################
-# selinux_getenforce(domain)
-# Allow domain to check whether SELinux is enforcing.
-#line 216
-
-
-#####################################
-# selinux_setenforce(domain)
-# Allow domain to set SELinux to enforcing.
-#line 225
-
-
-#####################################
-# selinux_setbool(domain)
-# Allow domain to set SELinux booleans.
-#line 234
-
-
-#####################################
-# security_access_policy(domain)
-# Read only access to all policy files and
-# selinuxfs
-#line 248
-
-
-#####################################
-# selinux_manage_policy(domain)
-# Ability to manage policy files and
-# trigger runtime reload.
-#line 261
-
-
-#####################################
-# mmac_manage_policy(domain)
-# Ability to manage mmac policy files,
-# trigger runtime reload, change
-# mmac enforcing mode and access logcat.
-#line 274
-
-
-#####################################
-# access_kmsg(domain)
-# Ability to read from kernel logs
-# and execute the klogctl syscall
-# in a non destructive manner. See
-# man 2 klogctl
-#line 284
-
-
-#####################################
-# write_klog(domain)
-# Ability to write to kernel log via
-# klog_write()
-# See system/core/libcutil/klog.c
-#line 295
-
-
-#####################################
-# create_pty(domain)
-# Allow domain to create and use a pty, isolated from any other domain ptys.
-#line 309
-
-
-#####################################
-# Non system_app application set
-#
-
-
-#####################################
-# Userdebug or eng builds
-# SELinux rules which apply only to userdebug or eng builds
-#
-
-
-#####################################
-# permissive_or_unconfined
-# Returns "permissive $1" if FORCE_PERMISSIVE_TO_UNCONFINED is false,
-# and "unconfined($1)" otherwise.
-#
-# This is used for experimental domains, where we want to ensure
-# the domain is unconfined+enforcing once new SELinux policy development
-# has ceased.
-#
-
-
-#####################################
-# write_logd(domain)
-# Ability to write to android log
-# daemon via sockets
-#line 345
-
-
-#####################################
-# read_logd(domain)
-# Ability to read from android
-# log daemon via sockets
-#line 353
-
-
-#####################################
-# control_logd(domain)
-# Ability to control
-# android log daemon via sockets
-#line 363
-
-#line 1 "external/sepolicy/attributes"
-######################################
-# Attribute declarations
-#
-
-# All types used for devices.
-attribute dev_type;
-
-# All types used for processes.
-attribute domain;
-
-# All types used for filesystems.
-attribute fs_type;
-
-# All types used for files that can exist on a labeled fs.
-# Do not use for pseudo file types.
-attribute file_type;
-
-# All types used for domain entry points.
-attribute exec_type;
-
-# All types used for /data files.
-attribute data_file_type;
-
-# All types use for sysfs files.
-attribute sysfs_type;
-
-# Attribute used for all sdcards
-attribute sdcard_type;
-
-# All types used for nodes/hosts.
-attribute node_type;
-
-# All types used for network interfaces.
-attribute netif_type;
-
-# All types used for network ports.
-attribute port_type;
-
-# All types used for property service
-attribute property_type;
-
-# All domains that can override MLS restrictions.
-# i.e. processes that can read up and write down.
-attribute mlstrustedsubject;
-
-# All types that can override MLS restrictions.
-# i.e. files that can be read by lower and written by higher
-attribute mlstrustedobject;
-
-# Domains that are allowed all permissions ("unconfined").
-attribute unconfineddomain;
-
-# All domains used for shells.
-attribute shelldomain;
-
-# All domains used for apps.
-attribute appdomain;
-
-# All domains used for apps with network access.
-attribute netdomain;
-
-# All domains used for apps with bluetooth access.
-attribute bluetoothdomain;
-
-# All domains used for binder service domains.
-attribute binderservicedomain;
-
-# Allow domains used for platform (signed by build key) apps.
-attribute platformappdomain;
-
-# All domains which are allowed the "relabelto" permission
-attribute relabeltodomain;
-#line 1 "external/sepolicy/adbd.te"
-# adbd seclabel is specified in init.rc since
-# it lives in the rootfs and has no unique file type.
-type adbd, domain;
-
-#line 7
-
-
-
-#line 9
-# Allow the necessary permissions.
-#line 9
-
-#line 9
-# Old domain may exec the file and transition to the new domain.
-#line 9
-allow adbd shell_exec:file { getattr open read execute };
-#line 9
-allow adbd shell:process transition;
-#line 9
-# New domain is entered by executing the file.
-#line 9
-allow shell shell_exec:file { entrypoint read execute };
-#line 9
-# New domain can send SIGCHLD to its caller.
-#line 9
-allow shell adbd:process sigchld;
-#line 9
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 9
-dontaudit adbd shell:process noatsecure;
-#line 9
-# XXX dontaudit candidate but requires further study.
-#line 9
-allow adbd shell:process { siginh rlimitinh };
-#line 9
-
-#line 9
-# Make the transition occur by default.
-#line 9
-type_transition adbd shell_exec:process shell;
-#line 9
-
-# this is an entrypoint
-allow adbd rootfs:file entrypoint;
-
-# Do not sanitize the environment or open fds of the shell.
-allow adbd shell:process noatsecure;
-
-# Set UID and GID to shell. Set supplementary groups.
-allow adbd self:capability { setuid setgid };
-
-# Drop capabilities from bounding set on user builds.
-allow adbd self:capability setpcap;
-
-# Create and use network sockets.
-
-#line 23
-typeattribute adbd netdomain;
-#line 23
-
-
-# Access /dev/android_adb.
-allow adbd adb_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# On emulator, access /dev/qemu*.
-allow adbd qemu_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Use a pseudo tty.
-allow adbd devpts:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# adb push/pull /data/local/tmp.
-allow adbd shell_data_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow adbd shell_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# adb push/pull sdcard.
-allow adbd sdcard_type:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow adbd sdcard_type:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Set service.adb.*, sys.powerctl properties.
-
-#line 43
-allow adbd property_socket:sock_file write;
-#line 43
-allow adbd init:unix_stream_socket connectto;
-#line 43
-
-allow adbd shell_prop:property_service set;
-allow adbd powerctl_prop:property_service set;
-
-# XXX Run /system/bin/vdc to connect to vold. Run in a separate domain?
-# Also covers running /system/bin/bu.
-allow adbd system_file:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-
-#line 50
-allow adbd vold_socket:sock_file write;
-#line 50
-allow adbd vold:unix_stream_socket connectto;
-#line 50
-
-
-# Perform binder IPC to surfaceflinger (screencap)
-# XXX Run screencap in a separate domain?
-
-#line 54
-# Call the servicemanager and transfer references to it.
-#line 54
-allow adbd servicemanager:binder { call transfer };
-#line 54
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 54
-# all domains in domain.te.
-#line 54
-
-
-#line 55
-# Call the server domain and optionally transfer references to it.
-#line 55
-allow adbd surfaceflinger:binder { call transfer };
-#line 55
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 55
-allow surfaceflinger adbd:binder transfer;
-#line 55
-# Receive and use open files from the server.
-#line 55
-allow adbd surfaceflinger:fd use;
-#line 55
-
-
-# Read /data/misc/adb/adb_keys.
-allow adbd adb_keys_file:dir search;
-allow adbd adb_keys_file:file { getattr open read ioctl lock };
-
-# Allow access in case /data/misc/adb still has the old type.
-allow adbd system_data_file:dir search;
-allow adbd system_data_file:file { getattr open read ioctl lock };
-
-# ndk-gdb invokes adb forward to forward the gdbserver socket.
-allow adbd app_data_file:dir search;
-allow adbd app_data_file:sock_file write;
-allow adbd appdomain:unix_stream_socket connectto;
-
-# ndk-gdb invokes adb pull of app_process, linker, and libc.so.
-allow adbd zygote_exec:file { getattr open read ioctl lock };
-allow adbd system_file:file { getattr open read ioctl lock };
-#line 1 "external/sepolicy/app.te"
-###
-### Domain for all zygote spawned apps
-###
-### This file is the base policy for all zygote spawned apps.
-### Other policy files, such as isolated_app.te, untrusted_app.te, etc
-### extend from this policy. Only policies which should apply to ALL
-### zygote spawned apps should be added here.
-###
-
-# Dalvik Compiler JIT Mapping.
-allow appdomain self:process execmem;
-allow appdomain ashmem_device:chr_file execute;
-
-# Allow apps to connect to the keystore
-
-#line 15
-allow appdomain keystore_socket:sock_file write;
-#line 15
-allow appdomain keystore:unix_stream_socket connectto;
-#line 15
-
-
-# Receive and use open file descriptors inherited from zygote.
-allow appdomain zygote:fd use;
-
-# gdbserver for ndk-gdb reads the zygote.
-allow appdomain zygote_exec:file { getattr open read ioctl lock };
-
-# gdbserver for ndk-gdb ptrace attaches to app process.
-allow appdomain self:process ptrace;
-
-# Read system properties managed by zygote.
-allow appdomain zygote_tmpfs:file read;
-
-# Notify zygote of death;
-allow appdomain zygote:process sigchld;
-
-# Notify shell and adbd of death when spawned via runas for ndk-gdb.
-allow appdomain shell:process sigchld;
-allow appdomain adbd:process sigchld;
-
-# child shell or gdbserver pty access for runas.
-allow appdomain devpts:chr_file { getattr read write ioctl };
-
-# Communicate with system_server.
-allow appdomain system_server:fifo_file { { getattr open read ioctl lock } { open append write } };
-allow appdomain system_server:unix_stream_socket { read write setopt };
-
-#line 42
-# Call the server domain and optionally transfer references to it.
-#line 42
-allow appdomain system_server:binder { call transfer };
-#line 42
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 42
-allow system_server appdomain:binder transfer;
-#line 42
-# Receive and use open files from the server.
-#line 42
-allow appdomain system_server:fd use;
-#line 42
-
-
-# Communication with other apps via fifos
-allow appdomain appdomain:fifo_file { { getattr open read ioctl lock } { open append write } };
-
-# Communicate with surfaceflinger.
-allow appdomain surfaceflinger:unix_stream_socket { read write setopt };
-
-#line 49
-# Call the server domain and optionally transfer references to it.
-#line 49
-allow appdomain surfaceflinger:binder { call transfer };
-#line 49
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 49
-allow surfaceflinger appdomain:binder transfer;
-#line 49
-# Receive and use open files from the server.
-#line 49
-allow appdomain surfaceflinger:fd use;
-#line 49
-
-
-# App sandbox file accesses.
-allow appdomain app_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow appdomain app_data_file:{ file lnk_file sock_file fifo_file } { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Read/write data files created by the platform apps if they
-# were passed to the app via binder or local IPC. Do not allow open.
-allow appdomain platform_app_data_file:file { getattr read write };
-
-# lib subdirectory of /data/data dir is system-owned.
-allow appdomain system_data_file:dir { open getattr read search ioctl };
-allow appdomain system_data_file:file { execute execute_no_trans open };
-
-# Execute the shell or other system executables.
-allow appdomain shell_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-allow appdomain system_file:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-
-# Read/write wallpaper file (opened by system).
-allow appdomain wallpaper_file:file { getattr read write };
-
-# Write to /data/anr/traces.txt.
-allow appdomain anr_data_file:dir search;
-allow appdomain anr_data_file:file { open append };
-
-# Allow apps to send dump information to dumpstate
-allow appdomain dumpstate:fd use;
-allow appdomain dumpstate:unix_stream_socket { read write getopt getattr };
-allow appdomain shell_data_file:file { write getattr };
-
-# Write to /proc/net/xt_qtaguid/ctrl file.
-allow appdomain qtaguid_proc:file { { getattr open read ioctl lock } { open append write } };
-# Everybody can read the xt_qtaguid resource tracking misc dev.
-# So allow all apps to read from /dev/xt_qtaguid.
-allow appdomain qtaguid_device:chr_file { getattr open read ioctl lock };
-
-# Grant GPU access to all processes started by Zygote.
-# They need that to render the standard UI.
-allow appdomain gpu_device:chr_file { { { getattr open read ioctl lock } { open append write } } execute };
-
-# Use the Binder.
-
-#line 90
-# Call the servicemanager and transfer references to it.
-#line 90
-allow appdomain servicemanager:binder { call transfer };
-#line 90
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 90
-# all domains in domain.te.
-#line 90
-
-# Perform binder IPC to binder services.
-
-#line 92
-# Call the server domain and optionally transfer references to it.
-#line 92
-allow appdomain binderservicedomain:binder { call transfer };
-#line 92
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 92
-allow binderservicedomain appdomain:binder transfer;
-#line 92
-# Receive and use open files from the server.
-#line 92
-allow appdomain binderservicedomain:fd use;
-#line 92
-
-# Perform binder IPC to other apps.
-
-#line 94
-# Call the server domain and optionally transfer references to it.
-#line 94
-allow appdomain appdomain:binder { call transfer };
-#line 94
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 94
-allow appdomain appdomain:binder transfer;
-#line 94
-# Receive and use open files from the server.
-#line 94
-allow appdomain appdomain:fd use;
-#line 94
-
-
-# Appdomain interaction with isolated apps
-
-#line 97
-allow appdomain isolated_app:dir { open getattr read search ioctl };
-#line 97
-allow appdomain isolated_app:{ file lnk_file } { getattr open read ioctl lock };
-#line 97
-
-
-# Already connected, unnamed sockets being passed over some other IPC
-# hence no sock_file or connectto permission. This appears to be how
-# Chrome works, may need to be updated as more apps using isolated services
-# are examined.
-allow appdomain isolated_app:unix_stream_socket { read write };
-
-# Backup ability for every app. BMS opens and passes the fd
-# to any app that has backup ability. Hence, no open permissions here.
-allow appdomain backup_data_file:file { read write getattr };
-allow appdomain cache_backup_file:file { read write getattr };
-# Backup ability using 'adb backup'
-allow appdomain system_data_file:lnk_file getattr;
-
-# Allow all applications to read downloaded files
-allow appdomain download_file:dir search;
-allow appdomain download_file:file { getattr open read ioctl lock };
-
-# Allow applications to communicate with netd via /dev/socket/dnsproxyd
-# to do DNS resolution
-
-#line 118
-allow appdomain dnsproxyd_socket:sock_file write;
-#line 118
-allow appdomain netd:unix_stream_socket connectto;
-#line 118
-
-
-# Allow applications to communicate with drmserver over binder
-
-#line 121
-# Call the server domain and optionally transfer references to it.
-#line 121
-allow appdomain drmserver:binder { call transfer };
-#line 121
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 121
-allow drmserver appdomain:binder transfer;
-#line 121
-# Receive and use open files from the server.
-#line 121
-allow appdomain drmserver:fd use;
-#line 121
-
-
-# Allow applications to communicate with mediaserver over binder
-
-#line 124
-# Call the server domain and optionally transfer references to it.
-#line 124
-allow appdomain mediaserver:binder { call transfer };
-#line 124
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 124
-allow mediaserver appdomain:binder transfer;
-#line 124
-# Receive and use open files from the server.
-#line 124
-allow appdomain mediaserver:fd use;
-#line 124
-
-
-# Allow applications to make outbound tcp connections to any port
-allow appdomain port_type:tcp_socket name_connect;
-
-# Allow apps to see changes to the routing table.
-allow appdomain self:netlink_route_socket {
- read
- bind
- create
- nlmsg_read
- ioctl
- getattr
- setattr
- getopt
- setopt
- shutdown
-};
-
-# Allow apps to use rawip sockets. This is needed for apps which execute
-# /system/bin/ping, for example.
-allow appdomain self:rawip_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-
-# Allow apps to use the USB Accessory interface.
-# http://developer.android.com/guide/topics/connectivity/usb/accessory.html
-#
-# USB devices are first opened by the system server (USBDeviceManagerService)
-# and the file descriptor is passed to the right Activity via binder.
-allow appdomain usb_device:chr_file { read write getattr ioctl };
-allow appdomain usbaccessory_device:chr_file { read write getattr };
-
-# For art.
-allow appdomain dalvikcache_data_file:file execute;
-
-# For legacy unlabeled userdata on existing devices.
-# See discussion of Unlabeled files in domain.te for more information.
-allow appdomain unlabeled:file { getattr execute execute_no_trans };
-
-###
-### CTS-specific rules
-###
-
-# For cts/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/RootProcessScanner.java.
-# Reads /proc/pid/status and statm entries to check that
-# no unexpected root processes are running.
-# Also for cts/tests/tests/security/src/android/security/cts/VoldExploitTest.java
-# Reads /proc/pid/cmdline of vold.
-allow appdomain domain:dir { open read search getattr };
-allow appdomain domain:{ file lnk_file } { open read getattr };
-
-# For cts/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java.
-# testRunAsHasCorrectCapabilities
-allow appdomain runas_exec:file getattr;
-# Others are either allowed elsewhere or not desired.
-
-# For cts/tests/tests/security/src/android/security/cts/SELinuxTest.java
-# Check SELinux policy and contexts.
-
-#line 181
-allow appdomain selinuxfs:dir { open getattr read search ioctl };
-#line 181
-allow appdomain selinuxfs:file { { getattr open read ioctl lock } { open append write } };
-#line 181
-allow appdomain kernel:security compute_av;
-#line 181
-allow appdomain self:netlink_selinux_socket *;
-#line 181
-
-
-#line 182
-allow appdomain selinuxfs:dir { open getattr read search ioctl };
-#line 182
-allow appdomain selinuxfs:file { { getattr open read ioctl lock } { open append write } };
-#line 182
-allow appdomain kernel:security check_context;
-#line 182
-
-# Validate that each process is running in the correct security context.
-allow appdomain domain:process getattr;
-
-# logd access
-
-#line 187
-
-#line 187
-allow appdomain logdr_socket:sock_file write;
-#line 187
-allow appdomain logd:unix_stream_socket connectto;
-#line 187
-
-#line 187
-
-# application inherit logd write socket (urge is to deprecate this long term)
-allow appdomain zygote:unix_dgram_socket write;
-
-###
-### Neverallow rules
-###
-### These are things that Android apps should NEVER be able to do
-###
-
-# Superuser capabilities.
-# bluetooth requires net_admin.
-neverallow { appdomain -unconfineddomain -bluetooth } self:capability *;
-neverallow { appdomain -unconfineddomain } self:capability2 *;
-
-# Block device access.
-neverallow { appdomain -unconfineddomain } dev_type:blk_file { read write };
-
-# Access to any of the following character devices.
-neverallow { appdomain -unconfineddomain } {
- audio_device
- camera_device
- dm_device
- radio_device
- gps_device
- rpmsg_device
-}:chr_file { read write };
-
-# Note: Try expanding list of app domains in the future.
-neverallow { untrusted_app isolated_app shell -unconfineddomain }
- graphics_device:chr_file { read write };
-
-neverallow { appdomain -nfc -unconfineddomain } nfc_device:chr_file
- { read write };
-neverallow { appdomain -bluetooth -unconfineddomain } hci_attach_dev:chr_file
- { read write };
-neverallow { appdomain -unconfineddomain } tee_device:chr_file { read write };
-
-# Set SELinux enforcing mode, booleans or any other SELinux settings.
-neverallow { appdomain -unconfineddomain } kernel:security
- { setenforce setbool setsecparam setcheckreqprot };
-
-# Load security policy.
-neverallow appdomain kernel:security load_policy;
-
-# Privileged netlink socket interfaces.
-neverallow { appdomain -unconfineddomain }
- self:{
- netlink_socket
- netlink_firewall_socket
- netlink_tcpdiag_socket
- netlink_nflog_socket
- netlink_xfrm_socket
- netlink_audit_socket
- netlink_ip6fw_socket
- netlink_dnrt_socket
- netlink_kobject_uevent_socket
- } *;
-
-# Sockets under /dev/socket that are not specifically typed.
-neverallow { appdomain -unconfineddomain } socket_device:sock_file write;
-
-# Unix domain sockets.
-neverallow { appdomain -unconfineddomain } adbd_socket:sock_file write;
-neverallow { appdomain -unconfineddomain } installd_socket:sock_file write;
-neverallow { appdomain -bluetooth -radio -shell -system_app -unconfineddomain }
- property_socket:sock_file write;
-neverallow { appdomain -radio -unconfineddomain } rild_socket:sock_file write;
-neverallow { appdomain -unconfineddomain } vold_socket:sock_file write;
-neverallow { appdomain -unconfineddomain } zygote_socket:sock_file write;
-
-# ptrace access to non-app domains.
-neverallow { appdomain -unconfineddomain } { domain -appdomain }:process ptrace;
-
-# Write access to /proc/pid entries for any non-app domain.
-neverallow { appdomain -unconfineddomain } { domain -appdomain }:file write;
-
-# signal access to non-app domains.
-# sigchld allowed for parent death notification.
-# signull allowed for kill(pid, 0) existence test.
-# All others prohibited.
-neverallow { appdomain -unconfineddomain } { domain -appdomain }:process
- { sigkill sigstop signal };
-
-# Transition to a non-app domain.
-# Exception for the shell domain, can transition to runas, etc.
-neverallow { appdomain -shell -unconfineddomain } ~appdomain:process
- { transition dyntransition };
-
-# Map low memory.
-# Note: Take to domain.te and apply to all domains in the future.
-neverallow { appdomain -unconfineddomain } self:memprotect mmap_zero;
-
-# Write to rootfs.
-neverallow { appdomain -unconfineddomain } rootfs:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-
-# Write to /system.
-neverallow { appdomain -unconfineddomain } system_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-
-# Write to entrypoint executables.
-neverallow { appdomain -unconfineddomain } exec_type:file
- { create write setattr relabelfrom relabelto append unlink link rename };
-
-# Write to system-owned parts of /data.
-# This is the default type for anything under /data not otherwise
-# specified in file_contexts. Define a different type for portions
-# that should be writable by apps.
-# Exception for system_app for Settings.
-neverallow { appdomain -unconfineddomain -system_app }
- system_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-
-# Write to various other parts of /data.
-neverallow { appdomain -system_app -unconfineddomain }
- security_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -unconfineddomain } drm_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -unconfineddomain } gps_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -platform_app -unconfineddomain }
- apk_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -platform_app -unconfineddomain }
- apk_tmp_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -platform_app -unconfineddomain }
- apk_private_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -platform_app -unconfineddomain }
- apk_private_tmp_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -shell -unconfineddomain }
- shell_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -bluetooth -unconfineddomain }
- bluetooth_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -unconfineddomain }
- keystore_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -unconfineddomain }
- systemkeys_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -unconfineddomain }
- wifi_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-neverallow { appdomain -unconfineddomain }
- dhcp_data_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } }
- { create write setattr relabelfrom relabelto append unlink link rename };
-
-# Access to factory files.
-neverallow { appdomain -unconfineddomain }
- efs_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } { read write };
-
-# Write to various pseudo file systems.
-neverallow { appdomain -bluetooth -nfc -unconfineddomain }
- sysfs:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } write;
-neverallow { appdomain -unconfineddomain }
- proc:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } write;
-
-# Access to syslog(2) or /proc/kmsg.
-neverallow { appdomain -system_app -unconfineddomain }
- kernel:system { syslog_read syslog_mod syslog_console };
-
-# Ability to perform any filesystem operation other than statfs(2).
-# i.e. no mount(2), unmount(2), etc.
-neverallow { appdomain -unconfineddomain } fs_type:filesystem ~getattr;
-
-# Ability to set system properties.
-neverallow { appdomain -system_app -radio -shell -bluetooth -unconfineddomain }
- property_type:property_service set;
-#line 1 "external/sepolicy/binderservicedomain.te"
-# Rules common to all binder service domains
-
-# Allow dumpstate to collect information from binder services
-allow binderservicedomain dumpstate:fd use;
-allow binderservicedomain dumpstate:unix_stream_socket { read write getopt getattr };
-allow binderservicedomain shell_data_file:file { getattr write };
-
-# Allow dumpsys to work from adb shell
-allow binderservicedomain devpts:chr_file { { getattr open read ioctl lock } { open append write } };
-#line 1 "external/sepolicy/bluetooth.te"
-# bluetooth subsystem
-type bluetooth, domain;
-
-#line 3
-typeattribute bluetooth appdomain;
-#line 3
-# Label ashmem objects with our own unique type.
-#line 3
-
-#line 3
-type bluetooth_tmpfs, file_type;
-#line 3
-type_transition bluetooth tmpfs:file bluetooth_tmpfs;
-#line 3
-allow bluetooth bluetooth_tmpfs:file { read write };
-#line 3
-
-#line 3
-# Map with PROT_EXEC.
-#line 3
-allow bluetooth bluetooth_tmpfs:file execute;
-#line 3
-
-
-# Data file accesses.
-allow bluetooth bluetooth_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow bluetooth bluetooth_data_file:{ file lnk_file sock_file fifo_file } { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Socket creation under /data/misc/bluedroid.
-type_transition bluetooth bluetooth_data_file:sock_file bluetooth_socket;
-allow bluetooth bluetooth_socket:sock_file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# bluetooth factory file accesses.
-
-#line 14
-allow bluetooth bluetooth_efs_file:dir { open getattr read search ioctl };
-#line 14
-allow bluetooth bluetooth_efs_file:{ file lnk_file } { getattr open read ioctl lock };
-#line 14
-
-
-# Device accesses.
-allow bluetooth { tun_device uhid_device hci_attach_dev }:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Other domains that can create and use bluetooth sockets.
-# SELinux does not presently define a specific socket class for
-# bluetooth sockets, nor does it distinguish among the bluetooth protocols.
-allow bluetoothdomain self:socket *;
-
-# sysfs access.
-allow bluetooth sysfs_bluetooth_writable:file { { getattr open read ioctl lock } { open append write } };
-allow bluetooth self:capability net_admin;
-
-# Allow clients to use a socket provided by the bluetooth app.
-allow bluetoothdomain bluetooth:unix_stream_socket { read write shutdown };
-
-# tethering
-allow bluetooth self:{ tun_socket udp_socket } { ioctl create };
-allow bluetooth efs_file:dir search;
-
-# Talk to init over the property socket.
-
-#line 36
-allow bluetooth property_socket:sock_file write;
-#line 36
-allow bluetooth init:unix_stream_socket connectto;
-#line 36
-
-
-# proc access.
-allow bluetooth proc_bluetooth_writable:file { { getattr open read ioctl lock } { open append write } };
-
-# bluetooth file transfers
-allow bluetooth sdcard_internal:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow bluetooth sdcard_internal:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Allow reading of media_rw_data_file file descriptors
-# passed to bluetooth
-allow bluetooth media_rw_data_file:file { read getattr };
-
-# Allow write access to bluetooth specific properties
-allow bluetooth bluetooth_prop:property_service set;
-
-###
-### Neverallow rules
-###
-### These are things that the bluetooth app should NEVER be able to do
-###
-
-# Superuser capabilities.
-# bluetooth requires net_admin.
-neverallow { bluetooth -unconfineddomain } self:capability ~net_admin;
-#line 1 "external/sepolicy/bootanim.te"
-# bootanimation oneshot service
-type bootanim, domain;
-type bootanim_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init bootanim_exec:file { getattr open read execute };
-#line 5
-allow init bootanim:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow bootanim bootanim_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow bootanim init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init bootanim:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init bootanim:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init bootanim_exec:process bootanim;
-#line 5
-
-#line 5
-
-#line 5
-type bootanim_tmpfs, file_type;
-#line 5
-type_transition bootanim tmpfs:file bootanim_tmpfs;
-#line 5
-allow bootanim bootanim_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-
-
-#line 7
-# Call the servicemanager and transfer references to it.
-#line 7
-allow bootanim servicemanager:binder { call transfer };
-#line 7
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 7
-# all domains in domain.te.
-#line 7
-
-
-#line 8
-# Call the server domain and optionally transfer references to it.
-#line 8
-allow bootanim surfaceflinger:binder { call transfer };
-#line 8
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 8
-allow surfaceflinger bootanim:binder transfer;
-#line 8
-# Receive and use open files from the server.
-#line 8
-allow bootanim surfaceflinger:fd use;
-#line 8
-
-
-allow bootanim gpu_device:chr_file { { getattr open read ioctl lock } { open append write } };
-#line 1 "external/sepolicy/clatd.te"
-# 464xlat daemon
-type clatd, domain;
-
-#line 3
-typeattribute clatd mlstrustedsubject;
-#line 3
-typeattribute clatd unconfineddomain;
-#line 3
-
-type clatd_exec, exec_type, file_type;
-
-
-#line 6
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow init clatd_exec:file { getattr open read execute };
-#line 6
-allow init clatd:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow clatd clatd_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow clatd init:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit init clatd:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow init clatd:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition init clatd_exec:process clatd;
-#line 6
-
-#line 6
-
-#line 6
-type clatd_tmpfs, file_type;
-#line 6
-type_transition clatd tmpfs:file clatd_tmpfs;
-#line 6
-allow clatd clatd_tmpfs:file { read write };
-#line 6
-
-#line 6
-
-
-#line 7
-typeattribute clatd netdomain;
-#line 7
-
-#line 1 "external/sepolicy/debuggerd.te"
-# debugger interface
-type debuggerd, domain;
-type debuggerd_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init debuggerd_exec:file { getattr open read execute };
-#line 5
-allow init debuggerd:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow debuggerd debuggerd_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow debuggerd init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init debuggerd:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init debuggerd:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init debuggerd_exec:process debuggerd;
-#line 5
-
-#line 5
-
-#line 5
-type debuggerd_tmpfs, file_type;
-#line 5
-type_transition debuggerd tmpfs:file debuggerd_tmpfs;
-#line 5
-allow debuggerd debuggerd_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-typeattribute debuggerd mlstrustedsubject;
-allow debuggerd self:capability { dac_override sys_ptrace chown kill fowner };
-allow debuggerd self:capability2 { syslog };
-allow debuggerd domain:dir { open getattr read search ioctl };
-allow debuggerd domain:file { getattr open read ioctl lock };
-allow debuggerd { domain -init -ueventd -watchdogd -healthd -adbd }:process ptrace;
-
-#line 12
-allow debuggerd security_file:dir { open getattr read search ioctl };
-#line 12
-allow debuggerd security_file:file { getattr open read ioctl lock };
-#line 12
-allow debuggerd security_file:lnk_file { getattr open read ioctl lock };
-#line 12
-allow debuggerd selinuxfs:dir { open getattr read search ioctl };
-#line 12
-allow debuggerd selinuxfs:file { getattr open read ioctl lock };
-#line 12
-allow debuggerd rootfs:dir { open getattr read search ioctl };
-#line 12
-allow debuggerd rootfs:file { getattr open read ioctl lock };
-#line 12
-
-allow debuggerd system_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow debuggerd system_data_file:dir relabelfrom;
-
-#line 15
-typeattribute debuggerd relabeltodomain;
-#line 15
-
-allow debuggerd tombstone_data_file:dir relabelto;
-allow debuggerd tombstone_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow debuggerd tombstone_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow debuggerd domain:process { sigstop signal };
-allow debuggerd exec_type:file { getattr open read ioctl lock };
-# Access app library
-allow debuggerd system_data_file:file open;
-
-# Connect to system_server via /data/system/ndebugsocket.
-
-#line 25
-allow debuggerd system_ndebug_socket:sock_file write;
-#line 25
-allow debuggerd system_server:unix_stream_socket connectto;
-#line 25
-
-
-#line 30
-
-
-# logd access
-
-#line 33
-
-#line 33
-allow debuggerd logdr_socket:sock_file write;
-#line 33
-allow debuggerd logd:unix_stream_socket connectto;
-#line 33
-
-#line 33
-
-#line 1 "external/sepolicy/device.te"
-# Device types
-type device, dev_type, fs_type;
-type alarm_device, dev_type, mlstrustedobject;
-type adb_device, dev_type;
-type ashmem_device, dev_type, mlstrustedobject;
-type audio_device, dev_type;
-type binder_device, dev_type, mlstrustedobject;
-type block_device, dev_type;
-type camera_device, dev_type;
-type dm_device, dev_type;
-type loop_device, dev_type;
-type radio_device, dev_type;
-type ram_device, dev_type;
-type console_device, dev_type;
-type cpuctl_device, dev_type;
-type fscklogs, dev_type;
-type full_device, dev_type;
-# GPU (used by most UI apps)
-type gpu_device, dev_type, mlstrustedobject;
-type graphics_device, dev_type;
-type hw_random_device, dev_type;
-type input_device, dev_type;
-type kmem_device, dev_type;
-type log_device, dev_type, mlstrustedobject;
-type mtd_device, dev_type;
-type mtp_device, dev_type, mlstrustedobject;
-type nfc_device, dev_type;
-type ptmx_device, dev_type, mlstrustedobject;
-type qemu_device, dev_type;
-type kmsg_device, dev_type;
-type null_device, dev_type, mlstrustedobject;
-type random_device, dev_type;
-type sensors_device, dev_type;
-type serial_device, dev_type;
-type socket_device, dev_type;
-type owntty_device, dev_type, mlstrustedobject;
-type tty_device, dev_type;
-type urandom_device, dev_type;
-type video_device, dev_type;
-type vcs_device, dev_type;
-type zero_device, dev_type;
-type fuse_device, dev_type;
-type iio_device, dev_type;
-type ion_device, dev_type, mlstrustedobject;
-type gps_device, dev_type;
-type qtaguid_device, dev_type;
-type watchdog_device, dev_type;
-type uhid_device, dev_type;
-type tun_device, dev_type, mlstrustedobject;
-type usbaccessory_device, dev_type;
-type usb_device, dev_type;
-type klog_device, dev_type;
-type properties_device, dev_type;
-
-# All devices have a uart for the hci
-# attach service. The uart dev node
-# varies per device. This type
-# is used in per device policy
-type hci_attach_dev, dev_type;
-
-# All devices have a rpmsg device for
-# achieving remoteproc and rpmsg modules
-type rpmsg_device, dev_type;
-
-# Partition layout block device
-type root_block_device, dev_type;
-#line 1 "external/sepolicy/dhcp.te"
-type dhcp, domain;
-
-#line 2
-typeattribute dhcp mlstrustedsubject;
-#line 2
-typeattribute dhcp unconfineddomain;
-#line 2
-
-type dhcp_exec, exec_type, file_type;
-type dhcp_data_file, file_type, data_file_type;
-
-
-#line 6
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow init dhcp_exec:file { getattr open read execute };
-#line 6
-allow init dhcp:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow dhcp dhcp_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow dhcp init:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit init dhcp:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow init dhcp:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition init dhcp_exec:process dhcp;
-#line 6
-
-#line 6
-
-#line 6
-type dhcp_tmpfs, file_type;
-#line 6
-type_transition dhcp tmpfs:file dhcp_tmpfs;
-#line 6
-allow dhcp dhcp_tmpfs:file { read write };
-#line 6
-
-#line 6
-
-
-#line 7
-typeattribute dhcp netdomain;
-#line 7
-
-
-allow dhcp cgroup:dir { create write add_name };
-allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service };
-allow dhcp self:packet_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-allow dhcp self:netlink_route_socket { { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } } nlmsg_write };
-allow dhcp self:rawip_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-allow dhcp shell_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-allow dhcp system_file:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-# For /proc/sys/net/ipv4/conf/*/promote_secondaries
-allow dhcp proc_net:file write;
-allow dhcp system_prop:property_service set ;
-
-#line 19
-allow dhcp property_socket:sock_file write;
-#line 19
-allow dhcp init:unix_stream_socket connectto;
-#line 19
-
-allow dhcp owntty_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-type_transition dhcp system_data_file:{ dir file } dhcp_data_file;
-allow dhcp dhcp_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow dhcp dhcp_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# PAN connections
-allow dhcp netd:fd use;
-allow dhcp netd:fifo_file { { getattr open read ioctl lock } { open append write } };
-allow dhcp netd:{ { udp_socket unix_dgram_socket } unix_stream_socket } { read write };
-allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket netlink_nflog_socket } { read write };
-#line 1 "external/sepolicy/dnsmasq.te"
-# DNS, DHCP services
-type dnsmasq, domain;
-
-#line 3
-typeattribute dnsmasq mlstrustedsubject;
-#line 3
-typeattribute dnsmasq unconfineddomain;
-#line 3
-
-type dnsmasq_exec, exec_type, file_type;
-
-allow dnsmasq self:capability { net_bind_service setgid setuid };
-allow dnsmasq self:tcp_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-
-allow dnsmasq dhcp_data_file:dir { open search write add_name remove_name };
-allow dnsmasq dhcp_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow dnsmasq port:tcp_socket name_bind;
-allow dnsmasq node:tcp_socket node_bind;
-#line 1 "external/sepolicy/domain.te"
-# Rules for all domains.
-
-# Allow reaping by init.
-allow domain init:process sigchld;
-
-# Read access to properties mapping.
-allow domain kernel:fd use;
-allow domain tmpfs:file { read getattr };
-
-# Search /storage/emulated tmpfs mount.
-allow domain tmpfs:dir { open getattr read search ioctl };
-
-# Intra-domain accesses.
-allow domain self:process ~{ execmem execstack execheap ptrace };
-allow domain self:fd use;
-allow domain self:dir { open getattr read search ioctl };
-allow domain self:lnk_file { getattr open read ioctl lock };
-allow domain self:{ fifo_file file } { { getattr open read ioctl lock } { open append write } };
-allow domain self:{ unix_dgram_socket unix_stream_socket } *;
-
-# Inherit or receive open files from others.
-allow domain init:fd use;
-allow domain system_server:fd use;
-
-# Connect to adbd and use a socket transferred from it.
-# This is used for e.g. adb backup/restore.
-allow domain adbd:unix_stream_socket connectto;
-allow domain adbd:fd use;
-allow domain adbd:unix_stream_socket { getattr getopt read write shutdown };
-
-#line 43
-
-
-###
-### Talk to debuggerd.
-###
-allow domain debuggerd:process sigchld;
-allow domain debuggerd:unix_stream_socket connectto;
-
-# Root fs.
-allow domain rootfs:dir { open getattr read search ioctl };
-allow domain rootfs:file { getattr open read ioctl lock };
-allow domain rootfs:lnk_file { getattr open read ioctl lock };
-
-# Device accesses.
-allow domain device:dir search;
-allow domain dev_type:lnk_file { getattr open read ioctl lock };
-allow domain devpts:dir search;
-allow domain device:file read;
-allow domain socket_device:dir search;
-allow domain owntty_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow domain null_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow domain zero_device:chr_file { getattr open read ioctl lock };
-allow domain ashmem_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow domain binder_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow domain ptmx_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow domain log_device:dir search;
-allow domain log_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow domain alarm_device:chr_file { getattr open read ioctl lock };
-allow domain urandom_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow domain random_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow domain properties_device:file { getattr open read ioctl lock };
-
-# logd access
-
-#line 76
-
-#line 76
-
-#line 76
-allow domain logdw_socket:sock_file write;
-#line 76
-allow domain logd:unix_dgram_socket sendto;
-#line 76
-
-#line 76
-
-
-# Filesystem accesses.
-allow domain fs_type:filesystem getattr;
-allow domain fs_type:dir getattr;
-
-# System file accesses.
-allow domain system_file:dir { open getattr read search ioctl };
-allow domain system_file:file { getattr open read ioctl lock };
-allow domain system_file:file execute;
-allow domain system_file:lnk_file { getattr open read ioctl lock };
-
-# Read files already opened under /data.
-allow domain system_data_file:dir { search getattr };
-allow domain system_data_file:file { getattr read };
-allow domain system_data_file:lnk_file { getattr open read ioctl lock };
-
-# Read apk files under /data/app.
-allow domain apk_data_file:dir { getattr search };
-allow domain apk_data_file:file { getattr open read ioctl lock };
-
-# Read /data/dalvik-cache.
-allow domain dalvikcache_data_file:dir { search getattr };
-allow domain dalvikcache_data_file:file { getattr open read ioctl lock };
-
-# Read already opened /cache files.
-allow domain cache_file:dir { open getattr read search ioctl };
-allow domain cache_file:file { getattr read };
-allow domain cache_file:lnk_file { getattr open read ioctl lock };
-
-# Read timezone related information
-
-#line 107
-allow domain zoneinfo_data_file:dir { open getattr read search ioctl };
-#line 107
-allow domain zoneinfo_data_file:{ file lnk_file } { getattr open read ioctl lock };
-#line 107
-
-
-# For /acct/uid/*/tasks.
-allow domain cgroup:dir { search write };
-allow domain cgroup:file { open append write };
-
-#Allow access to ion memory allocation device
-allow domain ion_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Read access to pseudo filesystems.
-
-#line 117
-allow domain proc:dir { open getattr read search ioctl };
-#line 117
-allow domain proc:{ file lnk_file } { getattr open read ioctl lock };
-#line 117
-
-
-#line 118
-allow domain sysfs:dir { open getattr read search ioctl };
-#line 118
-allow domain sysfs:{ file lnk_file } { getattr open read ioctl lock };
-#line 118
-
-
-#line 119
-allow domain sysfs_devices_system_cpu:dir { open getattr read search ioctl };
-#line 119
-allow domain sysfs_devices_system_cpu:{ file lnk_file } { getattr open read ioctl lock };
-#line 119
-
-
-#line 120
-allow domain inotify:dir { open getattr read search ioctl };
-#line 120
-allow domain inotify:{ file lnk_file } { getattr open read ioctl lock };
-#line 120
-
-
-#line 121
-allow domain cgroup:dir { open getattr read search ioctl };
-#line 121
-allow domain cgroup:{ file lnk_file } { getattr open read ioctl lock };
-#line 121
-
-
-#line 122
-allow domain proc_net:dir { open getattr read search ioctl };
-#line 122
-allow domain proc_net:{ file lnk_file } { getattr open read ioctl lock };
-#line 122
-
-
-# debugfs access
-allow domain debugfs:dir { open getattr read search ioctl };
-allow domain debugfs:file { open append write };
-
-# Get SELinux enforcing status.
-
-#line 129
-allow domain selinuxfs:dir { open getattr read search ioctl };
-#line 129
-allow domain selinuxfs:file { getattr open read ioctl lock };
-#line 129
-
-
-# security files
-allow domain security_file:dir { search getattr };
-allow domain security_file:file getattr;
-
-# World readable asec image contents
-allow domain asec_public_file:file { getattr open read ioctl lock };
-allow domain { asec_public_file asec_apk_file }:dir { open getattr read search ioctl };
-
-######## Backwards compatibility - Unlabeled files ############
-
-# Revert to DAC rules when looking at unlabeled files. Over time, the number
-# of unlabeled files should decrease.
-# TODO: delete these rules in the future.
-#
-# Note on relabelfrom: We allow any app relabelfrom, but without the relabelto
-# capability, it's essentially useless. This is needed to allow an app with
-# relabelto to relabel unlabeled files.
-#
-allow domain unlabeled:{ file lnk_file sock_file fifo_file } { { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } } relabelfrom };
-allow domain unlabeled:dir { { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } } relabelfrom };
-neverallow { domain -relabeltodomain } *:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } relabelto;
-
-###
-### neverallow rules
-###
-
-# Limit ability to ptrace or read sensitive /proc/pid files of processes
-# with other UIDs to these whitelisted domains.
-neverallow { domain -debuggerd -vold -dumpstate -system_server } self:capability sys_ptrace;
-
-# Limit device node creation and raw I/O to these whitelisted domains.
-neverallow { domain -kernel -init -recovery -ueventd -watchdogd -healthd -vold -uncrypt } self:capability { sys_rawio mknod };
-
-# No domain needs mac_override as it is unused by SELinux.
-neverallow domain self:capability2 mac_override;
-
-# Only recovery needs mac_admin to set contexts not defined in current policy.
-neverallow { domain -recovery } self:capability2 mac_admin;
-
-# Only init should be able to load SELinux policies.
-# The first load technically occurs while still in the kernel domain,
-# but this does not trigger a denial since there is no policy yet.
-# Policy reload requires allowing this to the init domain.
-neverallow { domain -init } kernel:security load_policy;
-
-# Only init prior to switching context should be able to set enforcing mode.
-# init starts in kernel domain and switches to init domain via setcon in
-# the init.rc, so the setenforce occurs while still in kernel. After
-# switching domains, there is never any need to setenforce again by init.
-neverallow { domain -kernel } kernel:security { setenforce setcheckreqprot };
-
-# Only init, ueventd and system_server should be able to access HW RNG
-neverallow { domain -init -system_server -ueventd -unconfineddomain } hw_random_device:chr_file *;
-
-# Ensure that all entrypoint executables are in exec_type.
-neverallow domain { file_type -exec_type }:file entrypoint;
-
-# Ensure that nothing in userspace can access /dev/mem or /dev/kmem
-neverallow { domain -kernel -ueventd -init } kmem_device:chr_file *;
-neverallow domain kmem_device:chr_file ~{ create relabelto unlink setattr };
-
-# Only init should be able to configure kernel usermodehelpers or
-# security-sensitive proc settings.
-neverallow { domain -init } usermodehelper:file { append write };
-neverallow { domain -init } proc_security:file { append write };
-
-# No domain should be allowed to ptrace init.
-neverallow domain init:process ptrace;
-
-# Init can't receive binder calls. If this neverallow rule is being
-# triggered, it's probably due to a service with no SELinux domain.
-neverallow domain init:binder call;
-
-# Don't allow raw read/write/open access to block_device
-# Rather force a relabel to a more specific type
-neverallow { domain -kernel -init -recovery -vold -uncrypt } block_device:blk_file { open read write };
-
-# Don't allow raw read/write/open access to generic devices.
-# Rather force a relabel to a more specific type.
-# ueventd is exempt from this, as its managing these devices.
-neverallow { domain -unconfineddomain -ueventd } device:chr_file { open read write };
-
-# Limit what domains can mount filesystems or change their mount flags.
-# sdcard_type / vfat is exempt as a larger set of domains need
-# this capability, including device-specific domains.
-neverallow { domain -kernel -init -recovery -vold -zygote } { fs_type -sdcard_type }:filesystem { mount remount relabelfrom relabelto };
-#line 1 "external/sepolicy/drmserver.te"
-# drmserver - DRM service
-type drmserver, domain;
-type drmserver_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init drmserver_exec:file { getattr open read execute };
-#line 5
-allow init drmserver:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow drmserver drmserver_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow drmserver init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init drmserver:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init drmserver:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init drmserver_exec:process drmserver;
-#line 5
-
-#line 5
-
-#line 5
-type drmserver_tmpfs, file_type;
-#line 5
-type_transition drmserver tmpfs:file drmserver_tmpfs;
-#line 5
-allow drmserver drmserver_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-typeattribute drmserver mlstrustedsubject;
-
-# Perform Binder IPC to system server.
-
-#line 9
-# Call the servicemanager and transfer references to it.
-#line 9
-allow drmserver servicemanager:binder { call transfer };
-#line 9
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 9
-# all domains in domain.te.
-#line 9
-
-
-#line 10
-# Call the server domain and optionally transfer references to it.
-#line 10
-allow drmserver system_server:binder { call transfer };
-#line 10
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 10
-allow system_server drmserver:binder transfer;
-#line 10
-# Receive and use open files from the server.
-#line 10
-allow drmserver system_server:fd use;
-#line 10
-
-
-#line 11
-# Call the server domain and optionally transfer references to it.
-#line 11
-allow drmserver appdomain:binder { call transfer };
-#line 11
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 11
-allow appdomain drmserver:binder transfer;
-#line 11
-# Receive and use open files from the server.
-#line 11
-allow drmserver appdomain:fd use;
-#line 11
-
-
-#line 12
-typeattribute drmserver binderservicedomain;
-#line 12
-
-
-# Perform Binder IPC to mediaserver
-
-#line 15
-# Call the server domain and optionally transfer references to it.
-#line 15
-allow drmserver mediaserver:binder { call transfer };
-#line 15
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 15
-allow mediaserver drmserver:binder transfer;
-#line 15
-# Receive and use open files from the server.
-#line 15
-allow drmserver mediaserver:fd use;
-#line 15
-
-
-allow drmserver sdcard_type:dir search;
-allow drmserver drm_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow drmserver drm_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow drmserver self:{ tcp_socket udp_socket } *;
-allow drmserver port:tcp_socket name_connect;
-allow drmserver tee_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow drmserver platform_app_data_file:file { read write getattr };
-allow drmserver app_data_file:file { read write getattr };
-allow drmserver sdcard_type:file { read write getattr };
-
-#line 26
-allow drmserver efs_file:dir { open getattr read search ioctl };
-#line 26
-allow drmserver efs_file:{ file lnk_file } { getattr open read ioctl lock };
-#line 26
-
-
-type drmserver_socket, file_type;
-
-# /data/app/tlcd_sock socket file.
-# Clearly, /data/app is the most logical place to create a socket. Not.
-allow drmserver apk_data_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-type_transition drmserver apk_data_file:sock_file drmserver_socket;
-allow drmserver drmserver_socket:sock_file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow drmserver tee:unix_stream_socket connectto;
-# Delete old socket file if present.
-allow drmserver apk_data_file:sock_file unlink;
-
-# After taking a video, drmserver looks at the video file.
-
-#line 40
-allow drmserver media_rw_data_file:dir { open getattr read search ioctl };
-#line 40
-allow drmserver media_rw_data_file:{ file lnk_file } { getattr open read ioctl lock };
-#line 40
-
-#line 1 "external/sepolicy/dumpstate.te"
-# dumpstate
-type dumpstate, domain;
-
-#line 3
-typeattribute dumpstate mlstrustedsubject;
-#line 3
-typeattribute dumpstate unconfineddomain;
-#line 3
-
-type dumpstate_exec, exec_type, file_type;
-
-
-#line 6
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow init dumpstate_exec:file { getattr open read execute };
-#line 6
-allow init dumpstate:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow dumpstate dumpstate_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow dumpstate init:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit init dumpstate:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow init dumpstate:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition init dumpstate_exec:process dumpstate;
-#line 6
-
-#line 6
-
-#line 6
-type dumpstate_tmpfs, file_type;
-#line 6
-type_transition dumpstate tmpfs:file dumpstate_tmpfs;
-#line 6
-allow dumpstate dumpstate_tmpfs:file { read write };
-#line 6
-
-#line 6
-
-
-#line 7
-typeattribute dumpstate netdomain;
-#line 7
-
-
-#line 8
-typeattribute dumpstate relabeltodomain;
-#line 8
-
-
-#line 9
-# Call the servicemanager and transfer references to it.
-#line 9
-allow dumpstate servicemanager:binder { call transfer };
-#line 9
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 9
-# all domains in domain.te.
-#line 9
-
-
-# Drop privileges by switching UID / GID
-allow dumpstate self:capability { setuid setgid };
-
-# Allow dumpstate to scan through /proc/pid for all processes
-
-#line 15
-allow dumpstate domain:dir { open getattr read search ioctl };
-#line 15
-allow dumpstate domain:{ file lnk_file } { getattr open read ioctl lock };
-#line 15
-
-
-# Send signals to processes
-allow dumpstate self:capability kill;
-
-# Allow executing files on system, such as:
-# /system/bin/toolbox
-# /system/bin/logcat
-# /system/bin/dumpsys
-allow dumpstate system_file:file execute_no_trans;
-
-# Create and write into /data/anr/
-allow dumpstate self:capability { dac_override chown fowner fsetid };
-allow dumpstate anr_data_file:dir { { { open getattr read search ioctl } { open search write add_name remove_name } } relabelto };
-allow dumpstate anr_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow dumpstate system_data_file:dir { { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } } relabelfrom };
-
-# Allow reading /data/system/uiderrors.txt
-# TODO: scope this down.
-allow dumpstate system_data_file:file { getattr open read ioctl lock };
-
-# Read dmesg
-allow dumpstate self:capability2 syslog;
-allow dumpstate kernel:system syslog_read;
-
-# Get process attributes
-allow dumpstate domain:process getattr;
-
-# Signal java processes to dump their stack
-allow dumpstate { appdomain system_server }:process signal;
-
-# Signal native processes to dump their stack.
-# This list comes from native_processes_to_dump in dumpstate/utils.c
-allow dumpstate { drmserver mediaserver sdcardd surfaceflinger }:process signal;
-
-# The /system/bin/ip command needs this for routing table information.
-allow dumpstate self:netlink_route_socket { write getattr setopt };
-
-# The vdc command needs to talk to the vold socket.
-
-#line 54
-allow dumpstate vold_socket:sock_file write;
-#line 54
-allow dumpstate vold:unix_stream_socket connectto;
-#line 54
-
-
-# Vibrate the device after we're done collecting the bugreport
-# /sys/class/timed_output/vibrator/enable
-# TODO: create a new file class, instead of allowing write access to all of /sys
-allow dumpstate sysfs:file { open append write };
-
-# Other random bits of data we want to collect
-allow dumpstate qtaguid_proc:file { getattr open read ioctl lock };
-allow dumpstate debugfs:file { getattr open read ioctl lock };
-
-# Allow dumpstate to make binder calls to any binder service
-
-#line 66
-# Call the server domain and optionally transfer references to it.
-#line 66
-allow dumpstate binderservicedomain:binder { call transfer };
-#line 66
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 66
-allow binderservicedomain dumpstate:binder transfer;
-#line 66
-# Receive and use open files from the server.
-#line 66
-allow dumpstate binderservicedomain:fd use;
-#line 66
-
-
-#line 67
-# Call the server domain and optionally transfer references to it.
-#line 67
-allow dumpstate appdomain:binder { call transfer };
-#line 67
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 67
-allow appdomain dumpstate:binder transfer;
-#line 67
-# Receive and use open files from the server.
-#line 67
-allow dumpstate appdomain:fd use;
-#line 67
-
-
-# Reading /proc/PID/maps of other processes
-allow dumpstate self:capability sys_ptrace;
-
-# Allow the bugreport service to create a file in
-# /data/data/com.android.shell/files/bugreports/bugreport
-allow dumpstate shell_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow dumpstate shell_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Run a shell.
-allow dumpstate shell_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-
-# For running am and similar framework commands.
-# Run /system/bin/app_process.
-allow dumpstate zygote_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-# Dalvik Compiler JIT.
-allow dumpstate ashmem_device:chr_file execute;
-allow dumpstate dumpstate_tmpfs:file execute;
-allow dumpstate self:process execmem;
-# For art.
-allow dumpstate dalvikcache_data_file:file execute;
-
-# logd access
-
-#line 91
-
-#line 91
-allow dumpstate logdr_socket:sock_file write;
-#line 91
-allow dumpstate logd:unix_stream_socket connectto;
-#line 91
-
-#line 91
-
-
-#line 92
-# Group AID_LOG checked by filesystem & logd
-#line 92
-# to permit control commands
-#line 92
-
-#line 92
-allow dumpstate logd_socket:sock_file write;
-#line 92
-allow dumpstate logd:unix_stream_socket connectto;
-#line 92
-
-#line 92
-
-#line 1 "external/sepolicy/file.te"
-# Filesystem types
-type labeledfs, fs_type;
-type pipefs, fs_type;
-type sockfs, fs_type;
-type rootfs, fs_type;
-type proc, fs_type;
-# Security-sensitive proc nodes that should not be writable to most.
-type proc_security, fs_type;
-# proc, sysfs, or other nodes that permit configuration of kernel usermodehelpers.
-type usermodehelper, fs_type, sysfs_type;
-type qtaguid_proc, fs_type, mlstrustedobject;
-type proc_bluetooth_writable, fs_type;
-type proc_net, fs_type;
-type selinuxfs, fs_type;
-type cgroup, fs_type, mlstrustedobject;
-type sysfs, fs_type, mlstrustedobject;
-type sysfs_writable, fs_type, sysfs_type, mlstrustedobject;
-type sysfs_bluetooth_writable, fs_type, sysfs_type, mlstrustedobject;
-type sysfs_nfc_power_writable, fs_type, sysfs_type, mlstrustedobject;
-type sysfs_wake_lock, fs_type, sysfs_type;
-# /sys/devices/system/cpu
-type sysfs_devices_system_cpu, fs_type, sysfs_type;
-# /sys/module/lowmemorykiller
-type sysfs_lowmemorykiller, fs_type, sysfs_type;
-type inotify, fs_type, mlstrustedobject;
-type devpts, fs_type, mlstrustedobject;
-type tmpfs, fs_type;
-type shm, fs_type;
-type mqueue, fs_type;
-type sdcard_internal, sdcard_type, fs_type, mlstrustedobject;
-type sdcard_external, sdcard_type, fs_type, mlstrustedobject;
-type debugfs, fs_type, mlstrustedobject;
-
-# File types
-type unlabeled, file_type;
-# Default type for anything under /system.
-type system_file, file_type;
-# Default type for anything under /data.
-type system_data_file, file_type, data_file_type;
-# /data/drm - DRM plugin data
-type drm_data_file, file_type, data_file_type;
-# /data/anr - ANR traces
-type anr_data_file, file_type, data_file_type, mlstrustedobject;
-# /data/tombstones - core dumps
-type tombstone_data_file, file_type, data_file_type;
-# /data/app - user-installed apps
-type apk_data_file, file_type, data_file_type;
-type apk_tmp_file, file_type, data_file_type, mlstrustedobject;
-# /data/app-private - forward-locked apps
-type apk_private_data_file, file_type, data_file_type;
-type apk_private_tmp_file, file_type, data_file_type, mlstrustedobject;
-# /data/dalvik-cache
-type dalvikcache_data_file, file_type, data_file_type;
-# /data/local - writable by shell
-type shell_data_file, file_type, data_file_type;
-# /data/gps
-type gps_data_file, file_type, data_file_type;
-
-# /data/misc subdirectories
-type adb_keys_file, file_type, data_file_type;
-type audio_data_file, file_type, data_file_type;
-type bluetooth_data_file, file_type, data_file_type;
-type camera_data_file, file_type, data_file_type;
-type keystore_data_file, file_type, data_file_type;
-type media_data_file, file_type, data_file_type;
-type media_rw_data_file, file_type, data_file_type;
-type nfc_data_file, file_type, data_file_type;
-type radio_data_file, file_type, data_file_type;
-type systemkeys_data_file, file_type, data_file_type;
-type vpn_data_file, file_type, data_file_type;
-type wifi_data_file, file_type, data_file_type;
-type zoneinfo_data_file, file_type, data_file_type;
-
-# Compatibility with type names used in vanilla Android 4.3 and 4.4.
-typealias audio_data_file alias audio_firmware_file;
-# /data/data subdirectories - app sandboxes
-type app_data_file, file_type, data_file_type;
-type platform_app_data_file, file_type, data_file_type, mlstrustedobject;
-# Default type for anything under /cache
-type cache_file, file_type, mlstrustedobject;
-# Type for /cache/.*\.{data|restore} and default
-# type for anything under /cache/backup
-type cache_backup_file, file_type, mlstrustedobject;
-# Default type for anything under /efs
-type efs_file, file_type;
-# Type for wallpaper file.
-type wallpaper_file, file_type, mlstrustedobject;
-# /mnt/asec
-type asec_apk_file, file_type, data_file_type;
-# Elements of asec files (/mnt/asec) that are world readable
-type asec_public_file, file_type, data_file_type;
-# /data/app-asec
-type asec_image_file, file_type, data_file_type;
-# /data/backup and /data/secure/backup
-type backup_data_file, file_type, data_file_type, mlstrustedobject;
-# For /data/security
-type security_file, file_type;
-# All devices have bluetooth efs files. But they
-# vary per device, so this type is used in per
-# device policy
-type bluetooth_efs_file, file_type;
-# Downloaded files
-type download_file, file_type;
-
-# Socket types
-type adbd_socket, file_type;
-type bluetooth_socket, file_type;
-type dnsproxyd_socket, file_type, mlstrustedobject;
-type dumpstate_socket, file_type;
-type gps_socket, file_type;
-type installd_socket, file_type;
-type keystore_socket, file_type;
-type lmkd_socket, file_type;
-type logd_debug, file_type;
-type logd_socket, file_type;
-type logdr_socket, file_type;
-type logdw_socket, file_type;
-type mdns_socket, file_type;
-type netd_socket, file_type;
-type property_socket, file_type;
-type qemud_socket, file_type;
-type racoon_socket, file_type;
-type rild_socket, file_type;
-type rild_debug_socket, file_type;
-type system_wpa_socket, file_type;
-type system_ndebug_socket, file_type;
-type vold_socket, file_type;
-type wpa_socket, file_type;
-type zygote_socket, file_type;
-
-# UART (for GPS) control proc file
-type gps_control, file_type;
-
-# Allow files to be created in their appropriate filesystems.
-allow fs_type self:filesystem associate;
-allow sysfs_type sysfs:filesystem associate;
-allow file_type labeledfs:filesystem associate;
-allow file_type tmpfs:filesystem associate;
-allow file_type rootfs:filesystem associate;
-allow dev_type tmpfs:filesystem associate;
-#line 1 "external/sepolicy/gpsd.te"
-# gpsd - GPS daemon
-type gpsd, domain;
-
-#line 3
-typeattribute gpsd mlstrustedsubject;
-#line 3
-typeattribute gpsd unconfineddomain;
-#line 3
-
-type gpsd_exec, exec_type, file_type;
-
-
-#line 6
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow init gpsd_exec:file { getattr open read execute };
-#line 6
-allow init gpsd:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow gpsd gpsd_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow gpsd init:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit init gpsd:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow init gpsd:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition init gpsd_exec:process gpsd;
-#line 6
-
-#line 6
-
-#line 6
-type gpsd_tmpfs, file_type;
-#line 6
-type_transition gpsd tmpfs:file gpsd_tmpfs;
-#line 6
-allow gpsd gpsd_tmpfs:file { read write };
-#line 6
-
-#line 6
-
-
-#line 7
-typeattribute gpsd netdomain;
-#line 7
-
-allow gpsd gps_data_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow gpsd gps_data_file:{ file lnk_file sock_file fifo_file } { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-# Socket is created by the daemon, not by init, and under /data/gps,
-# not under /dev/socket.
-type_transition gpsd gps_data_file:sock_file gps_socket;
-allow gpsd gps_socket:sock_file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-# XXX Label sysfs files with a specific type?
-allow gpsd sysfs:file { { getattr open read ioctl lock } { open append write } };
-
-allow gpsd gps_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Execute the shell or system commands.
-allow gpsd shell_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-allow gpsd system_file:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-#line 1 "external/sepolicy/hci_attach.te"
-type hci_attach, domain;
-type hci_attach_exec, exec_type, file_type;
-
-
-#line 4
-
-#line 4
-# Allow the necessary permissions.
-#line 4
-
-#line 4
-# Old domain may exec the file and transition to the new domain.
-#line 4
-allow init hci_attach_exec:file { getattr open read execute };
-#line 4
-allow init hci_attach:process transition;
-#line 4
-# New domain is entered by executing the file.
-#line 4
-allow hci_attach hci_attach_exec:file { entrypoint read execute };
-#line 4
-# New domain can send SIGCHLD to its caller.
-#line 4
-allow hci_attach init:process sigchld;
-#line 4
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 4
-dontaudit init hci_attach:process noatsecure;
-#line 4
-# XXX dontaudit candidate but requires further study.
-#line 4
-allow init hci_attach:process { siginh rlimitinh };
-#line 4
-
-#line 4
-# Make the transition occur by default.
-#line 4
-type_transition init hci_attach_exec:process hci_attach;
-#line 4
-
-#line 4
-
-#line 4
-type hci_attach_tmpfs, file_type;
-#line 4
-type_transition hci_attach tmpfs:file hci_attach_tmpfs;
-#line 4
-allow hci_attach hci_attach_tmpfs:file { read write };
-#line 4
-
-#line 4
-
-
-allow hci_attach kernel:system module_request;
-allow hci_attach hci_attach_dev:chr_file { { getattr open read ioctl lock } { open append write } };
-allow hci_attach bluetooth_efs_file:dir { open getattr read search ioctl };
-allow hci_attach bluetooth_efs_file:file { getattr open read ioctl lock };
-#line 1 "external/sepolicy/healthd.te"
-# healthd seclabel is specified in init.rc since
-# it lives in the rootfs and has no unique file type.
-type healthd, domain;
-
-allow healthd rootfs:file { read entrypoint };
-
-#line 6
-type_transition healthd device:chr_file klog_device "__kmsg__";
-#line 6
-allow healthd klog_device:chr_file { create open write unlink };
-#line 6
-allow healthd device:dir { write add_name remove_name };
-#line 6
-
-# /dev/__null__ created by init prior to policy load,
-# open fd inherited by healthd.
-allow healthd tmpfs:chr_file { read write };
-
-allow healthd self:capability { net_admin mknod };
-allow healthd self:capability2 block_suspend;
-allow healthd self:netlink_kobject_uevent_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-
-#line 14
-# Call the servicemanager and transfer references to it.
-#line 14
-allow healthd servicemanager:binder { call transfer };
-#line 14
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 14
-# all domains in domain.te.
-#line 14
-
-
-#line 15
-typeattribute healthd binderservicedomain;
-#line 15
-
-
-#line 16
-# Call the server domain and optionally transfer references to it.
-#line 16
-allow healthd system_server:binder { call transfer };
-#line 16
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 16
-allow system_server healthd:binder transfer;
-#line 16
-# Receive and use open files from the server.
-#line 16
-allow healthd system_server:fd use;
-#line 16
-
-
-###
-### healthd: charger mode
-###
-
-allow healthd graphics_device:dir { open getattr read search ioctl };
-allow healthd graphics_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow healthd input_device:dir { open getattr read search ioctl };
-allow healthd input_device:chr_file { getattr open read ioctl lock };
-allow healthd ashmem_device:chr_file execute;
-allow healthd self:process execmem;
-#line 1 "external/sepolicy/hostapd.te"
-# userspace wifi access points
-type hostapd, domain;
-
-#line 3
-typeattribute hostapd mlstrustedsubject;
-#line 3
-typeattribute hostapd unconfineddomain;
-#line 3
-
-type hostapd_exec, exec_type, file_type;
-
-allow hostapd self:capability { net_admin net_raw setuid setgid };
-allow hostapd self:netlink_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-allow hostapd self:packet_socket { create write read };
-allow hostapd self:netlink_route_socket { bind create write nlmsg_write read };
-allow hostapd self:udp_socket { create ioctl };
-
-allow hostapd wifi_data_file:file { { getattr open read ioctl lock } { open append write } };
-allow hostapd wifi_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow hostapd wpa_socket:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow hostapd wpa_socket:sock_file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow hostapd netd:fd use;
-allow hostapd netd:udp_socket { read write };
-allow hostapd netd:netlink_kobject_uevent_socket { read write };
-allow hostapd netd:netlink_nflog_socket { read write };
-allow hostapd netd:netlink_route_socket { read write };
-allow hostapd netd:unix_stream_socket { read write };
-allow hostapd netd:fifo_file { read write };
-#line 1 "external/sepolicy/init_shell.te"
-# Restricted domain for shell processes spawned by init
-type init_shell, domain, shelldomain;
-
-#line 3
-# Allow the necessary permissions.
-#line 3
-
-#line 3
-# Old domain may exec the file and transition to the new domain.
-#line 3
-allow init shell_exec:file { getattr open read execute };
-#line 3
-allow init init_shell:process transition;
-#line 3
-# New domain is entered by executing the file.
-#line 3
-allow init_shell shell_exec:file { entrypoint read execute };
-#line 3
-# New domain can send SIGCHLD to its caller.
-#line 3
-allow init_shell init:process sigchld;
-#line 3
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 3
-dontaudit init init_shell:process noatsecure;
-#line 3
-# XXX dontaudit candidate but requires further study.
-#line 3
-allow init init_shell:process { siginh rlimitinh };
-#line 3
-
-#line 3
-# Make the transition occur by default.
-#line 3
-type_transition init shell_exec:process init_shell;
-#line 3
-
-
-#line 4
-typeattribute init_shell mlstrustedsubject;
-#line 4
-typeattribute init_shell unconfineddomain;
-#line 4
-
-
-# inherits from shelldomain.te
-#line 1 "external/sepolicy/init.te"
-# init switches to init domain (via init.rc).
-type init, domain;
-# init is unconfined.
-
-#line 4
-typeattribute init mlstrustedsubject;
-#line 4
-typeattribute init unconfineddomain;
-#line 4
-
-
-#line 5
-type init_tmpfs, file_type;
-#line 5
-type_transition init tmpfs:file init_tmpfs;
-#line 5
-allow init init_tmpfs:file { read write };
-#line 5
-
-
-#line 6
-typeattribute init relabeltodomain;
-#line 6
-
-# add a rule to handle unlabelled mounts
-allow init unlabeled:filesystem mount;
-
-allow init self:capability { sys_rawio mknod };
-
-allow init dev_type:blk_file { { getattr open read ioctl lock } { open append write } };
-allow init fs_type:filesystem *;
-allow init {fs_type dev_type file_type}:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } relabelto;
-allow init kernel:security load_policy;
-allow init usermodehelper:file { { getattr open read ioctl lock } { open append write } };
-allow init proc_security:file { { getattr open read ioctl lock } { open append write } };
-
-# Transitions to seclabel processes in init.rc
-allow init adbd:process transition;
-allow init healthd:process transition;
-allow init recovery:process transition;
-allow init shell:process transition;
-allow init ueventd:process transition;
-allow init watchdogd:process transition;
-#line 1 "external/sepolicy/inputflinger.te"
-# inputflinger
-type inputflinger, domain;
-
-#line 3
-typeattribute inputflinger mlstrustedsubject;
-#line 3
-typeattribute inputflinger unconfineddomain;
-#line 3
-
-type inputflinger_exec, exec_type, file_type;
-
-
-#line 6
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow init inputflinger_exec:file { getattr open read execute };
-#line 6
-allow init inputflinger:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow inputflinger inputflinger_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow inputflinger init:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit init inputflinger:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow init inputflinger:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition init inputflinger_exec:process inputflinger;
-#line 6
-
-#line 6
-
-#line 6
-type inputflinger_tmpfs, file_type;
-#line 6
-type_transition inputflinger tmpfs:file inputflinger_tmpfs;
-#line 6
-allow inputflinger inputflinger_tmpfs:file { read write };
-#line 6
-
-#line 6
-
-
-#line 7
-# Call the servicemanager and transfer references to it.
-#line 7
-allow inputflinger servicemanager:binder { call transfer };
-#line 7
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 7
-# all domains in domain.te.
-#line 7
-
-
-#line 8
-typeattribute inputflinger binderservicedomain;
-#line 8
-
-#line 1 "external/sepolicy/installd.te"
-# installer daemon
-type installd, domain;
-type installd_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init installd_exec:file { getattr open read execute };
-#line 5
-allow init installd:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow installd installd_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow installd init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init installd:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init installd:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init installd_exec:process installd;
-#line 5
-
-#line 5
-
-#line 5
-type installd_tmpfs, file_type;
-#line 5
-type_transition installd tmpfs:file installd_tmpfs;
-#line 5
-allow installd installd_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-
-#line 6
-typeattribute installd relabeltodomain;
-#line 6
-
-typeattribute installd mlstrustedsubject;
-allow installd self:capability { chown dac_override fowner fsetid setgid setuid };
-allow installd system_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow installd system_data_file:lnk_file create;
-allow installd dalvikcache_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow installd data_file_type:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow installd data_file_type:dir { relabelfrom relabelto };
-allow installd data_file_type:{ { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } { getattr unlink };
-allow installd apk_data_file:file { getattr open read ioctl lock };
-allow installd apk_tmp_file:file { getattr open read ioctl lock };
-allow installd system_file:file { getattr execute execute_no_trans };
-allow installd cgroup:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow installd download_file:dir { { open getattr read search ioctl } write remove_name };
-allow installd download_file:file { { getattr open read ioctl lock } unlink };
-dontaudit installd self:capability sys_admin;
-# Check validity of SELinux context before use.
-
-#line 23
-allow installd selinuxfs:dir { open getattr read search ioctl };
-#line 23
-allow installd selinuxfs:file { { getattr open read ioctl lock } { open append write } };
-#line 23
-allow installd kernel:security check_context;
-#line 23
-
-# Read /seapp_contexts and /data/security/seapp_contexts
-
-#line 25
-allow installd security_file:dir { open getattr read search ioctl };
-#line 25
-allow installd security_file:file { getattr open read ioctl lock };
-#line 25
-allow installd security_file:lnk_file { getattr open read ioctl lock };
-#line 25
-allow installd selinuxfs:dir { open getattr read search ioctl };
-#line 25
-allow installd selinuxfs:file { getattr open read ioctl lock };
-#line 25
-allow installd rootfs:dir { open getattr read search ioctl };
-#line 25
-allow installd rootfs:file { getattr open read ioctl lock };
-#line 25
-
-# ASEC
-allow installd platform_app_data_file:lnk_file { create setattr };
-allow installd app_data_file:lnk_file { create setattr };
-allow installd asec_apk_file:file { getattr open read ioctl lock };
-allow installd bluetooth_data_file:lnk_file { create setattr };
-allow installd nfc_data_file:lnk_file { create setattr };
-allow installd radio_data_file:lnk_file { create setattr };
-allow installd shell_data_file:lnk_file { create setattr };
-#line 1 "external/sepolicy/isolated_app.te"
-###
-### Services with isolatedProcess=true in their manifest.
-###
-### This file defines the rules for isolated apps. An "isolated
-### app" is an APP with UID between AID_ISOLATED_START (99000)
-### and AID_ISOLATED_END (99999).
-###
-### isolated_app includes all the appdomain rules, plus the
-### additional following rules:
-###
-
-type isolated_app, domain;
-
-#line 13
-typeattribute isolated_app appdomain;
-#line 13
-# Label ashmem objects with our own unique type.
-#line 13
-
-#line 13
-type isolated_app_tmpfs, file_type;
-#line 13
-type_transition isolated_app tmpfs:file isolated_app_tmpfs;
-#line 13
-allow isolated_app isolated_app_tmpfs:file { read write };
-#line 13
-
-#line 13
-# Map with PROT_EXEC.
-#line 13
-allow isolated_app isolated_app_tmpfs:file execute;
-#line 13
-
-
-# Already connected, unnamed sockets being passed over some other IPC
-# hence no sock_file or connectto permission. This appears to be how
-# Chrome works, may need to be updated as more apps using isolated services
-# are examined.
-allow isolated_app appdomain:unix_stream_socket { read write };
-
-allow isolated_app dalvikcache_data_file:file execute;
-allow isolated_app apk_data_file:dir getattr;
-#line 1 "external/sepolicy/kernel.te"
-# Life begins with the kernel.
-type kernel, domain;
-
-allow kernel init:process dyntransition;
-
-# The kernel is unconfined.
-
-#line 7
-typeattribute kernel mlstrustedsubject;
-#line 7
-typeattribute kernel unconfineddomain;
-#line 7
-
-
-#line 8
-typeattribute kernel relabeltodomain;
-#line 8
-
-
-allow kernel {fs_type dev_type file_type}:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } relabelto;
-allow kernel unlabeled:filesystem mount;
-allow kernel fs_type:filesystem *;
-
-# Initial setenforce by init prior to switching to init domain.
-allow kernel self:security setenforce;
-
-# Set checkreqprot by init.rc prior to switching to init domain.
-allow kernel self:security setcheckreqprot;
-
-# For operations performed by kernel or init prior to switching to init domain.
-## TODO: Investigate whether it is safe to remove these
-allow kernel self:capability { sys_rawio mknod };
-auditallow kernel self:capability { sys_rawio mknod };
-allow kernel dev_type:blk_file { { getattr open read ioctl lock } { open append write } };
-auditallow kernel dev_type:blk_file { { getattr open read ioctl lock } { open append write } };
-#line 1 "external/sepolicy/keystore.te"
-type keystore, domain;
-type keystore_exec, exec_type, file_type;
-
-# keystore daemon
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init keystore_exec:file { getattr open read execute };
-#line 5
-allow init keystore:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow keystore keystore_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow keystore init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init keystore:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init keystore:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init keystore_exec:process keystore;
-#line 5
-
-#line 5
-
-#line 5
-type keystore_tmpfs, file_type;
-#line 5
-type_transition keystore tmpfs:file keystore_tmpfs;
-#line 5
-allow keystore keystore_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-typeattribute keystore mlstrustedsubject;
-
-#line 7
-# Call the servicemanager and transfer references to it.
-#line 7
-allow keystore servicemanager:binder { call transfer };
-#line 7
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 7
-# all domains in domain.te.
-#line 7
-
-
-#line 8
-typeattribute keystore binderservicedomain;
-#line 8
-
-allow keystore keystore_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow keystore keystore_data_file:{ file lnk_file sock_file fifo_file } { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow keystore keystore_exec:file { getattr };
-allow keystore tee_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow keystore tee:unix_stream_socket connectto;
-#line 1 "external/sepolicy/lmkd.te"
-# lmkd low memory killer daemon
-type lmkd, domain;
-type lmkd_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init lmkd_exec:file { getattr open read execute };
-#line 5
-allow init lmkd:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow lmkd lmkd_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow lmkd init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init lmkd:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init lmkd:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init lmkd_exec:process lmkd;
-#line 5
-
-#line 5
-
-#line 5
-type lmkd_tmpfs, file_type;
-#line 5
-type_transition lmkd tmpfs:file lmkd_tmpfs;
-#line 5
-allow lmkd lmkd_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-
-allow lmkd self:capability { dac_override sys_resource };
-
-## Open and write to /proc/PID/oom_score_adj
-## TODO: maybe scope this down?
-
-#line 11
-allow lmkd appdomain:dir { open getattr read search ioctl };
-#line 11
-allow lmkd appdomain:{ file lnk_file } { getattr open read ioctl lock };
-#line 11
-
-allow lmkd appdomain:file write;
-
-#line 13
-allow lmkd system_server:dir { open getattr read search ioctl };
-#line 13
-allow lmkd system_server:{ file lnk_file } { getattr open read ioctl lock };
-#line 13
-
-allow lmkd system_server:file write;
-
-## Writes to /sys/module/lowmemorykiller/parameters/minfree
-allow lmkd sysfs_lowmemorykiller:file { open append write };
-#line 1 "external/sepolicy/logd.te"
-# android user-space log manager
-type logd, domain;
-type logd_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init logd_exec:file { getattr open read execute };
-#line 5
-allow init logd:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow logd logd_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow logd init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init logd:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init logd:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init logd_exec:process logd;
-#line 5
-
-#line 5
-
-#line 5
-type logd_tmpfs, file_type;
-#line 5
-type_transition logd tmpfs:file logd_tmpfs;
-#line 5
-allow logd logd_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-allow logd self:unix_stream_socket *;
-
-allow logd self:capability { setuid setgid sys_nice };
-
-
-#line 10
-allow logd domain:dir { open getattr read search ioctl };
-#line 10
-allow logd domain:{ file lnk_file } { getattr open read ioctl lock };
-#line 10
-
-
-#line 17
-
-
-###
-### Neverallow rules
-###
-### logd should NEVER do any of this
-
-# Block device access.
-neverallow logd dev_type:blk_file { read write };
-
-# ptrace any other app
-neverallow logd domain:process ptrace;
-
-# Write to /system.
-neverallow logd system_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } write;
-
-# Write to files in /data/data or system files on /data
-neverallow logd { app_data_file system_data_file }:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } write;
-#line 1 "external/sepolicy/media_app.te"
-###
-### Apps signed with the media key.
-###
-
-type media_app, domain;
-
-#line 6
-typeattribute media_app appdomain;
-#line 6
-# Label ashmem objects with our own unique type.
-#line 6
-
-#line 6
-type media_app_tmpfs, file_type;
-#line 6
-type_transition media_app tmpfs:file media_app_tmpfs;
-#line 6
-allow media_app media_app_tmpfs:file { read write };
-#line 6
-
-#line 6
-# Map with PROT_EXEC.
-#line 6
-allow media_app media_app_tmpfs:file execute;
-#line 6
-
-
-#line 7
-typeattribute media_app platformappdomain;
-#line 7
-typeattribute media_app mlstrustedsubject;
-#line 7
-
-
-#line 8
-typeattribute media_app binderservicedomain;
-#line 8
-
-# Access the network.
-
-#line 10
-typeattribute media_app netdomain;
-#line 10
-
-# Access /dev/mtp_usb.
-allow media_app mtp_device:chr_file { { getattr open read ioctl lock } { open append write } };
-# Write to /cache.
-allow media_app cache_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow media_app cache_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-# Stat /cache/lost+found
-allow media_app unlabeled:file getattr;
-allow media_app unlabeled:dir getattr;
-# Stat /cache/backup
-allow media_app cache_backup_file:file getattr;
-allow media_app cache_backup_file:dir getattr;
-# Read files in the rootdir (in particular, file_contexts for restorecon).
-allow media_app rootfs:file { getattr open read ioctl lock };
-allow media_app download_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow media_app download_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-# Allow platform apps to mark platform app data files as download files
-
-#line 27
-typeattribute media_app relabeltodomain;
-#line 27
-
-allow media_app platform_app_data_file:dir relabelfrom;
-allow media_app download_file:dir relabelto;
-#line 1 "external/sepolicy/mediaserver.te"
-# mediaserver - multimedia daemon
-type mediaserver, domain;
-
-#line 3
-typeattribute mediaserver mlstrustedsubject;
-#line 3
-typeattribute mediaserver unconfineddomain;
-#line 3
-
-type mediaserver_exec, exec_type, file_type;
-
-typeattribute mediaserver mlstrustedsubject;
-
-
-#line 8
-typeattribute mediaserver netdomain;
-#line 8
-
-
-#line 9
-
-#line 9
-# Allow the necessary permissions.
-#line 9
-
-#line 9
-# Old domain may exec the file and transition to the new domain.
-#line 9
-allow init mediaserver_exec:file { getattr open read execute };
-#line 9
-allow init mediaserver:process transition;
-#line 9
-# New domain is entered by executing the file.
-#line 9
-allow mediaserver mediaserver_exec:file { entrypoint read execute };
-#line 9
-# New domain can send SIGCHLD to its caller.
-#line 9
-allow mediaserver init:process sigchld;
-#line 9
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 9
-dontaudit init mediaserver:process noatsecure;
-#line 9
-# XXX dontaudit candidate but requires further study.
-#line 9
-allow init mediaserver:process { siginh rlimitinh };
-#line 9
-
-#line 9
-# Make the transition occur by default.
-#line 9
-type_transition init mediaserver_exec:process mediaserver;
-#line 9
-
-#line 9
-
-#line 9
-type mediaserver_tmpfs, file_type;
-#line 9
-type_transition mediaserver tmpfs:file mediaserver_tmpfs;
-#line 9
-allow mediaserver mediaserver_tmpfs:file { read write };
-#line 9
-
-#line 9
-
-
-#line 10
-allow mediaserver property_socket:sock_file write;
-#line 10
-allow mediaserver init:unix_stream_socket connectto;
-#line 10
-
-
-
-#line 12
-allow mediaserver sdcard_type:dir { open getattr read search ioctl };
-#line 12
-allow mediaserver sdcard_type:{ file lnk_file } { getattr open read ioctl lock };
-#line 12
-
-
-
-#line 14
-# Call the servicemanager and transfer references to it.
-#line 14
-allow mediaserver servicemanager:binder { call transfer };
-#line 14
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 14
-# all domains in domain.te.
-#line 14
-
-
-#line 15
-# Call the server domain and optionally transfer references to it.
-#line 15
-allow mediaserver binderservicedomain:binder { call transfer };
-#line 15
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 15
-allow binderservicedomain mediaserver:binder transfer;
-#line 15
-# Receive and use open files from the server.
-#line 15
-allow mediaserver binderservicedomain:fd use;
-#line 15
-
-
-#line 16
-# Call the server domain and optionally transfer references to it.
-#line 16
-allow mediaserver appdomain:binder { call transfer };
-#line 16
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 16
-allow appdomain mediaserver:binder transfer;
-#line 16
-# Receive and use open files from the server.
-#line 16
-allow mediaserver appdomain:fd use;
-#line 16
-
-
-#line 17
-typeattribute mediaserver binderservicedomain;
-#line 17
-
-
-allow mediaserver self:process execmem;
-allow mediaserver kernel:system module_request;
-allow mediaserver media_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow mediaserver media_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow mediaserver app_data_file:dir search;
-allow mediaserver app_data_file:file { { getattr open read ioctl lock } { open append write } };
-allow mediaserver platform_app_data_file:file { getattr read };
-allow mediaserver sdcard_type:file write;
-allow mediaserver { gpu_device graphics_device }:chr_file { { getattr open read ioctl lock } { open append write } };
-allow mediaserver video_device:dir { open getattr read search ioctl };
-allow mediaserver video_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow mediaserver audio_device:dir { open getattr read search ioctl };
-allow mediaserver qemu_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow mediaserver tee_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow mediaserver audio_prop:property_service set;
-
-# Access audio devices at all.
-allow mediaserver audio_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# XXX Label with a specific type?
-allow mediaserver sysfs:file { { getattr open read ioctl lock } { open append write } };
-
-# XXX Why?
-allow mediaserver apk_data_file:file { read getattr };
-
-# Access camera device.
-allow mediaserver camera_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow mediaserver rpmsg_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Inter System processes communicate over named pipe (FIFO)
-allow mediaserver system_server:fifo_file { getattr open read ioctl lock };
-
-# Camera data
-
-#line 52
-allow mediaserver camera_data_file:dir { open getattr read search ioctl };
-#line 52
-allow mediaserver camera_data_file:{ file lnk_file } { getattr open read ioctl lock };
-#line 52
-
-
-#line 53
-allow mediaserver media_rw_data_file:dir { open getattr read search ioctl };
-#line 53
-allow mediaserver media_rw_data_file:{ file lnk_file } { getattr open read ioctl lock };
-#line 53
-
-
-# Grant access to audio files to mediaserver
-allow mediaserver audio_data_file:dir { { open getattr read search ioctl } add_name write };
-allow mediaserver audio_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Read/[write] to /proc/net/xt_qtaguid/ctrl and /dev/xt_qtaguid
-allow mediaserver qtaguid_proc:file { { getattr open read ioctl lock } { open append write } };
-allow mediaserver qtaguid_device:chr_file { getattr open read ioctl lock };
-
-# Allow abstract socket connection
-allow mediaserver rild:unix_stream_socket { connectto read write setopt };
-
-# Needed on some devices for playing DRM protected content,
-# but seems expected and appropriate for all devices.
-
-#line 68
-allow mediaserver drmserver_socket:sock_file write;
-#line 68
-allow mediaserver drmserver:unix_stream_socket connectto;
-#line 68
-
-
-# Needed on some devices for playing audio on paired BT device,
-# but seems appropriate for all devices.
-
-#line 72
-allow mediaserver bluetooth_socket:sock_file write;
-#line 72
-allow mediaserver bluetooth:unix_stream_socket connectto;
-#line 72
-
-#line 1 "external/sepolicy/mtp.te"
-# vpn tunneling protocol manager
-type mtp, domain;
-
-#line 3
-typeattribute mtp mlstrustedsubject;
-#line 3
-typeattribute mtp unconfineddomain;
-#line 3
-
-type mtp_exec, exec_type, file_type;
-
-
-#line 6
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow init mtp_exec:file { getattr open read execute };
-#line 6
-allow init mtp:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow mtp mtp_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow mtp init:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit init mtp:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow init mtp:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition init mtp_exec:process mtp;
-#line 6
-
-#line 6
-
-#line 6
-type mtp_tmpfs, file_type;
-#line 6
-type_transition mtp tmpfs:file mtp_tmpfs;
-#line 6
-allow mtp mtp_tmpfs:file { read write };
-#line 6
-
-#line 6
-
-
-#line 7
-typeattribute mtp netdomain;
-#line 7
-
-
-# pptp policy
-allow mtp self:tcp_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-allow mtp self:socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-allow mtp self:rawip_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-allow mtp self:capability net_raw;
-allow mtp ppp:process signal;
-allow mtp port:tcp_socket name_connect;
-allow mtp vpn_data_file:dir search;
-#line 1 "external/sepolicy/netd.te"
-# network manager
-type netd, domain;
-type netd_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init netd_exec:file { getattr open read execute };
-#line 5
-allow init netd:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow netd netd_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow netd init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init netd:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init netd:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init netd_exec:process netd;
-#line 5
-
-#line 5
-
-#line 5
-type netd_tmpfs, file_type;
-#line 5
-type_transition netd tmpfs:file netd_tmpfs;
-#line 5
-allow netd netd_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-
-#line 6
-typeattribute netd netdomain;
-#line 6
-
-
-allow netd self:capability { net_admin net_raw kill fsetid };
-allow netd self:netlink_kobject_uevent_socket *;
-allow netd self:netlink_route_socket *;
-allow netd self:netlink_nflog_socket *;
-allow netd self:rawip_socket *;
-allow netd self:unix_stream_socket *;
-allow netd shell_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-allow netd system_file:file { getattr execute execute_no_trans };
-allow netd devpts:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# For /proc/sys/net/ipv[46]/route/flush.
-allow netd proc_net:file write;
-
-# For /sys/modules/bcmdhd/parameters/firmware_path
-# XXX Split into its own type.
-allow netd sysfs:file write;
-
-# Set dhcp lease for PAN connection
-
-#line 26
-allow netd property_socket:sock_file write;
-#line 26
-allow netd init:unix_stream_socket connectto;
-#line 26
-
-allow netd system_prop:property_service set;
-
-# Connect to PAN
-
-#line 30
-# Allow the necessary permissions.
-#line 30
-
-#line 30
-# Old domain may exec the file and transition to the new domain.
-#line 30
-allow netd dhcp_exec:file { getattr open read execute };
-#line 30
-allow netd dhcp:process transition;
-#line 30
-# New domain is entered by executing the file.
-#line 30
-allow dhcp dhcp_exec:file { entrypoint read execute };
-#line 30
-# New domain can send SIGCHLD to its caller.
-#line 30
-allow dhcp netd:process sigchld;
-#line 30
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 30
-dontaudit netd dhcp:process noatsecure;
-#line 30
-# XXX dontaudit candidate but requires further study.
-#line 30
-allow netd dhcp:process { siginh rlimitinh };
-#line 30
-
-#line 30
-# Make the transition occur by default.
-#line 30
-type_transition netd dhcp_exec:process dhcp;
-#line 30
-
-allow netd dhcp:process signal;
-
-# Needed to update /data/misc/wifi/hostapd.conf
-# TODO: See what we can do to reduce the need for
-# these capabilities
-allow netd self:capability { dac_override chown fowner };
-allow netd wifi_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow netd wifi_data_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-
-# Allow netd to spawn hostapd in it's own domain
-
-#line 41
-# Allow the necessary permissions.
-#line 41
-
-#line 41
-# Old domain may exec the file and transition to the new domain.
-#line 41
-allow netd hostapd_exec:file { getattr open read execute };
-#line 41
-allow netd hostapd:process transition;
-#line 41
-# New domain is entered by executing the file.
-#line 41
-allow hostapd hostapd_exec:file { entrypoint read execute };
-#line 41
-# New domain can send SIGCHLD to its caller.
-#line 41
-allow hostapd netd:process sigchld;
-#line 41
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 41
-dontaudit netd hostapd:process noatsecure;
-#line 41
-# XXX dontaudit candidate but requires further study.
-#line 41
-allow netd hostapd:process { siginh rlimitinh };
-#line 41
-
-#line 41
-# Make the transition occur by default.
-#line 41
-type_transition netd hostapd_exec:process hostapd;
-#line 41
-
-allow netd hostapd:process signal;
-
-# Allow netd to spawn dnsmasq in it's own domain
-
-#line 45
-# Allow the necessary permissions.
-#line 45
-
-#line 45
-# Old domain may exec the file and transition to the new domain.
-#line 45
-allow netd dnsmasq_exec:file { getattr open read execute };
-#line 45
-allow netd dnsmasq:process transition;
-#line 45
-# New domain is entered by executing the file.
-#line 45
-allow dnsmasq dnsmasq_exec:file { entrypoint read execute };
-#line 45
-# New domain can send SIGCHLD to its caller.
-#line 45
-allow dnsmasq netd:process sigchld;
-#line 45
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 45
-dontaudit netd dnsmasq:process noatsecure;
-#line 45
-# XXX dontaudit candidate but requires further study.
-#line 45
-allow netd dnsmasq:process { siginh rlimitinh };
-#line 45
-
-#line 45
-# Make the transition occur by default.
-#line 45
-type_transition netd dnsmasq_exec:process dnsmasq;
-#line 45
-
-allow netd dnsmasq:process signal;
-
-# Allow netd to start clatd in its own domain
-
-#line 49
-# Allow the necessary permissions.
-#line 49
-
-#line 49
-# Old domain may exec the file and transition to the new domain.
-#line 49
-allow netd clatd_exec:file { getattr open read execute };
-#line 49
-allow netd clatd:process transition;
-#line 49
-# New domain is entered by executing the file.
-#line 49
-allow clatd clatd_exec:file { entrypoint read execute };
-#line 49
-# New domain can send SIGCHLD to its caller.
-#line 49
-allow clatd netd:process sigchld;
-#line 49
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 49
-dontaudit netd clatd:process noatsecure;
-#line 49
-# XXX dontaudit candidate but requires further study.
-#line 49
-allow netd clatd:process { siginh rlimitinh };
-#line 49
-
-#line 49
-# Make the transition occur by default.
-#line 49
-type_transition netd clatd_exec:process clatd;
-#line 49
-
-allow netd clatd:process signal;
-
-# Support netd running mdnsd
-# TODO: prune this back further
-allow netd ctl_default_prop:property_service set;
-allow netd device:sock_file write;
-
-###
-### Neverallow rules
-###
-### netd should NEVER do any of this
-
-# Block device access.
-neverallow netd dev_type:blk_file { read write };
-
-# Setting SELinux enforcing status or booleans.
-neverallow netd kernel:security { setenforce setbool };
-
-# Load security policy.
-neverallow netd kernel:security load_policy;
-
-# ptrace any other app
-neverallow netd { domain }:process ptrace;
-
-# Write to /system.
-neverallow netd system_file:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } write;
-
-# Write to files in /data/data or system files on /data
-neverallow netd { app_data_file system_data_file }:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } write;
-#line 1 "external/sepolicy/net.te"
-# Network types
-type node, node_type;
-type netif, netif_type;
-type port, port_type;
-
-# Use network sockets.
-allow netdomain self:{ tcp_socket udp_socket } *;
-# Connect to ports.
-allow netdomain port_type:tcp_socket name_connect;
-# Bind to ports.
-allow netdomain node_type:{ tcp_socket udp_socket } node_bind;
-allow netdomain port_type:udp_socket name_bind;
-allow netdomain port_type:tcp_socket name_bind;
-# Get route information.
-allow netdomain self:netlink_route_socket { create bind read nlmsg_read };
-
-# Talks to netd via dnsproxyd socket.
-
-#line 18
-allow netdomain dnsproxyd_socket:sock_file write;
-#line 18
-allow netdomain netd:unix_stream_socket connectto;
-#line 18
-
-#line 1 "external/sepolicy/nfc.te"
-# nfc subsystem
-type nfc, domain;
-
-#line 3
-typeattribute nfc appdomain;
-#line 3
-# Label ashmem objects with our own unique type.
-#line 3
-
-#line 3
-type nfc_tmpfs, file_type;
-#line 3
-type_transition nfc tmpfs:file nfc_tmpfs;
-#line 3
-allow nfc nfc_tmpfs:file { read write };
-#line 3
-
-#line 3
-# Map with PROT_EXEC.
-#line 3
-allow nfc nfc_tmpfs:file execute;
-#line 3
-
-
-#line 4
-typeattribute nfc binderservicedomain;
-#line 4
-
-
-# NFC device access.
-allow nfc nfc_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Data file accesses.
-allow nfc nfc_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow nfc nfc_data_file:{ file lnk_file sock_file fifo_file } { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-allow nfc sysfs_nfc_power_writable:file { { getattr open read ioctl lock } { open append write } };
-allow nfc sysfs:file write;
-
-allow nfc sdcard_type:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow nfc sdcard_type:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-#line 1 "external/sepolicy/platform_app.te"
-###
-### Apps signed with the platform key.
-###
-
-type platform_app, domain;
-
-#line 6
-typeattribute platform_app mlstrustedsubject;
-#line 6
-typeattribute platform_app unconfineddomain;
-#line 6
-
-
-#line 7
-typeattribute platform_app appdomain;
-#line 7
-# Label ashmem objects with our own unique type.
-#line 7
-
-#line 7
-type platform_app_tmpfs, file_type;
-#line 7
-type_transition platform_app tmpfs:file platform_app_tmpfs;
-#line 7
-allow platform_app platform_app_tmpfs:file { read write };
-#line 7
-
-#line 7
-# Map with PROT_EXEC.
-#line 7
-allow platform_app platform_app_tmpfs:file execute;
-#line 7
-
-
-#line 8
-typeattribute platform_app platformappdomain;
-#line 8
-typeattribute platform_app mlstrustedsubject;
-#line 8
-
-# Access the network.
-
-#line 10
-typeattribute platform_app netdomain;
-#line 10
-
-# Access bluetooth.
-
-#line 12
-typeattribute platform_app bluetoothdomain;
-#line 12
-
-# Write to /cache.
-allow platform_app cache_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow platform_app cache_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-# Read from /data/local.
-allow platform_app shell_data_file:dir search;
-allow platform_app shell_data_file:file { open getattr read };
-allow platform_app shell_data_file:lnk_file read;
-# Populate /data/app/vmdl*.tmp, /data/app-private/vmdl*.tmp files
-# created by system server.
-allow platform_app { apk_tmp_file apk_private_tmp_file }:file { { getattr open read ioctl lock } { open append write } };
-allow platform_app apk_private_data_file:dir search;
-# ASEC
-allow platform_app asec_apk_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow platform_app asec_apk_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-# Access download files.
-allow platform_app download_file:file { { getattr open read ioctl lock } { open append write } };
-# Allow BackupManagerService to backup all app domains
-allow platform_app appdomain:fifo_file write;
-
-#
-# Rules for all platform app domains.
-#
-
-# App sandbox file accesses.
-allow platformappdomain platform_app_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow platformappdomain platform_app_data_file:{ file lnk_file sock_file fifo_file } { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow platformappdomain platform_app_data_file:file execute;
-# App sdcard file accesses
-allow platformappdomain sdcard_type:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow platformappdomain sdcard_type:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-# Access to /data/media.
-allow platformappdomain media_rw_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow platformappdomain media_rw_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-#line 1 "external/sepolicy/ppp.te"
-# Point to Point Protocol daemon
-type ppp, domain;
-
-#line 3
-typeattribute ppp mlstrustedsubject;
-#line 3
-typeattribute ppp unconfineddomain;
-#line 3
-
-type ppp_device, dev_type;
-type ppp_exec, exec_type, file_type;
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow mtp ppp_exec:file { getattr open read execute };
-#line 6
-allow mtp ppp:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow ppp ppp_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow ppp mtp:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit mtp ppp:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow mtp ppp:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition mtp ppp_exec:process ppp;
-#line 6
-
-
-allow ppp mtp:socket { ioctl read getattr write setattr append bind connect getopt setopt shutdown };
-allow ppp ppp_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow ppp self:capability net_admin;
-allow ppp self:udp_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-allow ppp system_file:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-allow ppp vpn_data_file:dir { open search write add_name remove_name };
-allow ppp vpn_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow ppp mtp:fd use;
-#line 1 "external/sepolicy/property.te"
-type default_prop, property_type;
-type shell_prop, property_type;
-type debug_prop, property_type;
-type debuggerd_prop, property_type;
-type radio_prop, property_type;
-type system_prop, property_type;
-type vold_prop, property_type;
-type rild_prop, property_type;
-type ctl_default_prop, property_type;
-type ctl_dumpstate_prop, property_type;
-type ctl_rildaemon_prop, property_type;
-type audio_prop, property_type;
-type security_prop, property_type;
-type bluetooth_prop, property_type;
-type powerctl_prop, property_type;
-#line 1 "external/sepolicy/qemud.te"
-# qemu support daemon
-type qemud, domain;
-type qemud_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init qemud_exec:file { getattr open read execute };
-#line 5
-allow init qemud:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow qemud qemud_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow qemud init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init qemud:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init qemud:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init qemud_exec:process qemud;
-#line 5
-
-#line 5
-
-#line 5
-type qemud_tmpfs, file_type;
-#line 5
-type_transition qemud tmpfs:file qemud_tmpfs;
-#line 5
-allow qemud qemud_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-
-#line 6
-typeattribute qemud mlstrustedsubject;
-#line 6
-typeattribute qemud unconfineddomain;
-#line 1 "external/sepolicy/racoon.te"
-# IKE key management daemon
-type racoon, domain;
-
-#line 3
-typeattribute racoon mlstrustedsubject;
-#line 3
-typeattribute racoon unconfineddomain;
-#line 3
-
-type racoon_exec, exec_type, file_type;
-
-
-#line 6
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow init racoon_exec:file { getattr open read execute };
-#line 6
-allow init racoon:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow racoon racoon_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow racoon init:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit init racoon:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow init racoon:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition init racoon_exec:process racoon;
-#line 6
-
-#line 6
-
-#line 6
-type racoon_tmpfs, file_type;
-#line 6
-type_transition racoon tmpfs:file racoon_tmpfs;
-#line 6
-allow racoon racoon_tmpfs:file { read write };
-#line 6
-
-#line 6
-
-typeattribute racoon mlstrustedsubject;
-
-
-#line 9
-# Call the server domain and optionally transfer references to it.
-#line 9
-allow racoon servicemanager:binder { call transfer };
-#line 9
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 9
-allow servicemanager racoon:binder transfer;
-#line 9
-# Receive and use open files from the server.
-#line 9
-allow racoon servicemanager:fd use;
-#line 9
-
-
-#line 10
-# Call the server domain and optionally transfer references to it.
-#line 10
-allow racoon keystore:binder { call transfer };
-#line 10
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 10
-allow keystore racoon:binder transfer;
-#line 10
-# Receive and use open files from the server.
-#line 10
-allow racoon keystore:fd use;
-#line 10
-
-
-allow racoon tun_device:chr_file { getattr open read ioctl lock };
-allow racoon cgroup:dir { add_name create };
-allow racoon kernel:system module_request;
-allow racoon port:udp_socket name_bind;
-allow racoon node:udp_socket node_bind;
-
-allow racoon self:{ key_socket udp_socket } { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-allow racoon self:tun_socket create;
-allow racoon self:capability { net_admin net_bind_service net_raw setuid };
-
-# XXX: should we give ip-up-vpn its own label (currently racoon domain)
-allow racoon system_file:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-allow racoon vpn_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow racoon vpn_data_file:dir { open search write add_name remove_name };
-#line 1 "external/sepolicy/radio.te"
-# phone subsystem
-type radio, domain;
-
-#line 3
-typeattribute radio appdomain;
-#line 3
-# Label ashmem objects with our own unique type.
-#line 3
-
-#line 3
-type radio_tmpfs, file_type;
-#line 3
-type_transition radio tmpfs:file radio_tmpfs;
-#line 3
-allow radio radio_tmpfs:file { read write };
-#line 3
-
-#line 3
-# Map with PROT_EXEC.
-#line 3
-allow radio radio_tmpfs:file execute;
-#line 3
-
-
-#line 4
-typeattribute radio netdomain;
-#line 4
-
-
-#line 5
-typeattribute radio bluetoothdomain;
-#line 5
-
-
-#line 6
-typeattribute radio binderservicedomain;
-#line 6
-
-
-# Talks to init via the property socket.
-
-#line 9
-allow radio property_socket:sock_file write;
-#line 9
-allow radio init:unix_stream_socket connectto;
-#line 9
-
-
-# Talks to rild via the rild socket.
-
-#line 12
-allow radio rild_socket:sock_file write;
-#line 12
-allow radio rild:unix_stream_socket connectto;
-#line 12
-
-
-# Data file accesses.
-allow radio radio_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow radio radio_data_file:{ file lnk_file sock_file fifo_file } { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-allow radio alarm_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Property service
-allow radio radio_prop:property_service set;
-
-# ctl interface
-allow radio ctl_rildaemon_prop:property_service set;
-#line 1 "external/sepolicy/recovery.te"
-# recovery console (used in recovery init.rc for /sbin/recovery)
-type recovery, domain;
-allow recovery rootfs:file entrypoint;
-
-#line 4
-typeattribute recovery mlstrustedsubject;
-#line 4
-typeattribute recovery unconfineddomain;
-#line 4
-
-
-#line 5
-typeattribute recovery relabeltodomain;
-#line 5
-
-
-allow recovery self:capability2 mac_admin;
-
-allow recovery {fs_type dev_type -kmem_device file_type}:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } relabelto;
-allow recovery unlabeled:filesystem mount;
-allow recovery fs_type:filesystem *;
-
-# Required to e.g. wipe userdata/cache.
-allow recovery dev_type:blk_file { { getattr open read ioctl lock } { open append write } };
-
-allow recovery self:process execmem;
-allow recovery ashmem_device:chr_file execute;
-allow recovery tmpfs:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-
-## TODO: Investigate whether it is safe to remove these
-allow recovery self:capability { sys_rawio mknod };
-auditallow recovery self:capability { sys_rawio mknod };
-#line 1 "external/sepolicy/release_app.te"
-###
-### Apps signed with the release key (testkey in AOSP).
-###
-
-type release_app, domain;
-
-#line 6
-typeattribute release_app mlstrustedsubject;
-#line 6
-typeattribute release_app unconfineddomain;
-#line 6
-
-
-#line 7
-typeattribute release_app appdomain;
-#line 7
-# Label ashmem objects with our own unique type.
-#line 7
-
-#line 7
-type release_app_tmpfs, file_type;
-#line 7
-type_transition release_app tmpfs:file release_app_tmpfs;
-#line 7
-allow release_app release_app_tmpfs:file { read write };
-#line 7
-
-#line 7
-# Map with PROT_EXEC.
-#line 7
-allow release_app release_app_tmpfs:file execute;
-#line 7
-
-
-#line 8
-typeattribute release_app platformappdomain;
-#line 8
-typeattribute release_app mlstrustedsubject;
-#line 8
-
-# Access the network.
-
-#line 10
-typeattribute release_app netdomain;
-#line 10
-
-# Access bluetooth.
-
-#line 12
-typeattribute release_app bluetoothdomain;
-#line 12
-
-
-# Write to /cache.
-allow release_app cache_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow release_app cache_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-#line 1 "external/sepolicy/rild.te"
-# rild - radio interface layer daemon
-type rild, domain;
-
-#line 3
-typeattribute rild mlstrustedsubject;
-#line 3
-typeattribute rild unconfineddomain;
-#line 3
-
-type rild_exec, exec_type, file_type;
-
-
-#line 6
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow init rild_exec:file { getattr open read execute };
-#line 6
-allow init rild:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow rild rild_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow rild init:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit init rild:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow init rild:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition init rild_exec:process rild;
-#line 6
-
-#line 6
-
-#line 6
-type rild_tmpfs, file_type;
-#line 6
-type_transition rild tmpfs:file rild_tmpfs;
-#line 6
-allow rild rild_tmpfs:file { read write };
-#line 6
-
-#line 6
-
-
-#line 7
-typeattribute rild netdomain;
-#line 7
-
-allow rild self:netlink_route_socket { setopt write };
-allow rild kernel:system module_request;
-
-#line 10
-allow rild property_socket:sock_file write;
-#line 10
-allow rild init:unix_stream_socket connectto;
-#line 10
-
-
-#line 11
-allow rild qemud_socket:sock_file write;
-#line 11
-allow rild qemud:unix_stream_socket connectto;
-#line 11
-
-allow rild self:capability { setuid net_admin net_raw };
-allow rild alarm_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow rild cgroup:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow rild radio_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow rild radio_device:blk_file { getattr open read ioctl lock };
-allow rild qemu_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow rild mtd_device:dir search;
-allow rild efs_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow rild efs_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow rild shell_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-allow rild bluetooth_efs_file:file { getattr open read ioctl lock };
-allow rild bluetooth_efs_file:dir { open getattr read search ioctl };
-allow rild radio_data_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow rild radio_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow rild sdcard_type:dir { open getattr read search ioctl };
-allow rild system_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow rild system_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow rild system_file:file { getattr execute execute_no_trans };
-dontaudit rild self:capability sys_admin;
-
-# property service
-allow rild rild_prop:property_service set;
-allow rild radio_prop:property_service set;
-
-# Read/Write to uart driver (for GPS)
-allow rild gps_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-allow rild tty_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Allow rild to create, bind, read, write to itself through a netlink socket
-allow rild self:netlink_socket { create bind read write };
-
-allow rild self:netlink_kobject_uevent_socket { bind create getopt read setopt };
-
-# Access to wake locks
-allow rild sysfs_wake_lock:file { { getattr open read ioctl lock } { open append write } };
-
-allow rild self:socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } };
-#line 1 "external/sepolicy/runas.te"
-type runas, domain, mlstrustedsubject;
-type runas_exec, exec_type, file_type;
-
-# ndk-gdb invokes adb shell run-as.
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow shell runas_exec:file { getattr open read execute };
-#line 5
-allow shell runas:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow runas runas_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow runas shell:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit shell runas:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow shell runas:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition shell runas_exec:process runas;
-#line 5
-
-allow runas adbd:process sigchld;
-allow runas shell:fd use;
-allow runas devpts:chr_file { read write ioctl };
-
-# run-as reads package information.
-allow runas system_data_file:file { getattr open read ioctl lock };
-
-# run-as checks and changes to the app data dir.
-dontaudit runas self:capability dac_override;
-allow runas app_data_file:dir { getattr search };
-
-# run-as switches to the app UID/GID.
-allow runas self:capability { setuid setgid };
-
-# run-as switches to the app security context.
-# read /seapp_contexts and /data/security/seapp_contexts
-
-#line 22
-allow runas security_file:dir { open getattr read search ioctl };
-#line 22
-allow runas security_file:file { getattr open read ioctl lock };
-#line 22
-allow runas security_file:lnk_file { getattr open read ioctl lock };
-#line 22
-allow runas selinuxfs:dir { open getattr read search ioctl };
-#line 22
-allow runas selinuxfs:file { getattr open read ioctl lock };
-#line 22
-allow runas rootfs:dir { open getattr read search ioctl };
-#line 22
-allow runas rootfs:file { getattr open read ioctl lock };
-#line 22
-
-
-#line 23
-allow runas selinuxfs:dir { open getattr read search ioctl };
-#line 23
-allow runas selinuxfs:file { { getattr open read ioctl lock } { open append write } };
-#line 23
-allow runas kernel:security check_context;
-#line 23
- # validate context
-allow runas { appdomain -system_app }:process dyntransition; # setcon
-#line 1 "external/sepolicy/sdcardd.te"
-type sdcardd, domain;
-type sdcardd_exec, exec_type, file_type;
-
-
-#line 4
-
-#line 4
-# Allow the necessary permissions.
-#line 4
-
-#line 4
-# Old domain may exec the file and transition to the new domain.
-#line 4
-allow init sdcardd_exec:file { getattr open read execute };
-#line 4
-allow init sdcardd:process transition;
-#line 4
-# New domain is entered by executing the file.
-#line 4
-allow sdcardd sdcardd_exec:file { entrypoint read execute };
-#line 4
-# New domain can send SIGCHLD to its caller.
-#line 4
-allow sdcardd init:process sigchld;
-#line 4
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 4
-dontaudit init sdcardd:process noatsecure;
-#line 4
-# XXX dontaudit candidate but requires further study.
-#line 4
-allow init sdcardd:process { siginh rlimitinh };
-#line 4
-
-#line 4
-# Make the transition occur by default.
-#line 4
-type_transition init sdcardd_exec:process sdcardd;
-#line 4
-
-#line 4
-
-#line 4
-type sdcardd_tmpfs, file_type;
-#line 4
-type_transition sdcardd tmpfs:file sdcardd_tmpfs;
-#line 4
-allow sdcardd sdcardd_tmpfs:file { read write };
-#line 4
-
-#line 4
-
-
-allow sdcardd cgroup:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow sdcardd fuse_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow sdcardd rootfs:dir mounton;
-allow sdcardd sdcard_type:filesystem mount;
-allow sdcardd self:capability { setuid setgid dac_override sys_admin sys_resource };
-
-allow sdcardd sdcard_type:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow sdcardd sdcard_type:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-type_transition sdcardd system_data_file:{ dir file } media_rw_data_file;
-allow sdcardd media_rw_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow sdcardd media_rw_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Read /data/system/packages.list.
-allow sdcardd system_data_file:file { getattr open read ioctl lock };
-
-# Compatibility for existing devices with /data/media in system_data_file.
-# TODO: Remove these lines after we have guaranteed that /data/media has been relabeled to media_rw_data_file.
-allow sdcardd system_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow sdcardd system_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-#line 1 "external/sepolicy/servicemanager.te"
-# servicemanager - the Binder context manager
-type servicemanager, domain;
-type servicemanager_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init servicemanager_exec:file { getattr open read execute };
-#line 5
-allow init servicemanager:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow servicemanager servicemanager_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow servicemanager init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init servicemanager:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init servicemanager:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init servicemanager_exec:process servicemanager;
-#line 5
-
-#line 5
-
-#line 5
-type servicemanager_tmpfs, file_type;
-#line 5
-type_transition servicemanager tmpfs:file servicemanager_tmpfs;
-#line 5
-allow servicemanager servicemanager_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-
-# Note that we do not use the binder_* macros here.
-# servicemanager is unique in that it only provides
-# name service (aka context manager) for Binder.
-# As such, it only ever receives and transfers other references
-# created by other domains. It never passes its own references
-# or initiates a Binder IPC.
-allow servicemanager self:binder set_context_mgr;
-allow servicemanager domain:binder transfer;
-#line 1 "external/sepolicy/shared_app.te"
-###
-### Apps signed with the shared key.
-###
-
-type shared_app, domain;
-
-#line 6
-typeattribute shared_app mlstrustedsubject;
-#line 6
-typeattribute shared_app unconfineddomain;
-#line 6
-
-
-#line 7
-typeattribute shared_app appdomain;
-#line 7
-# Label ashmem objects with our own unique type.
-#line 7
-
-#line 7
-type shared_app_tmpfs, file_type;
-#line 7
-type_transition shared_app tmpfs:file shared_app_tmpfs;
-#line 7
-allow shared_app shared_app_tmpfs:file { read write };
-#line 7
-
-#line 7
-# Map with PROT_EXEC.
-#line 7
-allow shared_app shared_app_tmpfs:file execute;
-#line 7
-
-
-#line 8
-typeattribute shared_app platformappdomain;
-#line 8
-typeattribute shared_app mlstrustedsubject;
-#line 8
-
-# Access the network.
-
-#line 10
-typeattribute shared_app netdomain;
-#line 10
-
-# Access bluetooth.
-
-#line 12
-typeattribute shared_app bluetoothdomain;
-#line 12
-
-#line 1 "external/sepolicy/shelldomain.te"
-# Rules for all shell domains (e.g. console service and adb shell).
-
-# Access /data/local/tmp.
-allow shelldomain shell_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow shelldomain shell_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow shelldomain shell_data_file:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-
-# Access sdcard.
-allow shelldomain sdcard_type:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow shelldomain sdcard_type:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# adb bugreport
-
-#line 13
-allow shelldomain dumpstate_socket:sock_file write;
-#line 13
-allow shelldomain dumpstate:unix_stream_socket connectto;
-#line 13
-
-
-allow shelldomain rootfs:dir { open getattr read search ioctl };
-allow shelldomain devpts:chr_file { { getattr open read ioctl lock } { open append write } };
-allow shelldomain tty_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow shelldomain console_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow shelldomain input_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow shelldomain system_file:file { getattr execute execute_no_trans };
-allow shelldomain shell_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-allow shelldomain zygote_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-
-
-#line 24
-allow shelldomain apk_data_file:dir { open getattr read search ioctl };
-#line 24
-allow shelldomain apk_data_file:{ file lnk_file } { getattr open read ioctl lock };
-#line 24
-
-
-# Set properties.
-
-#line 27
-allow shelldomain property_socket:sock_file write;
-#line 27
-allow shelldomain init:unix_stream_socket connectto;
-#line 27
-
-allow shelldomain shell_prop:property_service set;
-allow shelldomain ctl_dumpstate_prop:property_service set;
-allow shelldomain debug_prop:property_service set;
-allow shelldomain powerctl_prop:property_service set;
-
-# ndk-gdb invokes adb shell ps to find the app PID.
-
-#line 34
-allow shelldomain { appdomain -system_app }:dir { open getattr read search ioctl };
-#line 34
-allow shelldomain { appdomain -system_app }:{ file lnk_file } { getattr open read ioctl lock };
-#line 34
-
-
-# ndk-gdb invokes adb shell ls to check the app data dir.
-allow shelldomain app_data_file:dir search;
-
-# ps and ps -Z output for app processes.
-
-#line 40
-allow shelldomain appdomain:dir { open getattr read search ioctl };
-#line 40
-allow shelldomain appdomain:{ file lnk_file } { getattr open read ioctl lock };
-#line 40
-
-allow shelldomain appdomain:process getattr;
-#line 1 "external/sepolicy/shell.te"
-# Domain for shell processes spawned by ADB
-type shell, domain, shelldomain, mlstrustedsubject;
-type shell_exec, exec_type, file_type;
-
-# Create and use network sockets.
-
-#line 6
-typeattribute shell netdomain;
-#line 6
-
-
-# Run app_process.
-# XXX Transition into its own domain?
-
-#line 10
-typeattribute shell appdomain;
-#line 10
-# Label ashmem objects with our own unique type.
-#line 10
-
-#line 10
-type shell_tmpfs, file_type;
-#line 10
-type_transition shell tmpfs:file shell_tmpfs;
-#line 10
-allow shell shell_tmpfs:file { read write };
-#line 10
-
-#line 10
-# Map with PROT_EXEC.
-#line 10
-allow shell shell_tmpfs:file execute;
-#line 10
-
-
-# inherits from shelldomain.te
-#line 1 "external/sepolicy/surfaceflinger.te"
-# surfaceflinger - display compositor service
-type surfaceflinger, domain;
-
-#line 3
-typeattribute surfaceflinger mlstrustedsubject;
-#line 3
-typeattribute surfaceflinger unconfineddomain;
-#line 3
-
-type surfaceflinger_exec, exec_type, file_type;
-
-
-#line 6
-
-#line 6
-# Allow the necessary permissions.
-#line 6
-
-#line 6
-# Old domain may exec the file and transition to the new domain.
-#line 6
-allow init surfaceflinger_exec:file { getattr open read execute };
-#line 6
-allow init surfaceflinger:process transition;
-#line 6
-# New domain is entered by executing the file.
-#line 6
-allow surfaceflinger surfaceflinger_exec:file { entrypoint read execute };
-#line 6
-# New domain can send SIGCHLD to its caller.
-#line 6
-allow surfaceflinger init:process sigchld;
-#line 6
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 6
-dontaudit init surfaceflinger:process noatsecure;
-#line 6
-# XXX dontaudit candidate but requires further study.
-#line 6
-allow init surfaceflinger:process { siginh rlimitinh };
-#line 6
-
-#line 6
-# Make the transition occur by default.
-#line 6
-type_transition init surfaceflinger_exec:process surfaceflinger;
-#line 6
-
-#line 6
-
-#line 6
-type surfaceflinger_tmpfs, file_type;
-#line 6
-type_transition surfaceflinger tmpfs:file surfaceflinger_tmpfs;
-#line 6
-allow surfaceflinger surfaceflinger_tmpfs:file { read write };
-#line 6
-
-#line 6
-
-typeattribute surfaceflinger mlstrustedsubject;
-
-# Talk to init over the property socket.
-
-#line 10
-allow surfaceflinger property_socket:sock_file write;
-#line 10
-allow surfaceflinger init:unix_stream_socket connectto;
-#line 10
-
-
-# Perform Binder IPC.
-
-#line 13
-# Call the servicemanager and transfer references to it.
-#line 13
-allow surfaceflinger servicemanager:binder { call transfer };
-#line 13
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 13
-# all domains in domain.te.
-#line 13
-
-
-#line 14
-# Call the server domain and optionally transfer references to it.
-#line 14
-allow surfaceflinger system_server:binder { call transfer };
-#line 14
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 14
-allow system_server surfaceflinger:binder transfer;
-#line 14
-# Receive and use open files from the server.
-#line 14
-allow surfaceflinger system_server:fd use;
-#line 14
-
-
-#line 15
-# Call the server domain and optionally transfer references to it.
-#line 15
-allow surfaceflinger nfc:binder { call transfer };
-#line 15
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 15
-allow nfc surfaceflinger:binder transfer;
-#line 15
-# Receive and use open files from the server.
-#line 15
-allow surfaceflinger nfc:fd use;
-#line 15
-
-
-#line 16
-# Call the server domain and optionally transfer references to it.
-#line 16
-allow surfaceflinger mediaserver:binder { call transfer };
-#line 16
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 16
-allow mediaserver surfaceflinger:binder transfer;
-#line 16
-# Receive and use open files from the server.
-#line 16
-allow surfaceflinger mediaserver:fd use;
-#line 16
-
-
-#line 17
-typeattribute surfaceflinger binderservicedomain;
-#line 17
-
-
-# Access the GPU.
-allow surfaceflinger gpu_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Access /dev/graphics/fb0.
-allow surfaceflinger graphics_device:dir search;
-allow surfaceflinger graphics_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Access /dev/video1.
-allow surfaceflinger video_device:dir { open getattr read search ioctl };
-allow surfaceflinger video_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Create and use netlink kobject uevent sockets.
-allow surfaceflinger self:netlink_kobject_uevent_socket *;
-
-# Set properties.
-allow surfaceflinger system_prop:property_service set;
-allow surfaceflinger ctl_default_prop:property_service set;
-
-# Use open files supplied by an app.
-allow surfaceflinger appdomain:fd use;
-allow surfaceflinger platform_app_data_file:file { read write };
-allow surfaceflinger app_data_file:file { read write };
-
-# Use open file provided by bootanim.
-allow surfaceflinger bootanim:fd use;
-
-# Allow a dumpstate triggered screenshot
-
-#line 46
-# Call the server domain and optionally transfer references to it.
-#line 46
-allow surfaceflinger dumpstate:binder { call transfer };
-#line 46
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 46
-allow dumpstate surfaceflinger:binder transfer;
-#line 46
-# Receive and use open files from the server.
-#line 46
-allow surfaceflinger dumpstate:fd use;
-#line 46
-
-
-#line 47
-# Call the server domain and optionally transfer references to it.
-#line 47
-allow surfaceflinger shell:binder { call transfer };
-#line 47
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 47
-allow shell surfaceflinger:binder transfer;
-#line 47
-# Receive and use open files from the server.
-#line 47
-allow surfaceflinger shell:fd use;
-#line 47
-
-
-# Needed on some devices for playing DRM protected content,
-# but seems expected and appropriate for all devices.
-allow surfaceflinger tee:unix_stream_socket connectto;
-allow surfaceflinger tee_device:chr_file { { getattr open read ioctl lock } { open append write } };
-#line 1 "external/sepolicy/su.te"
-# File types must be defined for file_contexts.
-type su_exec, exec_type, file_type;
-
-#line 23
-
-#line 1 "external/sepolicy/system_app.te"
-#
-# Apps that run with the system UID, e.g. com.android.system.ui,
-# com.android.settings. These are not as privileged as the system
-# server.
-#
-type system_app, domain;
-
-#line 7
-typeattribute system_app mlstrustedsubject;
-#line 7
-typeattribute system_app unconfineddomain;
-#line 7
-
-
-#line 8
-typeattribute system_app appdomain;
-#line 8
-# Label ashmem objects with our own unique type.
-#line 8
-
-#line 8
-type system_app_tmpfs, file_type;
-#line 8
-type_transition system_app tmpfs:file system_app_tmpfs;
-#line 8
-allow system_app system_app_tmpfs:file { read write };
-#line 8
-
-#line 8
-# Map with PROT_EXEC.
-#line 8
-allow system_app system_app_tmpfs:file execute;
-#line 8
-
-
-#line 9
-typeattribute system_app binderservicedomain;
-#line 9
-
-
-# Perform binder IPC to any app domain.
-
-#line 12
-# Call the server domain and optionally transfer references to it.
-#line 12
-allow system_app appdomain:binder { call transfer };
-#line 12
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 12
-allow appdomain system_app:binder transfer;
-#line 12
-# Receive and use open files from the server.
-#line 12
-allow system_app appdomain:fd use;
-#line 12
-
-
-# Read and write system data files.
-# May want to split into separate types.
-allow system_app system_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow system_app system_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Read wallpaper file.
-allow system_app wallpaper_file:file { getattr open read ioctl lock };
-
-# Write to dalvikcache.
-allow system_app dalvikcache_data_file:file { write setattr };
-
-# Talk to keystore.
-
-#line 26
-allow system_app keystore_socket:sock_file write;
-#line 26
-allow system_app keystore:unix_stream_socket connectto;
-#line 26
-
-
-# Read SELinux enforcing status.
-
-#line 29
-allow system_app selinuxfs:dir { open getattr read search ioctl };
-#line 29
-allow system_app selinuxfs:file { getattr open read ioctl lock };
-#line 29
-
-
-# Settings app reads sdcard for storage stats
-allow system_app sdcard_type:dir { open getattr read search ioctl };
-
-# Write to properties
-
-#line 35
-allow system_app property_socket:sock_file write;
-#line 35
-allow system_app init:unix_stream_socket connectto;
-#line 35
-
-allow system_app debug_prop:property_service set;
-allow system_app radio_prop:property_service set;
-allow system_app system_prop:property_service set;
-#line 1 "external/sepolicy/system_server.te"
-#
-# System Server aka system_server spawned by zygote.
-# Most of the framework services run in this process.
-#
-type system_server, domain, mlstrustedsubject;
-
-#line 6
-typeattribute system_server mlstrustedsubject;
-#line 6
-typeattribute system_server unconfineddomain;
-#line 6
-
-
-# Define a type for tmpfs-backed ashmem regions.
-
-#line 9
-type system_server_tmpfs, file_type;
-#line 9
-type_transition system_server tmpfs:file system_server_tmpfs;
-#line 9
-allow system_server system_server_tmpfs:file { read write };
-#line 9
-
-
-# Dalvik Compiler JIT Mapping.
-allow system_server self:process execmem;
-allow system_server ashmem_device:chr_file execute;
-allow system_server system_server_tmpfs:file execute;
-
-# For art.
-allow system_server dalvikcache_data_file:file execute;
-
-# Child of the zygote.
-allow system_server zygote:fd use;
-allow system_server zygote:process sigchld;
-allow system_server zygote_tmpfs:file read;
-
-# Needed to close the zygote socket, which involves getopt / getattr
-# This should be deleted after b/12061011 is fixed
-allow system_server zygote:unix_stream_socket { getopt getattr };
-
-# system server gets network and bluetooth permissions.
-
-#line 29
-typeattribute system_server netdomain;
-#line 29
-
-
-#line 30
-typeattribute system_server bluetoothdomain;
-#line 30
-
-
-# These are the capabilities assigned by the zygote to the
-# system server.
-allow system_server self:capability {
- kill
- net_admin
- net_bind_service
- net_broadcast
- net_raw
- sys_boot
- sys_module
- sys_nice
- sys_resource
- sys_time
- sys_tty_config
-};
-
-allow system_server self:capability2 block_suspend;
-
-# Triggered by /proc/pid accesses, not allowed.
-dontaudit system_server self:capability sys_ptrace;
-
-# Trigger module auto-load.
-allow system_server kernel:system module_request;
-
-# Use netlink uevent sockets.
-allow system_server self:netlink_kobject_uevent_socket *;
-
-# Kill apps.
-allow system_server appdomain:process { sigkill signal };
-
-# Set scheduling info for apps.
-allow system_server appdomain:process { getsched setsched };
-allow system_server mediaserver:process { getsched setsched };
-
-# Read /proc data for apps.
-allow system_server appdomain:dir { open getattr read search ioctl };
-allow system_server appdomain:{ file lnk_file } { { getattr open read ioctl lock } { open append write } };
-
-# Read/Write to /proc/net/xt_qtaguid/ctrl and and /dev/xt_qtaguid.
-allow system_server qtaguid_proc:file { { getattr open read ioctl lock } { open append write } };
-allow system_server qtaguid_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Read /sys/kernel/debug/wakeup_sources.
-allow system_server debugfs:file { getattr open read ioctl lock };
-
-# WifiWatchdog uses a packet_socket
-allow system_server self:packet_socket *;
-
-# 3rd party VPN clients require a tun_socket to be created
-allow system_server self:tun_socket create;
-
-# Notify init of death.
-allow system_server init:process sigchld;
-
-# Talk to init and various daemons via sockets.
-
-#line 87
-allow system_server property_socket:sock_file write;
-#line 87
-allow system_server init:unix_stream_socket connectto;
-#line 87
-
-
-#line 88
-allow system_server qemud_socket:sock_file write;
-#line 88
-allow system_server qemud:unix_stream_socket connectto;
-#line 88
-
-
-#line 89
-allow system_server installd_socket:sock_file write;
-#line 89
-allow system_server installd:unix_stream_socket connectto;
-#line 89
-
-
-#line 90
-allow system_server lmkd_socket:sock_file write;
-#line 90
-allow system_server lmkd:unix_stream_socket connectto;
-#line 90
-
-
-#line 91
-allow system_server netd_socket:sock_file write;
-#line 91
-allow system_server netd:unix_stream_socket connectto;
-#line 91
-
-
-#line 92
-allow system_server vold_socket:sock_file write;
-#line 92
-allow system_server vold:unix_stream_socket connectto;
-#line 92
-
-
-#line 93
-allow system_server zygote_socket:sock_file write;
-#line 93
-allow system_server zygote:unix_stream_socket connectto;
-#line 93
-
-
-#line 94
-allow system_server keystore_socket:sock_file write;
-#line 94
-allow system_server keystore:unix_stream_socket connectto;
-#line 94
-
-
-#line 95
-allow system_server gps_socket:sock_file write;
-#line 95
-allow system_server gpsd:unix_stream_socket connectto;
-#line 95
-
-
-#line 96
-allow system_server racoon_socket:sock_file write;
-#line 96
-allow system_server racoon:unix_stream_socket connectto;
-#line 96
-
-
-#line 97
-allow system_server wpa_socket:sock_file write;
-#line 97
-allow system_server wpa:unix_dgram_socket sendto;
-#line 97
-
-
-# Communicate over a socket created by surfaceflinger.
-allow system_server surfaceflinger:unix_stream_socket { read write setopt };
-
-# Perform Binder IPC.
-
-#line 103
-# Call the servicemanager and transfer references to it.
-#line 103
-allow system_server servicemanager:binder { call transfer };
-#line 103
-# rw access to /dev/binder and /dev/ashmem is presently granted to
-#line 103
-# all domains in domain.te.
-#line 103
-
-
-#line 104
-# Call the server domain and optionally transfer references to it.
-#line 104
-allow system_server binderservicedomain:binder { call transfer };
-#line 104
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 104
-allow binderservicedomain system_server:binder transfer;
-#line 104
-# Receive and use open files from the server.
-#line 104
-allow system_server binderservicedomain:fd use;
-#line 104
-
-
-#line 105
-# Call the server domain and optionally transfer references to it.
-#line 105
-allow system_server appdomain:binder { call transfer };
-#line 105
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 105
-allow appdomain system_server:binder transfer;
-#line 105
-# Receive and use open files from the server.
-#line 105
-allow system_server appdomain:fd use;
-#line 105
-
-
-#line 106
-# Call the server domain and optionally transfer references to it.
-#line 106
-allow system_server healthd:binder { call transfer };
-#line 106
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 106
-allow healthd system_server:binder transfer;
-#line 106
-# Receive and use open files from the server.
-#line 106
-allow system_server healthd:fd use;
-#line 106
-
-
-#line 107
-# Call the server domain and optionally transfer references to it.
-#line 107
-allow system_server dumpstate:binder { call transfer };
-#line 107
-# Allow the serverdomain to transfer references to the client on the reply.
-#line 107
-allow dumpstate system_server:binder transfer;
-#line 107
-# Receive and use open files from the server.
-#line 107
-allow system_server dumpstate:fd use;
-#line 107
-
-
-#line 108
-typeattribute system_server binderservicedomain;
-#line 108
-
-
-# Read /proc/pid files for Binder clients.
-
-#line 111
-allow system_server appdomain:dir { open getattr read search ioctl };
-#line 111
-allow system_server appdomain:{ file lnk_file } { getattr open read ioctl lock };
-#line 111
-
-
-#line 112
-allow system_server mediaserver:dir { open getattr read search ioctl };
-#line 112
-allow system_server mediaserver:{ file lnk_file } { getattr open read ioctl lock };
-#line 112
-
-allow system_server appdomain:process getattr;
-allow system_server mediaserver:process getattr;
-
-# Check SELinux permissions.
-
-#line 117
-allow system_server selinuxfs:dir { open getattr read search ioctl };
-#line 117
-allow system_server selinuxfs:file { { getattr open read ioctl lock } { open append write } };
-#line 117
-allow system_server kernel:security compute_av;
-#line 117
-allow system_server self:netlink_selinux_socket *;
-#line 117
-
-
-# XXX Label sysfs files with a specific type?
-allow system_server sysfs:file { { getattr open read ioctl lock } { open append write } };
-allow system_server sysfs_nfc_power_writable:file { { getattr open read ioctl lock } { open append write } };
-
-# Access devices.
-allow system_server device:dir { open getattr read search ioctl };
-allow system_server mdns_socket:sock_file { { getattr open read ioctl lock } { open append write } };
-allow system_server alarm_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server gpu_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server graphics_device:dir search;
-allow system_server graphics_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server iio_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server input_device:dir { open getattr read search ioctl };
-allow system_server input_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server tty_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server urandom_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server usbaccessory_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server video_device:dir { open getattr read search ioctl };
-allow system_server video_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server qemu_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server adbd_socket:sock_file { { getattr open read ioctl lock } { open append write } };
-
-# tun device used for 3rd party vpn apps
-allow system_server tun_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Manage data files.
-allow system_server data_file_type:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow system_server data_file_type:{ file lnk_file sock_file fifo_file } { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Read /file_contexts and /data/security/file_contexts
-
-#line 149
-allow system_server security_file:dir { open getattr read search ioctl };
-#line 149
-allow system_server security_file:file { getattr open read ioctl lock };
-#line 149
-allow system_server security_file:lnk_file { getattr open read ioctl lock };
-#line 149
-allow system_server selinuxfs:dir { open getattr read search ioctl };
-#line 149
-allow system_server selinuxfs:file { getattr open read ioctl lock };
-#line 149
-allow system_server rootfs:dir { open getattr read search ioctl };
-#line 149
-allow system_server rootfs:file { getattr open read ioctl lock };
-#line 149
-
-
-# Relabel apk files.
-
-#line 152
-typeattribute system_server relabeltodomain;
-#line 152
-
-allow system_server { apk_tmp_file apk_private_tmp_file }:file { relabelfrom relabelto };
-allow system_server { apk_data_file apk_private_data_file }:file { relabelfrom relabelto };
-
-# Relabel wallpaper.
-allow system_server system_data_file:file relabelfrom;
-allow system_server wallpaper_file:file relabelto;
-allow system_server wallpaper_file:file { { getattr open read ioctl lock } { open append write } };
-
-# Relabel /data/anr.
-allow system_server system_data_file:dir relabelfrom;
-allow system_server anr_data_file:dir relabelto;
-
-# Property Service write
-allow system_server system_prop:property_service set;
-allow system_server radio_prop:property_service set;
-allow system_server debug_prop:property_service set;
-allow system_server powerctl_prop:property_service set;
-
-# ctl interface
-allow system_server ctl_default_prop:property_service set;
-
-# Create a socket for receiving info from wpa.
-type_transition system_server wifi_data_file:sock_file system_wpa_socket;
-type_transition system_server wpa_socket:sock_file system_wpa_socket;
-allow system_server wpa_socket:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow system_server system_wpa_socket:sock_file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Remove sockets created by wpa_supplicant
-allow system_server wpa_socket:sock_file unlink;
-
-# Create a socket for connections from debuggerd.
-type_transition system_server system_data_file:sock_file system_ndebug_socket "ndebugsocket";
-allow system_server system_ndebug_socket:sock_file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Specify any arguments to zygote.
-allow system_server self:zygote { specifyids specifyrlimits specifyseinfo };
-
-# Manage cache files.
-allow system_server cache_file:dir { relabelfrom { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } } };
-allow system_server cache_file:file { relabelfrom { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } } };
-
-# Run system programs, e.g. dexopt.
-allow system_server system_file:file { getattr execute execute_no_trans };
-
-# Allow reading of /proc/pid data for other domains.
-# XXX dontaudit candidate
-allow system_server domain:dir { open getattr read search ioctl };
-allow system_server domain:file { getattr open read ioctl lock };
-
-# LocationManager(e.g, GPS) needs to read and write
-# to uart driver and ctrl proc entry
-allow system_server gps_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server gps_control:file { { getattr open read ioctl lock } { open append write } };
-
-# Allow system_server to use app-created sockets.
-allow system_server appdomain:{ tcp_socket udp_socket } { setopt read write };
-
-# Allow abstract socket connection
-allow system_server rild:unix_stream_socket connectto;
-
-# connect to vpn tunnel
-allow system_server mtp:unix_stream_socket { connectto };
-
-# BackupManagerService lets PMS create a data backup file
-allow system_server cache_backup_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-# Relabel /data/backup
-allow system_server backup_data_file:dir { relabelto relabelfrom };
-# Relabel /cache/.*\.{data|restore}
-allow system_server cache_backup_file:file { relabelto relabelfrom };
-# LocalTransport creates and relabels /cache/backup
-allow system_server cache_backup_file:dir { relabelto relabelfrom { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } } };
-
-# Allow system to talk to usb device
-allow system_server usb_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow system_server usb_device:dir { open getattr read search ioctl };
-
-# Allow system to talk to sensors
-allow system_server sensors_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Read from HW RNG (needed by EntropyMixer).
-allow system_server hw_random_device:chr_file { getattr open read ioctl lock };
-
-# Access to wake locks
-allow system_server sysfs_wake_lock:file { { getattr open read ioctl lock } { open append write } };
-
-# Read and delete files under /dev/fscklogs.
-
-#line 239
-allow system_server fscklogs:dir { open getattr read search ioctl };
-#line 239
-allow system_server fscklogs:{ file lnk_file } { getattr open read ioctl lock };
-#line 239
-
-allow system_server fscklogs:dir { write remove_name };
-allow system_server fscklogs:file unlink;
-
-# For SELinuxPolicyInstallReceiver
-
-#line 244
-
-#line 244
-allow system_server security_file:dir { open getattr read search ioctl };
-#line 244
-allow system_server security_file:file { getattr open read ioctl lock };
-#line 244
-allow system_server security_file:lnk_file { getattr open read ioctl lock };
-#line 244
-allow system_server selinuxfs:dir { open getattr read search ioctl };
-#line 244
-allow system_server selinuxfs:file { getattr open read ioctl lock };
-#line 244
-allow system_server rootfs:dir { open getattr read search ioctl };
-#line 244
-allow system_server rootfs:file { getattr open read ioctl lock };
-#line 244
-
-#line 244
-
-#line 244
-allow system_server property_socket:sock_file write;
-#line 244
-allow system_server init:unix_stream_socket connectto;
-#line 244
-
-#line 244
-allow system_server security_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-#line 244
-allow system_server security_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-#line 244
-allow system_server security_file:lnk_file { create rename unlink };
-#line 244
-allow system_server security_prop:property_service set;
-#line 244
-
-
-# For legacy unlabeled userdata on existing devices.
-# See discussion of Unlabeled files in domain.te for more information.
-# This rule is for dalvikcache mmap/mprotect PROT_EXEC.
-allow system_server unlabeled:file execute;
-
-# logd access, system_server inherit logd write socket
-# (urge is to deprecate this long term)
-allow system_server zygote:unix_dgram_socket write;
-
-# Be consistent with DAC permissions. Allow system_server to write to
-# /sys/module/lowmemorykiller/parameters/adj
-# /sys/module/lowmemorykiller/parameters/minfree
-allow system_server sysfs_lowmemorykiller:file { open append write };
-#line 1 "external/sepolicy/tee.te"
-##
-# trusted execution environment (tee) daemon
-#
-type tee, domain;
-type tee_exec, exec_type, file_type;
-type tee_device, dev_type;
-type tee_data_file, file_type, data_file_type;
-
-
-#line 9
-
-#line 9
-# Allow the necessary permissions.
-#line 9
-
-#line 9
-# Old domain may exec the file and transition to the new domain.
-#line 9
-allow init tee_exec:file { getattr open read execute };
-#line 9
-allow init tee:process transition;
-#line 9
-# New domain is entered by executing the file.
-#line 9
-allow tee tee_exec:file { entrypoint read execute };
-#line 9
-# New domain can send SIGCHLD to its caller.
-#line 9
-allow tee init:process sigchld;
-#line 9
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 9
-dontaudit init tee:process noatsecure;
-#line 9
-# XXX dontaudit candidate but requires further study.
-#line 9
-allow init tee:process { siginh rlimitinh };
-#line 9
-
-#line 9
-# Make the transition occur by default.
-#line 9
-type_transition init tee_exec:process tee;
-#line 9
-
-#line 9
-
-#line 9
-type tee_tmpfs, file_type;
-#line 9
-type_transition tee tmpfs:file tee_tmpfs;
-#line 9
-allow tee tee_tmpfs:file { read write };
-#line 9
-
-#line 9
-
-allow tee self:capability { dac_override };
-allow tee tee_device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow tee tee_data_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow tee tee_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow tee self:netlink_socket { create bind read };
-#line 1 "external/sepolicy/ueventd.te"
-# ueventd seclabel is specified in init.rc since
-# it lives in the rootfs and has no unique file type.
-type ueventd, domain;
-
-#line 4
-type ueventd_tmpfs, file_type;
-#line 4
-type_transition ueventd tmpfs:file ueventd_tmpfs;
-#line 4
-allow ueventd ueventd_tmpfs:file { read write };
-#line 4
-
-
-#line 5
-type_transition ueventd device:chr_file klog_device "__kmsg__";
-#line 5
-allow ueventd klog_device:chr_file { create open write unlink };
-#line 5
-allow ueventd device:dir { write add_name remove_name };
-#line 5
-
-
-#line 6
-allow ueventd security_file:dir { open getattr read search ioctl };
-#line 6
-allow ueventd security_file:file { getattr open read ioctl lock };
-#line 6
-allow ueventd security_file:lnk_file { getattr open read ioctl lock };
-#line 6
-allow ueventd selinuxfs:dir { open getattr read search ioctl };
-#line 6
-allow ueventd selinuxfs:file { getattr open read ioctl lock };
-#line 6
-allow ueventd rootfs:dir { open getattr read search ioctl };
-#line 6
-allow ueventd rootfs:file { getattr open read ioctl lock };
-#line 6
-
-
-#line 7
-typeattribute ueventd relabeltodomain;
-#line 7
-
-allow ueventd rootfs:file entrypoint;
-allow ueventd init:process sigchld;
-allow ueventd self:capability { chown mknod net_admin setgid fsetid sys_rawio dac_override fowner };
-allow ueventd device:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow ueventd device:chr_file { { getattr open read ioctl lock } { open append write } };
-allow ueventd sysfs:file { { getattr open read ioctl lock } { open append write } };
-allow ueventd sysfs:file setattr;
-allow ueventd sysfs_type:file { relabelfrom relabelto };
-allow ueventd sysfs_devices_system_cpu:file { { getattr open read ioctl lock } { open append write } };
-allow ueventd tmpfs:chr_file { { getattr open read ioctl lock } { open append write } };
-allow ueventd dev_type:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow ueventd dev_type:lnk_file { create unlink };
-allow ueventd dev_type:chr_file { create setattr unlink };
-allow ueventd dev_type:blk_file { create setattr unlink };
-allow ueventd self:netlink_kobject_uevent_socket *;
-allow ueventd efs_file:dir search;
-allow ueventd efs_file:file { getattr open read ioctl lock };
-#line 1 "external/sepolicy/unconfined.te"
-#######################################################
-#
-# This is the unconfined template. This template is the base policy
-# which is used by daemons and other privileged components of
-# Android.
-#
-# Historically, this template was called "unconfined" because it
-# allowed the domain to do anything it wanted. Over time,
-# this has changed, and will continue to change in the future.
-# The rules in this file will be removed when no remaining
-# unconfined domains require it, or when the rules contradict
-# Android security best practices. Domains which need rules not
-# provided by the unconfined template should add them directly to
-# the relevant policy.
-#
-# The use of this template is discouraged.
-######################################################
-
-allow unconfineddomain self:capability ~{ sys_ptrace sys_rawio mknod sys_module };
-allow unconfineddomain self:capability2 ~{ mac_override mac_admin };
-allow unconfineddomain kernel:security ~{ load_policy setenforce setcheckreqprot };
-allow unconfineddomain kernel:system *;
-allow unconfineddomain domain:process ~{ execmem execstack execheap ptrace transition dyntransition };
-allow unconfineddomain domain:fd *;
-allow unconfineddomain domain:dir { open getattr read search ioctl };
-allow unconfineddomain domain:lnk_file { getattr open read ioctl lock };
-allow unconfineddomain domain:{ fifo_file file } { { getattr open read ioctl lock } { open append write } };
-allow unconfineddomain domain:{ socket tcp_socket udp_socket rawip_socket netlink_socket packet_socket key_socket unix_stream_socket unix_dgram_socket appletalk_socket netlink_route_socket netlink_firewall_socket netlink_tcpdiag_socket netlink_nflog_socket netlink_xfrm_socket netlink_selinux_socket netlink_audit_socket netlink_ip6fw_socket netlink_dnrt_socket netlink_kobject_uevent_socket tun_socket } *;
-allow unconfineddomain domain:{ sem msgq shm ipc } *;
-allow unconfineddomain domain:key *;
-allow unconfineddomain {fs_type dev_type file_type}:{ dir lnk_file sock_file fifo_file } ~relabelto;
-allow unconfineddomain {fs_type -usermodehelper -proc_security}:{ chr_file file } ~{entrypoint execmod execute relabelto};
-allow unconfineddomain {dev_type -kmem_device}:{ chr_file file } ~{entrypoint execmod execute relabelto};
-allow unconfineddomain file_type:{ chr_file file } ~{entrypoint execmod execute relabelto};
-allow unconfineddomain { rootfs system_file exec_type }:file execute;
-allow unconfineddomain node_type:node *;
-allow unconfineddomain node_type:{ tcp_socket udp_socket rawip_socket } node_bind;
-allow unconfineddomain netif_type:netif *;
-allow unconfineddomain port_type:{ socket tcp_socket udp_socket rawip_socket netlink_socket packet_socket key_socket unix_stream_socket unix_dgram_socket appletalk_socket netlink_route_socket netlink_firewall_socket netlink_tcpdiag_socket netlink_nflog_socket netlink_xfrm_socket netlink_selinux_socket netlink_audit_socket netlink_ip6fw_socket netlink_dnrt_socket netlink_kobject_uevent_socket tun_socket } name_bind;
-allow unconfineddomain port_type:{ tcp_socket dccp_socket } name_connect;
-allow unconfineddomain domain:peer recv;
-allow unconfineddomain { domain -init }:binder { call transfer set_context_mgr };
-allow unconfineddomain property_type:property_service set;
-#line 1 "external/sepolicy/uncrypt.te"
-# uncrypt
-type uncrypt, domain;
-type uncrypt_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init uncrypt_exec:file { getattr open read execute };
-#line 5
-allow init uncrypt:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow uncrypt uncrypt_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow uncrypt init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init uncrypt:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init uncrypt:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init uncrypt_exec:process uncrypt;
-#line 5
-
-#line 5
-
-#line 5
-type uncrypt_tmpfs, file_type;
-#line 5
-type_transition uncrypt tmpfs:file uncrypt_tmpfs;
-#line 5
-allow uncrypt uncrypt_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-
-#line 6
-typeattribute uncrypt mlstrustedsubject;
-#line 6
-typeattribute uncrypt unconfineddomain;
-#line 6
-
-
-allow uncrypt self:capability dac_override;
-
-# Read OTA zip file from /data/data/com.google.android.gsf/app_download
-
-#line 11
-allow uncrypt app_data_file:dir { open getattr read search ioctl };
-#line 11
-allow uncrypt app_data_file:{ file lnk_file } { getattr open read ioctl lock };
-#line 11
-
-
-#line 16
-
-
-# Create tmp file /cache/recovery/command.tmp
-# Read /cache/recovery/command
-# Rename /cache/recovery/command.tmp to /cache/recovery/command
-allow uncrypt cache_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow uncrypt cache_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Set a property to reboot the device.
-
-#line 25
-allow uncrypt property_socket:sock_file write;
-#line 25
-allow uncrypt init:unix_stream_socket connectto;
-#line 25
-
-allow uncrypt powerctl_prop:property_service set;
-
-# Raw writes to block device
-allow uncrypt self:capability sys_rawio;
-allow uncrypt block_device:blk_file { open append write };
-#line 1 "external/sepolicy/untrusted_app.te"
-###
-### Untrusted apps.
-###
-### This file defines the rules for untrusted apps. An "untrusted
-### app" is an APP with UID between APP_AID (10000)
-### and AID_ISOLATED_START (99000).
-###
-### untrusted_app includes all the appdomain rules, plus the
-### additional following rules:
-###
-
-type untrusted_app, domain;
-
-#line 13
-typeattribute untrusted_app mlstrustedsubject;
-#line 13
-typeattribute untrusted_app unconfineddomain;
-#line 13
-
-
-#line 14
-typeattribute untrusted_app appdomain;
-#line 14
-# Label ashmem objects with our own unique type.
-#line 14
-
-#line 14
-type untrusted_app_tmpfs, file_type;
-#line 14
-type_transition untrusted_app tmpfs:file untrusted_app_tmpfs;
-#line 14
-allow untrusted_app untrusted_app_tmpfs:file { read write };
-#line 14
-
-#line 14
-# Map with PROT_EXEC.
-#line 14
-allow untrusted_app untrusted_app_tmpfs:file execute;
-#line 14
-
-
-#line 15
-typeattribute untrusted_app netdomain;
-#line 15
-
-
-#line 16
-typeattribute untrusted_app bluetoothdomain;
-#line 16
-
-
-# Some apps ship with shared libraries and binaries that they write out
-# to their sandbox directory and then execute.
-allow untrusted_app app_data_file:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-
-allow untrusted_app tun_device:chr_file { { getattr open read ioctl lock } { open append write } };
-
-# Internal SDCard rw access.
-allow untrusted_app sdcard_internal:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow untrusted_app sdcard_internal:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# External SDCard rw access.
-allow untrusted_app sdcard_external:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow untrusted_app sdcard_external:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# ASEC
-allow untrusted_app asec_apk_file:dir { getattr };
-allow untrusted_app asec_apk_file:file { getattr open read ioctl lock };
-# Execute libs in asec containers.
-allow untrusted_app asec_public_file:file execute;
-
-# Create tcp/udp sockets
-allow untrusted_app node_type:{ tcp_socket udp_socket } node_bind;
-allow untrusted_app self:{ tcp_socket udp_socket } { { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } } accept listen };
-# Bind to a particular hostname/address/interface (e.g., localhost) instead of
-# ANY. Normally, apps should not be listening on all interfaces.
-allow untrusted_app port:{ tcp_socket udp_socket } name_bind;
-
-# Allow the allocation and use of ptys
-# Used by: https://play.google.com/store/apps/details?id=jackpal.androidterm
-
-#line 47
-# Each domain gets a unique devpts type.
-#line 47
-type untrusted_app_devpts, fs_type;
-#line 47
-# Label the pty with the unique type when created.
-#line 47
-type_transition untrusted_app devpts:chr_file untrusted_app_devpts;
-#line 47
-# Allow use of the pty after creation.
-#line 47
-allow untrusted_app untrusted_app_devpts:chr_file { open getattr read write ioctl };
-#line 47
-# Note: devpts:dir search and ptmx_device:chr_file rw_file_perms
-#line 47
-# allowed to everyone via domain.te.
-#line 47
-
-
-# Used by Finsky / Android "Verify Apps" functionality when
-# running "adb install foo.apk".
-# TODO: Long term, we don't want apps probing into shell data files.
-# Figure out a way to remove these rules.
-allow untrusted_app shell_data_file:file { getattr open read ioctl lock };
-allow untrusted_app shell_data_file:dir { open getattr read search ioctl };
-#line 1 "external/sepolicy/vold.te"
-# volume manager
-type vold, domain;
-type vold_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init vold_exec:file { getattr open read execute };
-#line 5
-allow init vold:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow vold vold_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow vold init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init vold:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init vold:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init vold_exec:process vold;
-#line 5
-
-#line 5
-
-#line 5
-type vold_tmpfs, file_type;
-#line 5
-type_transition vold tmpfs:file vold_tmpfs;
-#line 5
-allow vold vold_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-
-typeattribute vold mlstrustedsubject;
-allow vold system_file:file { getattr execute execute_no_trans };
-allow vold block_device:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow vold block_device:blk_file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow vold device:dir write;
-allow vold devpts:chr_file { { getattr open read ioctl lock } { open append write } };
-allow vold rootfs:dir mounton;
-allow vold sdcard_type:dir mounton;
-allow vold sdcard_type:filesystem { mount remount unmount };
-allow vold sdcard_type:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow vold sdcard_type:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow vold tmpfs:filesystem { mount unmount };
-allow vold tmpfs:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow vold tmpfs:dir mounton;
-allow vold self:capability { net_admin dac_override mknod sys_admin chown fowner fsetid };
-allow vold self:netlink_kobject_uevent_socket *;
-allow vold app_data_file:dir search;
-allow vold app_data_file:file { { getattr open read ioctl lock } { open append write } };
-allow vold loop_device:blk_file { { getattr open read ioctl lock } { open append write } };
-allow vold dm_device:chr_file { { getattr open read ioctl lock } { open append write } };
-# For vold Process::killProcessesWithOpenFiles function.
-allow vold domain:dir { open getattr read search ioctl };
-allow vold domain:{ file lnk_file } { getattr open read ioctl lock };
-allow vold domain:process { signal sigkill };
-allow vold self:capability { sys_ptrace kill };
-
-# For blkid
-allow vold shell_exec:file { { getattr open read ioctl lock } { getattr execute execute_no_trans } };
-
-# XXX Label sysfs files with a specific type?
-allow vold sysfs:file { { getattr open read ioctl lock } { open append write } };
-
-
-#line 39
-type_transition vold device:chr_file klog_device "__kmsg__";
-#line 39
-allow vold klog_device:chr_file { create open write unlink };
-#line 39
-allow vold device:dir { write add_name remove_name };
-#line 39
-
-
-# Log fsck results
-allow vold fscklogs:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow vold fscklogs:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-#
-# Rules to support encrypted fs support.
-#
-
-# Set property.
-
-#line 50
-allow vold property_socket:sock_file write;
-#line 50
-allow vold init:unix_stream_socket connectto;
-#line 50
-
-
-# Unmount and mount the fs.
-allow vold labeledfs:filesystem { mount unmount remount };
-
-# Access /efs/userdata_footer.
-# XXX Split into a separate type?
-allow vold efs_file:file { { getattr open read ioctl lock } { open append write } };
-
-# Create and mount on /data/tmp_mnt.
-allow vold system_data_file:dir { create { { open getattr read search ioctl } { open search write add_name remove_name } } mounton };
-
-# Set scheduling policy of kernel processes
-allow vold kernel:process setsched;
-
-# Property Service
-allow vold vold_prop:property_service set;
-allow vold powerctl_prop:property_service set;
-allow vold ctl_default_prop:property_service set;
-
-# ASEC
-allow vold asec_image_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow vold asec_image_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-
-#line 73
-allow vold security_file:dir { open getattr read search ioctl };
-#line 73
-allow vold security_file:file { getattr open read ioctl lock };
-#line 73
-allow vold security_file:lnk_file { getattr open read ioctl lock };
-#line 73
-allow vold selinuxfs:dir { open getattr read search ioctl };
-#line 73
-allow vold selinuxfs:file { getattr open read ioctl lock };
-#line 73
-allow vold rootfs:dir { open getattr read search ioctl };
-#line 73
-allow vold rootfs:file { getattr open read ioctl lock };
-#line 73
-
-
-#line 74
-typeattribute vold relabeltodomain;
-#line 74
-
-allow vold asec_apk_file:dir { { { open getattr read search ioctl } { open search write add_name remove_name } } setattr relabelfrom };
-allow vold asec_public_file:dir { relabelto setattr };
-allow vold asec_apk_file:file { { getattr open read ioctl lock } setattr relabelfrom };
-allow vold asec_public_file:file { relabelto setattr };
-
-# Handle wake locks (used for device encryption)
-allow vold sysfs_wake_lock:file { { getattr open read ioctl lock } { open append write } };
-allow vold self:capability2 block_suspend;
-#line 1 "external/sepolicy/watchdogd.te"
-# watchdogd seclabel is specified in init.<board>.rc
-type watchdogd, domain;
-allow watchdogd rootfs:file { entrypoint { getattr open read ioctl lock } };
-allow watchdogd self:capability mknod;
-allow watchdogd device:dir { add_name write remove_name };
-allow watchdogd watchdog_device:chr_file { { getattr open read ioctl lock } { open append write } };
-# because of /dev/__kmsg__ and /dev/__null__
-
-#line 8
-type_transition watchdogd device:chr_file klog_device "__kmsg__";
-#line 8
-allow watchdogd klog_device:chr_file { create open write unlink };
-#line 8
-allow watchdogd device:dir { write add_name remove_name };
-#line 8
-
-type_transition watchdogd device:chr_file null_device "__null__";
-allow watchdogd null_device:chr_file { create unlink };
-#line 1 "external/sepolicy/wpa_supplicant.te"
-# wpa - wpa supplicant or equivalent
-type wpa, domain;
-type wpa_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init wpa_exec:file { getattr open read execute };
-#line 5
-allow init wpa:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow wpa wpa_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow wpa init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init wpa:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init wpa:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init wpa_exec:process wpa;
-#line 5
-
-#line 5
-
-#line 5
-type wpa_tmpfs, file_type;
-#line 5
-type_transition wpa tmpfs:file wpa_tmpfs;
-#line 5
-allow wpa wpa_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-allow wpa kernel:system module_request;
-allow wpa self:capability { setuid net_admin setgid net_raw };
-allow wpa cgroup:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow wpa self:netlink_route_socket *;
-allow wpa self:netlink_socket *;
-allow wpa self:packet_socket *;
-allow wpa self:udp_socket *;
-allow wpa wifi_data_file:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow wpa wifi_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-#line 15
-allow wpa system_wpa_socket:sock_file write;
-#line 15
-allow wpa system_server:unix_dgram_socket sendto;
-#line 15
-
-allow wpa random_device:chr_file { getattr open read ioctl lock };
-
-# Create a socket for receiving info from wpa
-type_transition wpa wifi_data_file:sock_file wpa_socket;
-allow wpa wpa_socket:dir { { { open getattr read search ioctl } { open search write add_name remove_name } } setattr };
-allow wpa wpa_socket:sock_file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-
-# Allow wpa_cli to work. wpa_cli creates a socket in
-# /data/misc/wifi/sockets which wpa supplicant communicates with.
-#line 27
-
-#line 1 "external/sepolicy/zygote.te"
-# zygote
-type zygote, domain;
-type zygote_exec, exec_type, file_type;
-
-
-#line 5
-
-#line 5
-# Allow the necessary permissions.
-#line 5
-
-#line 5
-# Old domain may exec the file and transition to the new domain.
-#line 5
-allow init zygote_exec:file { getattr open read execute };
-#line 5
-allow init zygote:process transition;
-#line 5
-# New domain is entered by executing the file.
-#line 5
-allow zygote zygote_exec:file { entrypoint read execute };
-#line 5
-# New domain can send SIGCHLD to its caller.
-#line 5
-allow zygote init:process sigchld;
-#line 5
-# Enable AT_SECURE, i.e. libc secure mode.
-#line 5
-dontaudit init zygote:process noatsecure;
-#line 5
-# XXX dontaudit candidate but requires further study.
-#line 5
-allow init zygote:process { siginh rlimitinh };
-#line 5
-
-#line 5
-# Make the transition occur by default.
-#line 5
-type_transition init zygote_exec:process zygote;
-#line 5
-
-#line 5
-
-#line 5
-type zygote_tmpfs, file_type;
-#line 5
-type_transition zygote tmpfs:file zygote_tmpfs;
-#line 5
-allow zygote zygote_tmpfs:file { read write };
-#line 5
-
-#line 5
-
-typeattribute zygote mlstrustedsubject;
-# Override DAC on files and switch uid/gid.
-allow zygote self:capability { dac_override setgid setuid fowner };
-# Drop capabilities from bounding set.
-allow zygote self:capability setpcap;
-# Switch SELinux context to app domains.
-allow zygote system_server:process dyntransition;
-allow zygote appdomain:process dyntransition;
-# Allow zygote to read app /proc/pid dirs (b/10455872)
-allow zygote appdomain:dir { getattr search };
-allow zygote appdomain:file { { getattr open read ioctl lock } };
-# Move children into the peer process group.
-allow zygote system_server:process { getpgid setpgid };
-allow zygote appdomain:process { getpgid setpgid };
-# Write to system data.
-allow zygote system_data_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow zygote system_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-allow zygote dalvikcache_data_file:dir { { open getattr read search ioctl } { open search write add_name remove_name } };
-allow zygote dalvikcache_data_file:file { create setattr { { getattr open read ioctl lock } { open append write } } { getattr link unlink rename } };
-# For art.
-allow zygote dalvikcache_data_file:file execute;
-# Execute dexopt.
-allow zygote system_file:file { getattr execute execute_no_trans };
-# Control cgroups.
-allow zygote cgroup:dir { create reparent rmdir setattr { { open getattr read search ioctl } { open search write add_name remove_name } } { getattr link unlink rename } };
-allow zygote self:capability sys_admin;
-# Check validity of SELinux context before use.
-
-#line 33
-allow zygote selinuxfs:dir { open getattr read search ioctl };
-#line 33
-allow zygote selinuxfs:file { { getattr open read ioctl lock } { open append write } };
-#line 33
-allow zygote kernel:security check_context;
-#line 33
-
-# Check SELinux permissions.
-
-#line 35
-allow zygote selinuxfs:dir { open getattr read search ioctl };
-#line 35
-allow zygote selinuxfs:file { { getattr open read ioctl lock } { open append write } };
-#line 35
-allow zygote kernel:security compute_av;
-#line 35
-allow zygote self:netlink_selinux_socket *;
-#line 35
-
-# Read /seapp_contexts and /data/security/seapp_contexts
-
-#line 37
-allow zygote security_file:dir { open getattr read search ioctl };
-#line 37
-allow zygote security_file:file { getattr open read ioctl lock };
-#line 37
-allow zygote security_file:lnk_file { getattr open read ioctl lock };
-#line 37
-allow zygote selinuxfs:dir { open getattr read search ioctl };
-#line 37
-allow zygote selinuxfs:file { getattr open read ioctl lock };
-#line 37
-allow zygote rootfs:dir { open getattr read search ioctl };
-#line 37
-allow zygote rootfs:file { getattr open read ioctl lock };
-#line 37
-
-
-# Setting up /storage/emulated.
-allow zygote rootfs:dir mounton;
-allow zygote sdcard_type:dir { write search setattr create add_name mounton };
-dontaudit zygote self:capability fsetid;
-allow zygote tmpfs:dir { write create add_name setattr mounton search };
-allow zygote tmpfs:filesystem mount;
-allow zygote labeledfs:filesystem remount;
-
-# Handle --invoke-with command when launching Zygote with a wrapper command.
-allow zygote zygote_exec:file { execute_no_trans open };
-
-# handle bugreports b/10498304
-allow zygote ashmem_device:chr_file execute;
-allow zygote shell_data_file:file { write getattr };
-allow zygote system_server:binder { transfer call };
-allow zygote servicemanager:binder { call };
-
-# For legacy unlabeled userdata on existing devices.
-# See discussion of Unlabeled files in domain.te for more information.
-# This rule is for dalvikcache mmap/mprotect PROT_EXEC.
-allow zygote unlabeled:file execute;
-#line 1 "build/target/board/generic/sepolicy/bootanim.te"
-allow bootanim self:process execmem;
-allow bootanim ashmem_device:chr_file execute;
-#line 1 "build/target/board/generic/sepolicy/domain.te"
-# For /sys/qemu_trace files in the emulator.
-allow domain sysfs_writable:file { { getattr open read ioctl lock } { open append write } };
-#line 1 "build/target/board/generic/sepolicy/surfaceflinger.te"
-allow surfaceflinger self:process execmem;
-allow surfaceflinger ashmem_device:chr_file execute;
-#line 1 "external/sepolicy/roles"
-role r;
-role r types domain;
-#line 1 "external/sepolicy/users"
-user u roles { r } level s0 range s0 - s0:c0.c1023;
-#line 1 "external/sepolicy/initial_sid_contexts"
-sid kernel u:r:kernel:s0
-sid security u:object_r:kernel:s0
-sid unlabeled u:object_r:unlabeled:s0
-sid fs u:object_r:labeledfs:s0
-sid file u:object_r:unlabeled:s0
-sid file_labels u:object_r:unlabeled:s0
-sid init u:object_r:unlabeled:s0
-sid any_socket u:object_r:unlabeled:s0
-sid port u:object_r:port:s0
-sid netif u:object_r:netif:s0
-sid netmsg u:object_r:unlabeled:s0
-sid node u:object_r:node:s0
-sid igmp_packet u:object_r:unlabeled:s0
-sid icmp_socket u:object_r:unlabeled:s0
-sid tcp_socket u:object_r:unlabeled:s0
-sid sysctl_modprobe u:object_r:unlabeled:s0
-sid sysctl u:object_r:proc:s0
-sid sysctl_fs u:object_r:unlabeled:s0
-sid sysctl_kernel u:object_r:unlabeled:s0
-sid sysctl_net u:object_r:unlabeled:s0
-sid sysctl_net_unix u:object_r:unlabeled:s0
-sid sysctl_vm u:object_r:unlabeled:s0
-sid sysctl_dev u:object_r:unlabeled:s0
-sid kmod u:object_r:unlabeled:s0
-sid policy u:object_r:unlabeled:s0
-sid scmp_packet u:object_r:unlabeled:s0
-sid devnull u:object_r:null_device:s0
-#line 1 "external/sepolicy/fs_use"
-# Label inodes via getxattr.
-fs_use_xattr yaffs2 u:object_r:labeledfs:s0;
-fs_use_xattr jffs2 u:object_r:labeledfs:s0;
-fs_use_xattr ext2 u:object_r:labeledfs:s0;
-fs_use_xattr ext3 u:object_r:labeledfs:s0;
-fs_use_xattr ext4 u:object_r:labeledfs:s0;
-fs_use_xattr xfs u:object_r:labeledfs:s0;
-fs_use_xattr btrfs u:object_r:labeledfs:s0;
-
-# Label inodes from task label.
-fs_use_task pipefs u:object_r:pipefs:s0;
-fs_use_task sockfs u:object_r:sockfs:s0;
-
-# Label inodes from combination of task label and fs label.
-# Define type_transition rules if you want per-domain types.
-fs_use_trans devpts u:object_r:devpts:s0;
-fs_use_trans tmpfs u:object_r:tmpfs:s0;
-fs_use_trans devtmpfs u:object_r:device:s0;
-fs_use_trans shm u:object_r:shm:s0;
-fs_use_trans mqueue u:object_r:mqueue:s0;
-
-#line 1 "external/sepolicy/genfs_contexts"
-# Label inodes with the fs label.
-genfscon rootfs / u:object_r:rootfs:s0
-# proc labeling can be further refined (longest matching prefix).
-genfscon proc / u:object_r:proc:s0
-genfscon proc /net u:object_r:proc_net:s0
-genfscon proc /net/xt_qtaguid/ctrl u:object_r:qtaguid_proc:s0
-genfscon proc /sys/fs/protected_hardlinks u:object_r:proc_security:s0
-genfscon proc /sys/fs/protected_symlinks u:object_r:proc_security:s0
-genfscon proc /sys/fs/suid_dumpable u:object_r:proc_security:s0
-genfscon proc /sys/kernel/core_pattern u:object_r:usermodehelper:s0
-genfscon proc /sys/kernel/dmesg_restrict u:object_r:proc_security:s0
-genfscon proc /sys/kernel/hotplug u:object_r:usermodehelper:s0
-genfscon proc /sys/kernel/kptr_restrict u:object_r:proc_security:s0
-genfscon proc /sys/kernel/modprobe u:object_r:usermodehelper:s0
-genfscon proc /sys/kernel/modules_disabled u:object_r:proc_security:s0
-genfscon proc /sys/kernel/poweroff_cmd u:object_r:usermodehelper:s0
-genfscon proc /sys/kernel/randomize_va_space u:object_r:proc_security:s0
-genfscon proc /sys/kernel/usermodehelper u:object_r:usermodehelper:s0
-genfscon proc /sys/net u:object_r:proc_net:s0
-genfscon proc /sys/vm/mmap_min_addr u:object_r:proc_security:s0
-# selinuxfs booleans can be individually labeled.
-genfscon selinuxfs / u:object_r:selinuxfs:s0
-genfscon cgroup / u:object_r:cgroup:s0
-# sysfs labels can be set by userspace.
-genfscon sysfs / u:object_r:sysfs:s0
-genfscon inotifyfs / u:object_r:inotify:s0
-genfscon vfat / u:object_r:sdcard_external:s0
-genfscon debugfs / u:object_r:debugfs:s0
-genfscon fuse / u:object_r:sdcard_internal:s0
-#line 1 "external/sepolicy/port_contexts"
-# portcon statements go here, e.g.
-# portcon tcp 80 u:object_r:http_port:s0
-
diff --git a/tools/selinux/src/gen_SELinux_CTS.py b/tools/selinux/src/gen_SELinux_CTS.py
deleted file mode 100755
index 85d49a8..0000000
--- a/tools/selinux/src/gen_SELinux_CTS.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/python
-# genCheckAccessCTS.py - takes an input SELinux policy.conf file and generates
-# an XML file based on the allow and neverallow rules. The file contains rules,
-# which are created by expanding the SELinux rule notation into the individual
-# components which a checkAccess() check, that a policy manager would have to
-# perform, needs.
-#
-# This test does not work with all valid SELinux policy.conf files. It is meant
-# to simply use a given AOSP generated policy.conf file to create sets
-# representing the policy's types, attributes, classes and permissions, which
-# are used to expand the allow and neverallow rules found. For a full parser
-# and compiler of SELinux, see external/checkpolicy.
-# @dcashman
-
-import pdb
-import re
-import sys
-from xml.etree.ElementTree import Element, SubElement, tostring
-from xml.dom import minidom
-
-import SELinux_CTS
-from SELinux_CTS import SELinuxPolicy
-
-usage = "Usage: ./gen_SELinux_CTS.py input_policy_file output_xml_avc_rules_file neverallow_only=[t/f]"
-
-if __name__ == "__main__":
- # check usage
- if len(sys.argv) != 4:
- print usage
- exit()
- input_file = sys.argv[1]
- output_file = sys.argv[2]
- neverallow_only = (sys.argv[3] == "neverallow_only=t")
- policy = SELinuxPolicy()
- policy.from_file_name(input_file) #load data from file
-
- # expand rules into 4-tuples for SELinux.h checkAccess() check
- xml_root = Element('SELinux_AVC_Rules')
- if not neverallow_only:
- count = 1
- for a in policy.allow_rules:
- expanded_xml = SELinux_CTS.expand_avc_rule_to_xml(policy, a, str(count), 'allow')
- if len(expanded_xml):
- xml_root.append(expanded_xml)
- count += 1
- count = 1
- for n in policy.neverallow_rules:
- expanded_xml = SELinux_CTS.expand_avc_rule_to_xml(policy, n, str(count), 'neverallow')
- if len(expanded_xml):
- xml_root.append(expanded_xml)
- count += 1
-
- #print out the xml file
- s = tostring(xml_root)
- s_parsed = minidom.parseString(s)
- output = s_parsed.toprettyxml(indent=" ")
- with open(output_file, 'w') as out_file:
- out_file.write(output)
diff --git a/tools/selinux/test/policy_clean_test.conf b/tools/selinux/test/policy_clean_test.conf
deleted file mode 100644
index 074a63b..0000000
--- a/tools/selinux/test/policy_clean_test.conf
+++ /dev/null
@@ -1,2230 +0,0 @@
-#line 1 "external/sepolicy/security_classes"
-# FLASK
-
-#
-# Define the security object classes
-#
-
-# Classes marked as userspace are classes
-# for userspace object managers
-
-class capability
-
-# file-related classes
-class file
-
-#
-# Define a common prefix for file access vectors.
-#
-
-common file
-{
- ioctl
- read
- write
- create
- getattr
- setattr
- lock
- relabelfrom
- relabelto
- append
- unlink
- link
- rename
- execute
- swapon
- quotaon
- mounton
-}
-
-class file
-inherits file
-{
- execute_no_trans
- entrypoint
- execmod
- open
- audit_access
-}
-
-class capability
-{
- # The capabilities are defined in include/linux/capability.h
- # Capabilities >= 32 are defined in the capability2 class.
- # Care should be taken to ensure that these are consistent with
- # those definitions. (Order matters)
-
- chown
- dac_override
- dac_read_search
- fowner
- fsetid
- kill
- setgid
- setuid
- setpcap
- linux_immutable
- net_bind_service
- net_broadcast
- net_admin
- net_raw
- ipc_lock
- ipc_owner
- sys_module
- sys_rawio
- sys_chroot
- sys_ptrace
- sys_pacct
- sys_admin
- sys_boot
- sys_nice
- sys_resource
- sys_time
- sys_tty_config
- mknod
- lease
- audit_write
- audit_control
- setfcap
-}
-
-########################################
-#
-# Basic level names for system low and high
-#
-
-
-#line 1 "external/sepolicy/mls"
-#########################################
-# MLS declarations
-#
-
-# Generate the desired number of sensitivities and categories.
-
-#line 6
-# Each sensitivity has a name and zero or more aliases.
-#line 6
-sensitivity s0;
-#line 6
-
-#line 6
-
-#line 6
-# Define the ordering of the sensitivity levels (least to greatest)
-#line 6
-dominance { s0 }
-#line 6
-
-category c0;
-#line 7
-category c1;
-#line 7
-category c2;
-#line 7
-category c3;
-#line 7
-category c4;
-#line 7
-category c5;
-#line 7
-category c6;
-#line 7
-category c7;
-#line 7
-category c8;
-#line 7
-category c9;
-#line 7
-category c10;
-#line 7
-category c11;
-#line 7
-category c12;
-#line 7
-category c13;
-#line 7
-category c14;
-#line 7
-category c15;
-#line 7
-category c16;
-#line 7
-category c17;
-#line 7
-category c18;
-#line 7
-category c19;
-#line 7
-category c20;
-#line 7
-category c21;
-#line 7
-category c22;
-#line 7
-category c23;
-#line 7
-category c24;
-#line 7
-category c25;
-#line 7
-category c26;
-#line 7
-category c27;
-#line 7
-category c28;
-#line 7
-category c29;
-#line 7
-category c30;
-#line 7
-category c31;
-#line 7
-category c32;
-#line 7
-category c33;
-#line 7
-category c34;
-#line 7
-category c35;
-#line 7
-category c36;
-#line 7
-category c37;
-#line 7
-category c38;
-#line 7
-category c39;
-#line 7
-category c40;
-#line 7
-category c41;
-#line 7
-category c42;
-#line 7
-category c43;
-#line 7
-category c44;
-#line 7
-category c45;
-#line 7
-category c46;
-#line 7
-category c47;
-#line 7
-category c48;
-#line 7
-category c49;
-#line 7
-category c50;
-#line 7
-category c51;
-#line 7
-category c52;
-#line 7
-category c53;
-#line 7
-category c54;
-#line 7
-category c55;
-#line 7
-category c56;
-#line 7
-category c57;
-#line 7
-category c58;
-#line 7
-category c59;
-#line 7
-category c60;
-#line 7
-category c61;
-#line 7
-category c62;
-#line 7
-category c63;
-#line 7
-category c64;
-#line 7
-category c65;
-#line 7
-category c66;
-#line 7
-category c67;
-#line 7
-category c68;
-#line 7
-category c69;
-#line 7
-category c70;
-#line 7
-category c71;
-#line 7
-category c72;
-#line 7
-category c73;
-#line 7
-category c74;
-#line 7
-category c75;
-#line 7
-category c76;
-#line 7
-category c77;
-#line 7
-category c78;
-#line 7
-category c79;
-#line 7
-category c80;
-#line 7
-category c81;
-#line 7
-category c82;
-#line 7
-category c83;
-#line 7
-category c84;
-#line 7
-category c85;
-#line 7
-category c86;
-#line 7
-category c87;
-#line 7
-category c88;
-#line 7
-category c89;
-#line 7
-category c90;
-#line 7
-category c91;
-#line 7
-category c92;
-#line 7
-category c93;
-#line 7
-category c94;
-#line 7
-category c95;
-#line 7
-category c96;
-#line 7
-category c97;
-#line 7
-category c98;
-#line 7
-category c99;
-#line 7
-category c100;
-#line 7
-category c101;
-#line 7
-category c102;
-#line 7
-category c103;
-#line 7
-category c104;
-#line 7
-category c105;
-#line 7
-category c106;
-#line 7
-category c107;
-#line 7
-category c108;
-#line 7
-category c109;
-#line 7
-category c110;
-#line 7
-category c111;
-#line 7
-category c112;
-#line 7
-category c113;
-#line 7
-category c114;
-#line 7
-category c115;
-#line 7
-category c116;
-#line 7
-category c117;
-#line 7
-category c118;
-#line 7
-category c119;
-#line 7
-category c120;
-#line 7
-category c121;
-#line 7
-category c122;
-#line 7
-category c123;
-#line 7
-category c124;
-#line 7
-category c125;
-#line 7
-category c126;
-#line 7
-category c127;
-#line 7
-category c128;
-#line 7
-category c129;
-#line 7
-category c130;
-#line 7
-category c131;
-#line 7
-category c132;
-#line 7
-category c133;
-#line 7
-category c134;
-#line 7
-category c135;
-#line 7
-category c136;
-#line 7
-category c137;
-#line 7
-category c138;
-#line 7
-category c139;
-#line 7
-category c140;
-#line 7
-category c141;
-#line 7
-category c142;
-#line 7
-category c143;
-#line 7
-category c144;
-#line 7
-category c145;
-#line 7
-category c146;
-#line 7
-category c147;
-#line 7
-category c148;
-#line 7
-category c149;
-#line 7
-category c150;
-#line 7
-category c151;
-#line 7
-category c152;
-#line 7
-category c153;
-#line 7
-category c154;
-#line 7
-category c155;
-#line 7
-category c156;
-#line 7
-category c157;
-#line 7
-category c158;
-#line 7
-category c159;
-#line 7
-category c160;
-#line 7
-category c161;
-#line 7
-category c162;
-#line 7
-category c163;
-#line 7
-category c164;
-#line 7
-category c165;
-#line 7
-category c166;
-#line 7
-category c167;
-#line 7
-category c168;
-#line 7
-category c169;
-#line 7
-category c170;
-#line 7
-category c171;
-#line 7
-category c172;
-#line 7
-category c173;
-#line 7
-category c174;
-#line 7
-category c175;
-#line 7
-category c176;
-#line 7
-category c177;
-#line 7
-category c178;
-#line 7
-category c179;
-#line 7
-category c180;
-#line 7
-category c181;
-#line 7
-category c182;
-#line 7
-category c183;
-#line 7
-category c184;
-#line 7
-category c185;
-#line 7
-category c186;
-#line 7
-category c187;
-#line 7
-category c188;
-#line 7
-category c189;
-#line 7
-category c190;
-#line 7
-category c191;
-#line 7
-category c192;
-#line 7
-category c193;
-#line 7
-category c194;
-#line 7
-category c195;
-#line 7
-category c196;
-#line 7
-category c197;
-#line 7
-category c198;
-#line 7
-category c199;
-#line 7
-category c200;
-#line 7
-category c201;
-#line 7
-category c202;
-#line 7
-category c203;
-#line 7
-category c204;
-#line 7
-category c205;
-#line 7
-category c206;
-#line 7
-category c207;
-#line 7
-category c208;
-#line 7
-category c209;
-#line 7
-category c210;
-#line 7
-category c211;
-#line 7
-category c212;
-#line 7
-category c213;
-#line 7
-category c214;
-#line 7
-category c215;
-#line 7
-category c216;
-#line 7
-category c217;
-#line 7
-category c218;
-#line 7
-category c219;
-#line 7
-category c220;
-#line 7
-category c221;
-#line 7
-category c222;
-#line 7
-category c223;
-#line 7
-category c224;
-#line 7
-category c225;
-#line 7
-category c226;
-#line 7
-category c227;
-#line 7
-category c228;
-#line 7
-category c229;
-#line 7
-category c230;
-#line 7
-category c231;
-#line 7
-category c232;
-#line 7
-category c233;
-#line 7
-category c234;
-#line 7
-category c235;
-#line 7
-category c236;
-#line 7
-category c237;
-#line 7
-category c238;
-#line 7
-category c239;
-#line 7
-category c240;
-#line 7
-category c241;
-#line 7
-category c242;
-#line 7
-category c243;
-#line 7
-category c244;
-#line 7
-category c245;
-#line 7
-category c246;
-#line 7
-category c247;
-#line 7
-category c248;
-#line 7
-category c249;
-#line 7
-category c250;
-#line 7
-category c251;
-#line 7
-category c252;
-#line 7
-category c253;
-#line 7
-category c254;
-#line 7
-category c255;
-#line 7
-category c256;
-#line 7
-category c257;
-#line 7
-category c258;
-#line 7
-category c259;
-#line 7
-category c260;
-#line 7
-category c261;
-#line 7
-category c262;
-#line 7
-category c263;
-#line 7
-category c264;
-#line 7
-category c265;
-#line 7
-category c266;
-#line 7
-category c267;
-#line 7
-category c268;
-#line 7
-category c269;
-#line 7
-category c270;
-#line 7
-category c271;
-#line 7
-category c272;
-#line 7
-category c273;
-#line 7
-category c274;
-#line 7
-category c275;
-#line 7
-category c276;
-#line 7
-category c277;
-#line 7
-category c278;
-#line 7
-category c279;
-#line 7
-category c280;
-#line 7
-category c281;
-#line 7
-category c282;
-#line 7
-category c283;
-#line 7
-category c284;
-#line 7
-category c285;
-#line 7
-category c286;
-#line 7
-category c287;
-#line 7
-category c288;
-#line 7
-category c289;
-#line 7
-category c290;
-#line 7
-category c291;
-#line 7
-category c292;
-#line 7
-category c293;
-#line 7
-category c294;
-#line 7
-category c295;
-#line 7
-category c296;
-#line 7
-category c297;
-#line 7
-category c298;
-#line 7
-category c299;
-#line 7
-category c300;
-#line 7
-category c301;
-#line 7
-category c302;
-#line 7
-category c303;
-#line 7
-category c304;
-#line 7
-category c305;
-#line 7
-category c306;
-#line 7
-category c307;
-#line 7
-category c308;
-#line 7
-category c309;
-#line 7
-category c310;
-#line 7
-category c311;
-#line 7
-category c312;
-#line 7
-category c313;
-#line 7
-category c314;
-#line 7
-category c315;
-#line 7
-category c316;
-#line 7
-category c317;
-#line 7
-category c318;
-#line 7
-category c319;
-#line 7
-category c320;
-#line 7
-category c321;
-#line 7
-category c322;
-#line 7
-category c323;
-#line 7
-category c324;
-#line 7
-category c325;
-#line 7
-category c326;
-#line 7
-category c327;
-#line 7
-category c328;
-#line 7
-category c329;
-#line 7
-category c330;
-#line 7
-category c331;
-#line 7
-category c332;
-#line 7
-category c333;
-#line 7
-category c334;
-#line 7
-category c335;
-#line 7
-category c336;
-#line 7
-category c337;
-#line 7
-category c338;
-#line 7
-category c339;
-#line 7
-category c340;
-#line 7
-category c341;
-#line 7
-category c342;
-#line 7
-category c343;
-#line 7
-category c344;
-#line 7
-category c345;
-#line 7
-category c346;
-#line 7
-category c347;
-#line 7
-category c348;
-#line 7
-category c349;
-#line 7
-category c350;
-#line 7
-category c351;
-#line 7
-category c352;
-#line 7
-category c353;
-#line 7
-category c354;
-#line 7
-category c355;
-#line 7
-category c356;
-#line 7
-category c357;
-#line 7
-category c358;
-#line 7
-category c359;
-#line 7
-category c360;
-#line 7
-category c361;
-#line 7
-category c362;
-#line 7
-category c363;
-#line 7
-category c364;
-#line 7
-category c365;
-#line 7
-category c366;
-#line 7
-category c367;
-#line 7
-category c368;
-#line 7
-category c369;
-#line 7
-category c370;
-#line 7
-category c371;
-#line 7
-category c372;
-#line 7
-category c373;
-#line 7
-category c374;
-#line 7
-category c375;
-#line 7
-category c376;
-#line 7
-category c377;
-#line 7
-category c378;
-#line 7
-category c379;
-#line 7
-category c380;
-#line 7
-category c381;
-#line 7
-category c382;
-#line 7
-category c383;
-#line 7
-category c384;
-#line 7
-category c385;
-#line 7
-category c386;
-#line 7
-category c387;
-#line 7
-category c388;
-#line 7
-category c389;
-#line 7
-category c390;
-#line 7
-category c391;
-#line 7
-category c392;
-#line 7
-category c393;
-#line 7
-category c394;
-#line 7
-category c395;
-#line 7
-category c396;
-#line 7
-category c397;
-#line 7
-category c398;
-#line 7
-category c399;
-#line 7
-category c400;
-#line 7
-category c401;
-#line 7
-category c402;
-#line 7
-category c403;
-#line 7
-category c404;
-#line 7
-category c405;
-#line 7
-category c406;
-#line 7
-category c407;
-#line 7
-category c408;
-#line 7
-category c409;
-#line 7
-category c410;
-#line 7
-category c411;
-#line 7
-category c412;
-#line 7
-category c413;
-#line 7
-category c414;
-#line 7
-category c415;
-#line 7
-category c416;
-#line 7
-category c417;
-#line 7
-category c418;
-#line 7
-category c419;
-#line 7
-category c420;
-#line 7
-category c421;
-#line 7
-category c422;
-#line 7
-category c423;
-#line 7
-category c424;
-#line 7
-category c425;
-#line 7
-category c426;
-#line 7
-category c427;
-#line 7
-category c428;
-#line 7
-category c429;
-#line 7
-category c430;
-#line 7
-category c431;
-#line 7
-category c432;
-#line 7
-category c433;
-#line 7
-category c434;
-#line 7
-category c435;
-#line 7
-category c436;
-#line 7
-category c437;
-#line 7
-category c438;
-#line 7
-category c439;
-#line 7
-category c440;
-#line 7
-category c441;
-#line 7
-category c442;
-#line 7
-category c443;
-#line 7
-category c444;
-#line 7
-category c445;
-#line 7
-category c446;
-#line 7
-category c447;
-#line 7
-category c448;
-#line 7
-category c449;
-#line 7
-category c450;
-#line 7
-category c451;
-#line 7
-category c452;
-#line 7
-category c453;
-#line 7
-category c454;
-#line 7
-category c455;
-#line 7
-category c456;
-#line 7
-category c457;
-#line 7
-category c458;
-#line 7
-category c459;
-#line 7
-category c460;
-#line 7
-category c461;
-#line 7
-category c462;
-#line 7
-category c463;
-#line 7
-category c464;
-#line 7
-category c465;
-#line 7
-category c466;
-#line 7
-category c467;
-#line 7
-category c468;
-#line 7
-category c469;
-#line 7
-category c470;
-#line 7
-category c471;
-#line 7
-category c472;
-#line 7
-category c473;
-#line 7
-category c474;
-#line 7
-category c475;
-#line 7
-category c476;
-#line 7
-category c477;
-#line 7
-category c478;
-#line 7
-category c479;
-#line 7
-category c480;
-#line 7
-category c481;
-#line 7
-category c482;
-#line 7
-category c483;
-#line 7
-category c484;
-#line 7
-category c485;
-#line 7
-category c486;
-#line 7
-category c487;
-#line 7
-category c488;
-#line 7
-category c489;
-#line 7
-category c490;
-#line 7
-category c491;
-#line 7
-category c492;
-#line 7
-category c493;
-#line 7
-category c494;
-#line 7
-category c495;
-#line 7
-category c496;
-#line 7
-category c497;
-#line 7
-category c498;
-#line 7
-category c499;
-#line 7
-category c500;
-#line 7
-category c501;
-#line 7
-category c502;
-#line 7
-category c503;
-#line 7
-category c504;
-#line 7
-category c505;
-#line 7
-category c506;
-#line 7
-category c507;
-#line 7
-category c508;
-#line 7
-category c509;
-#line 7
-category c510;
-#line 7
-category c511;
-#line 7
-category c512;
-#line 7
-category c513;
-#line 7
-category c514;
-#line 7
-category c515;
-#line 7
-category c516;
-#line 7
-category c517;
-#line 7
-category c518;
-#line 7
-category c519;
-#line 7
-category c520;
-#line 7
-category c521;
-#line 7
-category c522;
-#line 7
-category c523;
-#line 7
-category c524;
-#line 7
-category c525;
-#line 7
-category c526;
-#line 7
-category c527;
-#line 7
-category c528;
-#line 7
-category c529;
-#line 7
-category c530;
-#line 7
-category c531;
-#line 7
-category c532;
-#line 7
-category c533;
-#line 7
-category c534;
-#line 7
-category c535;
-#line 7
-category c536;
-#line 7
-category c537;
-#line 7
-category c538;
-#line 7
-category c539;
-#line 7
-category c540;
-#line 7
-category c541;
-#line 7
-category c542;
-#line 7
-category c543;
-#line 7
-category c544;
-#line 7
-category c545;
-#line 7
-category c546;
-#line 7
-category c547;
-#line 7
-category c548;
-#line 7
-category c549;
-#line 7
-category c550;
-#line 7
-category c551;
-#line 7
-category c552;
-#line 7
-category c553;
-#line 7
-category c554;
-#line 7
-category c555;
-#line 7
-category c556;
-#line 7
-category c557;
-#line 7
-category c558;
-#line 7
-category c559;
-#line 7
-category c560;
-#line 7
-category c561;
-#line 7
-category c562;
-#line 7
-category c563;
-#line 7
-category c564;
-#line 7
-category c565;
-#line 7
-category c566;
-#line 7
-category c567;
-#line 7
-category c568;
-#line 7
-category c569;
-#line 7
-category c570;
-#line 7
-category c571;
-#line 7
-category c572;
-#line 7
-category c573;
-#line 7
-category c574;
-#line 7
-category c575;
-#line 7
-category c576;
-#line 7
-category c577;
-#line 7
-category c578;
-#line 7
-category c579;
-#line 7
-category c580;
-#line 7
-category c581;
-#line 7
-category c582;
-#line 7
-category c583;
-#line 7
-category c584;
-#line 7
-category c585;
-#line 7
-category c586;
-#line 7
-category c587;
-#line 7
-category c588;
-#line 7
-category c589;
-#line 7
-category c590;
-#line 7
-category c591;
-#line 7
-category c592;
-#line 7
-category c593;
-#line 7
-category c594;
-#line 7
-category c595;
-#line 7
-category c596;
-#line 7
-category c597;
-#line 7
-category c598;
-#line 7
-category c599;
-#line 7
-category c600;
-#line 7
-category c601;
-#line 7
-category c602;
-#line 7
-category c603;
-#line 7
-category c604;
-#line 7
-category c605;
-#line 7
-category c606;
-#line 7
-category c607;
-#line 7
-category c608;
-#line 7
-category c609;
-#line 7
-category c610;
-#line 7
-category c611;
-#line 7
-category c612;
-#line 7
-category c613;
-#line 7
-category c614;
-#line 7
-category c615;
-#line 7
-category c616;
-#line 7
-category c617;
-#line 7
-category c618;
-#line 7
-category c619;
-#line 7
-category c620;
-#line 7
-category c621;
-#line 7
-category c622;
-#line 7
-category c623;
-#line 7
-category c624;
-#line 7
-category c625;
-#line 7
-category c626;
-#line 7
-category c627;
-#line 7
-category c628;
-#line 7
-category c629;
-#line 7
-category c630;
-#line 7
-category c631;
-#line 7
-category c632;
-#line 7
-category c633;
-#line 7
-category c634;
-#line 7
-category c635;
-#line 7
-category c636;
-#line 7
-category c637;
-#line 7
-category c638;
-#line 7
-category c639;
-#line 7
-category c640;
-#line 7
-category c641;
-#line 7
-category c642;
-#line 7
-category c643;
-#line 7
-category c644;
-#line 7
-category c645;
-#line 7
-category c646;
-#line 7
-category c647;
-#line 7
-category c648;
-#line 7
-category c649;
-#line 7
-category c650;
-#line 7
-category c651;
-#line 7
-category c652;
-#line 7
-category c653;
-#line 7
-category c654;
-#line 7
-category c655;
-#line 7
-category c656;
-#line 7
-category c657;
-#line 7
-category c658;
-#line 7
-category c659;
-#line 7
-category c660;
-#line 7
-category c661;
-#line 7
-category c662;
-#line 7
-category c663;
-#line 7
-category c664;
-#line 7
-category c665;
-#line 7
-category c666;
-#line 7
-category c667;
-#line 7
-category c668;
-#line 7
-category c669;
-#line 7
-category c670;
-#line 7
-category c671;
-#line 7
-category c672;
-#line 7
-category c673;
-#line 7
-category c674;
-#line 7
-category c675;
-#line 7
-category c676;
-#line 7
-category c677;
-#line 7
-category c678;
-#line 7
-category c679;
-#line 7
-category c680;
-#line 7
-category c681;
-#line 7
-category c682;
-#line 7
-category c683;
-#line 7
-category c684;
-#line 7
-category c685;
-#line 7
-category c686;
-#line 7
-category c687;
-#line 7
-category c688;
-#line 7
-category c689;
-#line 7
-category c690;
-#line 7
-category c691;
-#line 7
-category c692;
-#line 7
-category c693;
-#line 7
-category c694;
-#line 7
-category c695;
-#line 7
-category c696;
-#line 7
-category c697;
-#line 7
-category c698;
-#line 7
-category c699;
-#line 7
-category c700;
-#line 7
-category c701;
-#line 7
-category c702;
-#line 7
-category c703;
-#line 7
-category c704;
-#line 7
-category c705;
-#line 7
-category c706;
-#line 7
-category c707;
-#line 7
-category c708;
-#line 7
-category c709;
-#line 7
-category c710;
-#line 7
-category c711;
-#line 7
-category c712;
-#line 7
-category c713;
-#line 7
-category c714;
-#line 7
-category c715;
-#line 7
-category c716;
-#line 7
-category c717;
-#line 7
-category c718;
-#line 7
-category c719;
-#line 7
-category c720;
-#line 7
-category c721;
-#line 7
-category c722;
-#line 7
-category c723;
-#line 7
-category c724;
-#line 7
-category c725;
-#line 7
-category c726;
-#line 7
-category c727;
-#line 7
-category c728;
-#line 7
-category c729;
-#line 7
-category c730;
-#line 7
-category c731;
-#line 7
-category c732;
-#line 7
-category c733;
-#line 7
-category c734;
-#line 7
-category c735;
-#line 7
-category c736;
-#line 7
-category c737;
-#line 7
-category c738;
-#line 7
-category c739;
-#line 7
-category c740;
-#line 7
-category c741;
-#line 7
-category c742;
-#line 7
-category c743;
-#line 7
-category c744;
-#line 7
-category c745;
-#line 7
-category c746;
-#line 7
-category c747;
-#line 7
-category c748;
-#line 7
-category c749;
-#line 7
-category c750;
-#line 7
-category c751;
-#line 7
-category c752;
-#line 7
-category c753;
-#line 7
-category c754;
-#line 7
-category c755;
-#line 7
-category c756;
-#line 7
-category c757;
-#line 7
-category c758;
-#line 7
-category c759;
-#line 7
-category c760;
-#line 7
-category c761;
-#line 7
-category c762;
-#line 7
-category c763;
-#line 7
-category c764;
-#line 7
-category c765;
-#line 7
-category c766;
-#line 7
-category c767;
-#line 7
-category c768;
-#line 7
-category c769;
-#line 7
-category c770;
-#line 7
-category c771;
-#line 7
-category c772;
-#line 7
-category c773;
-#line 7
-category c774;
-#line 7
-category c775;
-#line 7
-category c776;
-#line 7
-category c777;
-#line 7
-category c778;
-#line 7
-category c779;
-#line 7
-category c780;
-#line 7
-category c781;
-#line 7
-category c782;
-#line 7
-category c783;
-#line 7
-category c784;
-#line 7
-category c785;
-#line 7
-category c786;
-#line 7
-category c787;
-#line 7
-category c788;
-#line 7
-category c789;
-#line 7
-category c790;
-#line 7
-category c791;
-#line 7
-category c792;
-#line 7
-category c793;
-#line 7
-category c794;
-#line 7
-category c795;
-#line 7
-category c796;
-#line 7
-category c797;
-#line 7
-category c798;
-#line 7
-category c799;
-#line 7
-category c800;
-#line 7
-category c801;
-#line 7
-category c802;
-#line 7
-category c803;
-#line 7
-category c804;
-#line 7
-category c805;
-#line 7
-category c806;
-#line 7
-category c807;
-#line 7
-category c808;
-#line 7
-category c809;
-#line 7
-category c810;
-#line 7
-category c811;
-#line 7
-category c812;
-#line 7
-category c813;
-#line 7
-category c814;
-#line 7
-category c815;
-#line 7
-category c816;
-#line 7
-category c817;
-#line 7
-category c818;
-#line 7
-category c819;
-#line 7
-category c820;
-#line 7
-category c821;
-#line 7
-category c822;
-#line 7
-category c823;
-#line 7
-category c824;
-#line 7
-category c825;
-#line 7
-category c826;
-#line 7
-category c827;
-#line 7
-category c828;
-#line 7
-category c829;
-#line 7
-category c830;
-#line 7
-category c831;
-#line 7
-category c832;
-#line 7
-category c833;
-#line 7
-category c834;
-#line 7
-category c835;
-#line 7
-category c836;
-#line 7
-category c837;
-#line 7
-category c838;
-#line 7
-category c839;
-#line 7
-category c840;
-#line 7
-category c841;
-#line 7
-category c842;
-#line 7
-category c843;
-#line 7
-category c844;
-#line 7
-category c845;
-#line 7
-category c846;
-#line 7
-category c847;
-#line 7
-category c848;
-#line 7
-category c849;
-#line 7
-category c850;
-#line 7
-category c851;
-#line 7
-category c852;
-#line 7
-category c853;
-#line 7
-category c854;
-#line 7
-category c855;
-#line 7
-category c856;
-#line 7
-category c857;
-#line 7
-category c858;
-#line 7
-category c859;
-#line 7
-category c860;
-#line 7
-category c861;
-#line 7
-category c862;
-#line 7
-category c863;
-#line 7
-category c864;
-#line 7
-category c865;
-#line 7
-category c866;
-#line 7
-category c867;
-#line 7
-category c868;
-#line 7
-category c869;
-#line 7
-category c870;
-#line 7
-category c871;
-#line 7
-category c872;
-#line 7
-category c873;
-#line 7
-category c874;
-#line 7
-category c875;
-#line 7
-category c876;
-#line 7
-category c877;
-#line 7
-category c878;
-#line 7
-category c879;
-#line 7
-category c880;
-#line 7
-category c881;
-#line 7
-category c882;
-#line 7
-category c883;
-#line 7
-category c884;
-#line 7
-category c885;
-#line 7
-category c886;
-#line 7
-category c887;
-#line 7
-category c888;
-#line 7
-category c889;
-#line 7
-category c890;
-#line 7
-category c891;
-#line 7
-category c892;
-#line 7
-category c893;
-#line 7
-category c894;
-#line 7
-category c895;
-#line 7
-category c896;
-#line 7
-category c897;
-#line 7
-category c898;
-#line 7
-category c899;
-#line 7
-category c900;
-#line 7
-category c901;
-#line 7
-category c902;
-#line 7
-category c903;
-#line 7
-category c904;
-#line 7
-category c905;
-#line 7
-category c906;
-#line 7
-category c907;
-#line 7
-category c908;
-#line 7
-category c909;
-#line 7
-category c910;
-#line 7
-category c911;
-#line 7
-category c912;
-#line 7
-category c913;
-#line 7
-category c914;
-#line 7
-category c915;
-#line 7
-category c916;
-#line 7
-category c917;
-#line 7
-category c918;
-#line 7
-category c919;
-#line 7
-category c920;
-#line 7
-category c921;
-#line 7
-category c922;
-#line 7
-category c923;
-#line 7
-category c924;
-#line 7
-category c925;
-#line 7
-category c926;
-#line 7
-category c927;
-#line 7
-category c928;
-#line 7
-category c929;
-#line 7
-category c930;
-#line 7
-category c931;
-#line 7
-category c932;
-#line 7
-category c933;
-#line 7
-category c934;
-#line 7
-category c935;
-#line 7
-category c936;
-#line 7
-category c937;
-#line 7
-category c938;
-#line 7
-category c939;
-#line 7
-category c940;
-#line 7
-category c941;
-#line 7
-category c942;
-#line 7
-category c943;
-#line 7
-category c944;
-#line 7
-category c945;
-#line 7
-category c946;
-#line 7
-category c947;
-#line 7
-category c948;
-#line 7
-category c949;
-#line 7
-category c950;
-#line 7
-category c951;
-#line 7
-category c952;
-#line 7
-category c953;
-#line 7
-category c954;
-#line 7
-category c955;
-#line 7
-category c956;
-#line 7
-category c957;
-#line 7
-category c958;
-#line 7
-category c959;
-#line 7
-category c960;
-#line 7
-category c961;
-#line 7
-category c962;
-#line 7
-category c963;
-#line 7
-category c964;
-#line 7
-category c965;
-#line 7
-category c966;
-#line 7
-category c967;
-#line 7
-category c968;
-#line 7
-category c969;
-#line 7
-category c970;
-#line 7
-category c971;
-#line 7
-category c972;
-#line 7
-category c973;
-#line 7
-category c974;
-#line 7
-category c975;
-#line 7
-category c976;
-#line 7
-category c977;
-#line 7
-category c978;
-#line 7
-category c979;
-#line 7
-category c980;
-#line 7
-category c981;
-#line 7
-category c982;
-#line 7
-category c983;
-#line 7
-category c984;
-#line 7
-category c985;
-#line 7
-category c986;
-#line 7
-category c987;
-#line 7
-category c988;
-#line 7
-category c989;
-#line 7
-category c990;
-#line 7
-category c991;
-#line 7
-category c992;
-#line 7
-category c993;
-#line 7
-category c994;
-#line 7
-category c995;
-#line 7
-category c996;
-#line 7
-category c997;
-#line 7
-category c998;
-#line 7
-category c999;
-#line 7
-category c1000;
-#line 7
-category c1001;
-#line 7
-category c1002;
-#line 7
-category c1003;
-#line 7
-category c1004;
-#line 7
-category c1005;
-#line 7
-category c1006;
-#line 7
-category c1007;
-#line 7
-category c1008;
-#line 7
-category c1009;
-#line 7
-category c1010;
-#line 7
-category c1011;
-#line 7
-category c1012;
-#line 7
-category c1013;
-#line 7
-category c1014;
-#line 7
-category c1015;
-#line 7
-category c1016;
-#line 7
-category c1017;
-#line 7
-category c1018;
-#line 7
-category c1019;
-#line 7
-category c1020;
-#line 7
-category c1021;
-#line 7
-category c1022;
-#line 7
-category c1023;
-#line 7
-
-
-# Generate level definitions for each sensitivity and category.
-level s0:c0.c1023;
-#line 10
-
-######################################
-# Attribute declarations
-#
-
-# All types used for processes.
-attribute domain;
-
-# Domains that are allowed all permissions ("unconfined").
-attribute unconfineddomain;
-
-# All domains used for apps.
-attribute appdomain;
-
-# All types used for files that can exist on a labeled fs.
-# Do not use for pseudo file types.
-attribute file_type;
-
-# All types used for domain entry points.
-attribute exec_type;
-
-#line 1 "external/sepolicy/bluetooth.te"
-# bluetooth subsystem
-type bluetooth, domain;
-permissive bluetooth;
-
-#line 4
-typeattribute bluetooth appdomain;
-
-#line 5
-typeattribute bluetooth unconfineddomain;
-#line 5
-
-#line 1 "external/sepolicy/healthd.te"
-# healthd seclabel is specified in init.rc since
-# it lives in the rootfs and has no unique file type.
-type healthd, domain;
-permissive healthd;
-type healthd_exec, exec_type, file_type;
-
-# New domain is entered by executing the file.
-#line 7
-allow healthd healthd_exec:file { entrypoint read execute };
-
-###
-### Neverallow rules
-###
-### These are things that Android apps should NEVER be able to do
-###
-
-# Superuser capabilities.
-# bluetooth requires net_admin.
-neverallow { appdomain -unconfineddomain -bluetooth } self:capability *;
-
-# Added to make the neverallow rule make sense in a limited environment.
-# Added at the bottom to not throw off file seek numbers in test suite.
-# This is not a problem, because allow rules are processed after all types
-# are gathered.
-type testTYPE, appdomain, domain;
diff --git a/tools/selinux/test/policy_test.conf b/tools/selinux/test/policy_test.conf
deleted file mode 100644
index d0962cd..0000000
--- a/tools/selinux/test/policy_test.conf
+++ /dev/null
@@ -1,2244 +0,0 @@
-#line 1 "external/sepolicy/security_classes"
-# FLASK
-
-#
-# Define the security object classes
-#
-
-# Classes marked as userspace are classes
-# for userspace object managers
-
-class capability
-
-# file-related classes
-class file
-
-#
-# Define a common prefix for file access vectors.
-#
-
-common file
-{
- ioctl
- read
- write
- create
- getattr
- setattr
- lock
- relabelfrom
- relabelto
- append
- unlink
- link
- rename
- execute
- swapon
- quotaon
- mounton
-}
-
-class file
-inherits file
-{
- execute_no_trans
- entrypoint
- execmod
- open
- audit_access
-}
-
-class capability
-{
- # The capabilities are defined in include/linux/capability.h
- # Capabilities >= 32 are defined in the capability2 class.
- # Care should be taken to ensure that these are consistent with
- # those definitions. (Order matters)
-
- chown
- dac_override
- dac_read_search
- fowner
- fsetid
- kill
- setgid
- setuid
- setpcap
- linux_immutable
- net_bind_service
- net_broadcast
- net_admin
- net_raw
- ipc_lock
- ipc_owner
- sys_module
- sys_rawio
- sys_chroot
- sys_ptrace
- sys_pacct
- sys_admin
- sys_boot
- sys_nice
- sys_resource
- sys_time
- sys_tty_config
- mknod
- lease
- audit_write
- audit_control
- setfcap
-}
-
-########################################
-#
-# Basic level names for system low and high
-#
-
-
-#line 1 "external/sepolicy/mls"
-#########################################
-# MLS declarations
-#
-
-# Generate the desired number of sensitivities and categories.
-
-#line 6
-# Each sensitivity has a name and zero or more aliases.
-#line 6
-sensitivity s0;
-#line 6
-
-#line 6
-
-#line 6
-# Define the ordering of the sensitivity levels (least to greatest)
-#line 6
-dominance { s0 }
-#line 6
-
-category c0;
-#line 7
-category c1;
-#line 7
-category c2;
-#line 7
-category c3;
-#line 7
-category c4;
-#line 7
-category c5;
-#line 7
-category c6;
-#line 7
-category c7;
-#line 7
-category c8;
-#line 7
-category c9;
-#line 7
-category c10;
-#line 7
-category c11;
-#line 7
-category c12;
-#line 7
-category c13;
-#line 7
-category c14;
-#line 7
-category c15;
-#line 7
-category c16;
-#line 7
-category c17;
-#line 7
-category c18;
-#line 7
-category c19;
-#line 7
-category c20;
-#line 7
-category c21;
-#line 7
-category c22;
-#line 7
-category c23;
-#line 7
-category c24;
-#line 7
-category c25;
-#line 7
-category c26;
-#line 7
-category c27;
-#line 7
-category c28;
-#line 7
-category c29;
-#line 7
-category c30;
-#line 7
-category c31;
-#line 7
-category c32;
-#line 7
-category c33;
-#line 7
-category c34;
-#line 7
-category c35;
-#line 7
-category c36;
-#line 7
-category c37;
-#line 7
-category c38;
-#line 7
-category c39;
-#line 7
-category c40;
-#line 7
-category c41;
-#line 7
-category c42;
-#line 7
-category c43;
-#line 7
-category c44;
-#line 7
-category c45;
-#line 7
-category c46;
-#line 7
-category c47;
-#line 7
-category c48;
-#line 7
-category c49;
-#line 7
-category c50;
-#line 7
-category c51;
-#line 7
-category c52;
-#line 7
-category c53;
-#line 7
-category c54;
-#line 7
-category c55;
-#line 7
-category c56;
-#line 7
-category c57;
-#line 7
-category c58;
-#line 7
-category c59;
-#line 7
-category c60;
-#line 7
-category c61;
-#line 7
-category c62;
-#line 7
-category c63;
-#line 7
-category c64;
-#line 7
-category c65;
-#line 7
-category c66;
-#line 7
-category c67;
-#line 7
-category c68;
-#line 7
-category c69;
-#line 7
-category c70;
-#line 7
-category c71;
-#line 7
-category c72;
-#line 7
-category c73;
-#line 7
-category c74;
-#line 7
-category c75;
-#line 7
-category c76;
-#line 7
-category c77;
-#line 7
-category c78;
-#line 7
-category c79;
-#line 7
-category c80;
-#line 7
-category c81;
-#line 7
-category c82;
-#line 7
-category c83;
-#line 7
-category c84;
-#line 7
-category c85;
-#line 7
-category c86;
-#line 7
-category c87;
-#line 7
-category c88;
-#line 7
-category c89;
-#line 7
-category c90;
-#line 7
-category c91;
-#line 7
-category c92;
-#line 7
-category c93;
-#line 7
-category c94;
-#line 7
-category c95;
-#line 7
-category c96;
-#line 7
-category c97;
-#line 7
-category c98;
-#line 7
-category c99;
-#line 7
-category c100;
-#line 7
-category c101;
-#line 7
-category c102;
-#line 7
-category c103;
-#line 7
-category c104;
-#line 7
-category c105;
-#line 7
-category c106;
-#line 7
-category c107;
-#line 7
-category c108;
-#line 7
-category c109;
-#line 7
-category c110;
-#line 7
-category c111;
-#line 7
-category c112;
-#line 7
-category c113;
-#line 7
-category c114;
-#line 7
-category c115;
-#line 7
-category c116;
-#line 7
-category c117;
-#line 7
-category c118;
-#line 7
-category c119;
-#line 7
-category c120;
-#line 7
-category c121;
-#line 7
-category c122;
-#line 7
-category c123;
-#line 7
-category c124;
-#line 7
-category c125;
-#line 7
-category c126;
-#line 7
-category c127;
-#line 7
-category c128;
-#line 7
-category c129;
-#line 7
-category c130;
-#line 7
-category c131;
-#line 7
-category c132;
-#line 7
-category c133;
-#line 7
-category c134;
-#line 7
-category c135;
-#line 7
-category c136;
-#line 7
-category c137;
-#line 7
-category c138;
-#line 7
-category c139;
-#line 7
-category c140;
-#line 7
-category c141;
-#line 7
-category c142;
-#line 7
-category c143;
-#line 7
-category c144;
-#line 7
-category c145;
-#line 7
-category c146;
-#line 7
-category c147;
-#line 7
-category c148;
-#line 7
-category c149;
-#line 7
-category c150;
-#line 7
-category c151;
-#line 7
-category c152;
-#line 7
-category c153;
-#line 7
-category c154;
-#line 7
-category c155;
-#line 7
-category c156;
-#line 7
-category c157;
-#line 7
-category c158;
-#line 7
-category c159;
-#line 7
-category c160;
-#line 7
-category c161;
-#line 7
-category c162;
-#line 7
-category c163;
-#line 7
-category c164;
-#line 7
-category c165;
-#line 7
-category c166;
-#line 7
-category c167;
-#line 7
-category c168;
-#line 7
-category c169;
-#line 7
-category c170;
-#line 7
-category c171;
-#line 7
-category c172;
-#line 7
-category c173;
-#line 7
-category c174;
-#line 7
-category c175;
-#line 7
-category c176;
-#line 7
-category c177;
-#line 7
-category c178;
-#line 7
-category c179;
-#line 7
-category c180;
-#line 7
-category c181;
-#line 7
-category c182;
-#line 7
-category c183;
-#line 7
-category c184;
-#line 7
-category c185;
-#line 7
-category c186;
-#line 7
-category c187;
-#line 7
-category c188;
-#line 7
-category c189;
-#line 7
-category c190;
-#line 7
-category c191;
-#line 7
-category c192;
-#line 7
-category c193;
-#line 7
-category c194;
-#line 7
-category c195;
-#line 7
-category c196;
-#line 7
-category c197;
-#line 7
-category c198;
-#line 7
-category c199;
-#line 7
-category c200;
-#line 7
-category c201;
-#line 7
-category c202;
-#line 7
-category c203;
-#line 7
-category c204;
-#line 7
-category c205;
-#line 7
-category c206;
-#line 7
-category c207;
-#line 7
-category c208;
-#line 7
-category c209;
-#line 7
-category c210;
-#line 7
-category c211;
-#line 7
-category c212;
-#line 7
-category c213;
-#line 7
-category c214;
-#line 7
-category c215;
-#line 7
-category c216;
-#line 7
-category c217;
-#line 7
-category c218;
-#line 7
-category c219;
-#line 7
-category c220;
-#line 7
-category c221;
-#line 7
-category c222;
-#line 7
-category c223;
-#line 7
-category c224;
-#line 7
-category c225;
-#line 7
-category c226;
-#line 7
-category c227;
-#line 7
-category c228;
-#line 7
-category c229;
-#line 7
-category c230;
-#line 7
-category c231;
-#line 7
-category c232;
-#line 7
-category c233;
-#line 7
-category c234;
-#line 7
-category c235;
-#line 7
-category c236;
-#line 7
-category c237;
-#line 7
-category c238;
-#line 7
-category c239;
-#line 7
-category c240;
-#line 7
-category c241;
-#line 7
-category c242;
-#line 7
-category c243;
-#line 7
-category c244;
-#line 7
-category c245;
-#line 7
-category c246;
-#line 7
-category c247;
-#line 7
-category c248;
-#line 7
-category c249;
-#line 7
-category c250;
-#line 7
-category c251;
-#line 7
-category c252;
-#line 7
-category c253;
-#line 7
-category c254;
-#line 7
-category c255;
-#line 7
-category c256;
-#line 7
-category c257;
-#line 7
-category c258;
-#line 7
-category c259;
-#line 7
-category c260;
-#line 7
-category c261;
-#line 7
-category c262;
-#line 7
-category c263;
-#line 7
-category c264;
-#line 7
-category c265;
-#line 7
-category c266;
-#line 7
-category c267;
-#line 7
-category c268;
-#line 7
-category c269;
-#line 7
-category c270;
-#line 7
-category c271;
-#line 7
-category c272;
-#line 7
-category c273;
-#line 7
-category c274;
-#line 7
-category c275;
-#line 7
-category c276;
-#line 7
-category c277;
-#line 7
-category c278;
-#line 7
-category c279;
-#line 7
-category c280;
-#line 7
-category c281;
-#line 7
-category c282;
-#line 7
-category c283;
-#line 7
-category c284;
-#line 7
-category c285;
-#line 7
-category c286;
-#line 7
-category c287;
-#line 7
-category c288;
-#line 7
-category c289;
-#line 7
-category c290;
-#line 7
-category c291;
-#line 7
-category c292;
-#line 7
-category c293;
-#line 7
-category c294;
-#line 7
-category c295;
-#line 7
-category c296;
-#line 7
-category c297;
-#line 7
-category c298;
-#line 7
-category c299;
-#line 7
-category c300;
-#line 7
-category c301;
-#line 7
-category c302;
-#line 7
-category c303;
-#line 7
-category c304;
-#line 7
-category c305;
-#line 7
-category c306;
-#line 7
-category c307;
-#line 7
-category c308;
-#line 7
-category c309;
-#line 7
-category c310;
-#line 7
-category c311;
-#line 7
-category c312;
-#line 7
-category c313;
-#line 7
-category c314;
-#line 7
-category c315;
-#line 7
-category c316;
-#line 7
-category c317;
-#line 7
-category c318;
-#line 7
-category c319;
-#line 7
-category c320;
-#line 7
-category c321;
-#line 7
-category c322;
-#line 7
-category c323;
-#line 7
-category c324;
-#line 7
-category c325;
-#line 7
-category c326;
-#line 7
-category c327;
-#line 7
-category c328;
-#line 7
-category c329;
-#line 7
-category c330;
-#line 7
-category c331;
-#line 7
-category c332;
-#line 7
-category c333;
-#line 7
-category c334;
-#line 7
-category c335;
-#line 7
-category c336;
-#line 7
-category c337;
-#line 7
-category c338;
-#line 7
-category c339;
-#line 7
-category c340;
-#line 7
-category c341;
-#line 7
-category c342;
-#line 7
-category c343;
-#line 7
-category c344;
-#line 7
-category c345;
-#line 7
-category c346;
-#line 7
-category c347;
-#line 7
-category c348;
-#line 7
-category c349;
-#line 7
-category c350;
-#line 7
-category c351;
-#line 7
-category c352;
-#line 7
-category c353;
-#line 7
-category c354;
-#line 7
-category c355;
-#line 7
-category c356;
-#line 7
-category c357;
-#line 7
-category c358;
-#line 7
-category c359;
-#line 7
-category c360;
-#line 7
-category c361;
-#line 7
-category c362;
-#line 7
-category c363;
-#line 7
-category c364;
-#line 7
-category c365;
-#line 7
-category c366;
-#line 7
-category c367;
-#line 7
-category c368;
-#line 7
-category c369;
-#line 7
-category c370;
-#line 7
-category c371;
-#line 7
-category c372;
-#line 7
-category c373;
-#line 7
-category c374;
-#line 7
-category c375;
-#line 7
-category c376;
-#line 7
-category c377;
-#line 7
-category c378;
-#line 7
-category c379;
-#line 7
-category c380;
-#line 7
-category c381;
-#line 7
-category c382;
-#line 7
-category c383;
-#line 7
-category c384;
-#line 7
-category c385;
-#line 7
-category c386;
-#line 7
-category c387;
-#line 7
-category c388;
-#line 7
-category c389;
-#line 7
-category c390;
-#line 7
-category c391;
-#line 7
-category c392;
-#line 7
-category c393;
-#line 7
-category c394;
-#line 7
-category c395;
-#line 7
-category c396;
-#line 7
-category c397;
-#line 7
-category c398;
-#line 7
-category c399;
-#line 7
-category c400;
-#line 7
-category c401;
-#line 7
-category c402;
-#line 7
-category c403;
-#line 7
-category c404;
-#line 7
-category c405;
-#line 7
-category c406;
-#line 7
-category c407;
-#line 7
-category c408;
-#line 7
-category c409;
-#line 7
-category c410;
-#line 7
-category c411;
-#line 7
-category c412;
-#line 7
-category c413;
-#line 7
-category c414;
-#line 7
-category c415;
-#line 7
-category c416;
-#line 7
-category c417;
-#line 7
-category c418;
-#line 7
-category c419;
-#line 7
-category c420;
-#line 7
-category c421;
-#line 7
-category c422;
-#line 7
-category c423;
-#line 7
-category c424;
-#line 7
-category c425;
-#line 7
-category c426;
-#line 7
-category c427;
-#line 7
-category c428;
-#line 7
-category c429;
-#line 7
-category c430;
-#line 7
-category c431;
-#line 7
-category c432;
-#line 7
-category c433;
-#line 7
-category c434;
-#line 7
-category c435;
-#line 7
-category c436;
-#line 7
-category c437;
-#line 7
-category c438;
-#line 7
-category c439;
-#line 7
-category c440;
-#line 7
-category c441;
-#line 7
-category c442;
-#line 7
-category c443;
-#line 7
-category c444;
-#line 7
-category c445;
-#line 7
-category c446;
-#line 7
-category c447;
-#line 7
-category c448;
-#line 7
-category c449;
-#line 7
-category c450;
-#line 7
-category c451;
-#line 7
-category c452;
-#line 7
-category c453;
-#line 7
-category c454;
-#line 7
-category c455;
-#line 7
-category c456;
-#line 7
-category c457;
-#line 7
-category c458;
-#line 7
-category c459;
-#line 7
-category c460;
-#line 7
-category c461;
-#line 7
-category c462;
-#line 7
-category c463;
-#line 7
-category c464;
-#line 7
-category c465;
-#line 7
-category c466;
-#line 7
-category c467;
-#line 7
-category c468;
-#line 7
-category c469;
-#line 7
-category c470;
-#line 7
-category c471;
-#line 7
-category c472;
-#line 7
-category c473;
-#line 7
-category c474;
-#line 7
-category c475;
-#line 7
-category c476;
-#line 7
-category c477;
-#line 7
-category c478;
-#line 7
-category c479;
-#line 7
-category c480;
-#line 7
-category c481;
-#line 7
-category c482;
-#line 7
-category c483;
-#line 7
-category c484;
-#line 7
-category c485;
-#line 7
-category c486;
-#line 7
-category c487;
-#line 7
-category c488;
-#line 7
-category c489;
-#line 7
-category c490;
-#line 7
-category c491;
-#line 7
-category c492;
-#line 7
-category c493;
-#line 7
-category c494;
-#line 7
-category c495;
-#line 7
-category c496;
-#line 7
-category c497;
-#line 7
-category c498;
-#line 7
-category c499;
-#line 7
-category c500;
-#line 7
-category c501;
-#line 7
-category c502;
-#line 7
-category c503;
-#line 7
-category c504;
-#line 7
-category c505;
-#line 7
-category c506;
-#line 7
-category c507;
-#line 7
-category c508;
-#line 7
-category c509;
-#line 7
-category c510;
-#line 7
-category c511;
-#line 7
-category c512;
-#line 7
-category c513;
-#line 7
-category c514;
-#line 7
-category c515;
-#line 7
-category c516;
-#line 7
-category c517;
-#line 7
-category c518;
-#line 7
-category c519;
-#line 7
-category c520;
-#line 7
-category c521;
-#line 7
-category c522;
-#line 7
-category c523;
-#line 7
-category c524;
-#line 7
-category c525;
-#line 7
-category c526;
-#line 7
-category c527;
-#line 7
-category c528;
-#line 7
-category c529;
-#line 7
-category c530;
-#line 7
-category c531;
-#line 7
-category c532;
-#line 7
-category c533;
-#line 7
-category c534;
-#line 7
-category c535;
-#line 7
-category c536;
-#line 7
-category c537;
-#line 7
-category c538;
-#line 7
-category c539;
-#line 7
-category c540;
-#line 7
-category c541;
-#line 7
-category c542;
-#line 7
-category c543;
-#line 7
-category c544;
-#line 7
-category c545;
-#line 7
-category c546;
-#line 7
-category c547;
-#line 7
-category c548;
-#line 7
-category c549;
-#line 7
-category c550;
-#line 7
-category c551;
-#line 7
-category c552;
-#line 7
-category c553;
-#line 7
-category c554;
-#line 7
-category c555;
-#line 7
-category c556;
-#line 7
-category c557;
-#line 7
-category c558;
-#line 7
-category c559;
-#line 7
-category c560;
-#line 7
-category c561;
-#line 7
-category c562;
-#line 7
-category c563;
-#line 7
-category c564;
-#line 7
-category c565;
-#line 7
-category c566;
-#line 7
-category c567;
-#line 7
-category c568;
-#line 7
-category c569;
-#line 7
-category c570;
-#line 7
-category c571;
-#line 7
-category c572;
-#line 7
-category c573;
-#line 7
-category c574;
-#line 7
-category c575;
-#line 7
-category c576;
-#line 7
-category c577;
-#line 7
-category c578;
-#line 7
-category c579;
-#line 7
-category c580;
-#line 7
-category c581;
-#line 7
-category c582;
-#line 7
-category c583;
-#line 7
-category c584;
-#line 7
-category c585;
-#line 7
-category c586;
-#line 7
-category c587;
-#line 7
-category c588;
-#line 7
-category c589;
-#line 7
-category c590;
-#line 7
-category c591;
-#line 7
-category c592;
-#line 7
-category c593;
-#line 7
-category c594;
-#line 7
-category c595;
-#line 7
-category c596;
-#line 7
-category c597;
-#line 7
-category c598;
-#line 7
-category c599;
-#line 7
-category c600;
-#line 7
-category c601;
-#line 7
-category c602;
-#line 7
-category c603;
-#line 7
-category c604;
-#line 7
-category c605;
-#line 7
-category c606;
-#line 7
-category c607;
-#line 7
-category c608;
-#line 7
-category c609;
-#line 7
-category c610;
-#line 7
-category c611;
-#line 7
-category c612;
-#line 7
-category c613;
-#line 7
-category c614;
-#line 7
-category c615;
-#line 7
-category c616;
-#line 7
-category c617;
-#line 7
-category c618;
-#line 7
-category c619;
-#line 7
-category c620;
-#line 7
-category c621;
-#line 7
-category c622;
-#line 7
-category c623;
-#line 7
-category c624;
-#line 7
-category c625;
-#line 7
-category c626;
-#line 7
-category c627;
-#line 7
-category c628;
-#line 7
-category c629;
-#line 7
-category c630;
-#line 7
-category c631;
-#line 7
-category c632;
-#line 7
-category c633;
-#line 7
-category c634;
-#line 7
-category c635;
-#line 7
-category c636;
-#line 7
-category c637;
-#line 7
-category c638;
-#line 7
-category c639;
-#line 7
-category c640;
-#line 7
-category c641;
-#line 7
-category c642;
-#line 7
-category c643;
-#line 7
-category c644;
-#line 7
-category c645;
-#line 7
-category c646;
-#line 7
-category c647;
-#line 7
-category c648;
-#line 7
-category c649;
-#line 7
-category c650;
-#line 7
-category c651;
-#line 7
-category c652;
-#line 7
-category c653;
-#line 7
-category c654;
-#line 7
-category c655;
-#line 7
-category c656;
-#line 7
-category c657;
-#line 7
-category c658;
-#line 7
-category c659;
-#line 7
-category c660;
-#line 7
-category c661;
-#line 7
-category c662;
-#line 7
-category c663;
-#line 7
-category c664;
-#line 7
-category c665;
-#line 7
-category c666;
-#line 7
-category c667;
-#line 7
-category c668;
-#line 7
-category c669;
-#line 7
-category c670;
-#line 7
-category c671;
-#line 7
-category c672;
-#line 7
-category c673;
-#line 7
-category c674;
-#line 7
-category c675;
-#line 7
-category c676;
-#line 7
-category c677;
-#line 7
-category c678;
-#line 7
-category c679;
-#line 7
-category c680;
-#line 7
-category c681;
-#line 7
-category c682;
-#line 7
-category c683;
-#line 7
-category c684;
-#line 7
-category c685;
-#line 7
-category c686;
-#line 7
-category c687;
-#line 7
-category c688;
-#line 7
-category c689;
-#line 7
-category c690;
-#line 7
-category c691;
-#line 7
-category c692;
-#line 7
-category c693;
-#line 7
-category c694;
-#line 7
-category c695;
-#line 7
-category c696;
-#line 7
-category c697;
-#line 7
-category c698;
-#line 7
-category c699;
-#line 7
-category c700;
-#line 7
-category c701;
-#line 7
-category c702;
-#line 7
-category c703;
-#line 7
-category c704;
-#line 7
-category c705;
-#line 7
-category c706;
-#line 7
-category c707;
-#line 7
-category c708;
-#line 7
-category c709;
-#line 7
-category c710;
-#line 7
-category c711;
-#line 7
-category c712;
-#line 7
-category c713;
-#line 7
-category c714;
-#line 7
-category c715;
-#line 7
-category c716;
-#line 7
-category c717;
-#line 7
-category c718;
-#line 7
-category c719;
-#line 7
-category c720;
-#line 7
-category c721;
-#line 7
-category c722;
-#line 7
-category c723;
-#line 7
-category c724;
-#line 7
-category c725;
-#line 7
-category c726;
-#line 7
-category c727;
-#line 7
-category c728;
-#line 7
-category c729;
-#line 7
-category c730;
-#line 7
-category c731;
-#line 7
-category c732;
-#line 7
-category c733;
-#line 7
-category c734;
-#line 7
-category c735;
-#line 7
-category c736;
-#line 7
-category c737;
-#line 7
-category c738;
-#line 7
-category c739;
-#line 7
-category c740;
-#line 7
-category c741;
-#line 7
-category c742;
-#line 7
-category c743;
-#line 7
-category c744;
-#line 7
-category c745;
-#line 7
-category c746;
-#line 7
-category c747;
-#line 7
-category c748;
-#line 7
-category c749;
-#line 7
-category c750;
-#line 7
-category c751;
-#line 7
-category c752;
-#line 7
-category c753;
-#line 7
-category c754;
-#line 7
-category c755;
-#line 7
-category c756;
-#line 7
-category c757;
-#line 7
-category c758;
-#line 7
-category c759;
-#line 7
-category c760;
-#line 7
-category c761;
-#line 7
-category c762;
-#line 7
-category c763;
-#line 7
-category c764;
-#line 7
-category c765;
-#line 7
-category c766;
-#line 7
-category c767;
-#line 7
-category c768;
-#line 7
-category c769;
-#line 7
-category c770;
-#line 7
-category c771;
-#line 7
-category c772;
-#line 7
-category c773;
-#line 7
-category c774;
-#line 7
-category c775;
-#line 7
-category c776;
-#line 7
-category c777;
-#line 7
-category c778;
-#line 7
-category c779;
-#line 7
-category c780;
-#line 7
-category c781;
-#line 7
-category c782;
-#line 7
-category c783;
-#line 7
-category c784;
-#line 7
-category c785;
-#line 7
-category c786;
-#line 7
-category c787;
-#line 7
-category c788;
-#line 7
-category c789;
-#line 7
-category c790;
-#line 7
-category c791;
-#line 7
-category c792;
-#line 7
-category c793;
-#line 7
-category c794;
-#line 7
-category c795;
-#line 7
-category c796;
-#line 7
-category c797;
-#line 7
-category c798;
-#line 7
-category c799;
-#line 7
-category c800;
-#line 7
-category c801;
-#line 7
-category c802;
-#line 7
-category c803;
-#line 7
-category c804;
-#line 7
-category c805;
-#line 7
-category c806;
-#line 7
-category c807;
-#line 7
-category c808;
-#line 7
-category c809;
-#line 7
-category c810;
-#line 7
-category c811;
-#line 7
-category c812;
-#line 7
-category c813;
-#line 7
-category c814;
-#line 7
-category c815;
-#line 7
-category c816;
-#line 7
-category c817;
-#line 7
-category c818;
-#line 7
-category c819;
-#line 7
-category c820;
-#line 7
-category c821;
-#line 7
-category c822;
-#line 7
-category c823;
-#line 7
-category c824;
-#line 7
-category c825;
-#line 7
-category c826;
-#line 7
-category c827;
-#line 7
-category c828;
-#line 7
-category c829;
-#line 7
-category c830;
-#line 7
-category c831;
-#line 7
-category c832;
-#line 7
-category c833;
-#line 7
-category c834;
-#line 7
-category c835;
-#line 7
-category c836;
-#line 7
-category c837;
-#line 7
-category c838;
-#line 7
-category c839;
-#line 7
-category c840;
-#line 7
-category c841;
-#line 7
-category c842;
-#line 7
-category c843;
-#line 7
-category c844;
-#line 7
-category c845;
-#line 7
-category c846;
-#line 7
-category c847;
-#line 7
-category c848;
-#line 7
-category c849;
-#line 7
-category c850;
-#line 7
-category c851;
-#line 7
-category c852;
-#line 7
-category c853;
-#line 7
-category c854;
-#line 7
-category c855;
-#line 7
-category c856;
-#line 7
-category c857;
-#line 7
-category c858;
-#line 7
-category c859;
-#line 7
-category c860;
-#line 7
-category c861;
-#line 7
-category c862;
-#line 7
-category c863;
-#line 7
-category c864;
-#line 7
-category c865;
-#line 7
-category c866;
-#line 7
-category c867;
-#line 7
-category c868;
-#line 7
-category c869;
-#line 7
-category c870;
-#line 7
-category c871;
-#line 7
-category c872;
-#line 7
-category c873;
-#line 7
-category c874;
-#line 7
-category c875;
-#line 7
-category c876;
-#line 7
-category c877;
-#line 7
-category c878;
-#line 7
-category c879;
-#line 7
-category c880;
-#line 7
-category c881;
-#line 7
-category c882;
-#line 7
-category c883;
-#line 7
-category c884;
-#line 7
-category c885;
-#line 7
-category c886;
-#line 7
-category c887;
-#line 7
-category c888;
-#line 7
-category c889;
-#line 7
-category c890;
-#line 7
-category c891;
-#line 7
-category c892;
-#line 7
-category c893;
-#line 7
-category c894;
-#line 7
-category c895;
-#line 7
-category c896;
-#line 7
-category c897;
-#line 7
-category c898;
-#line 7
-category c899;
-#line 7
-category c900;
-#line 7
-category c901;
-#line 7
-category c902;
-#line 7
-category c903;
-#line 7
-category c904;
-#line 7
-category c905;
-#line 7
-category c906;
-#line 7
-category c907;
-#line 7
-category c908;
-#line 7
-category c909;
-#line 7
-category c910;
-#line 7
-category c911;
-#line 7
-category c912;
-#line 7
-category c913;
-#line 7
-category c914;
-#line 7
-category c915;
-#line 7
-category c916;
-#line 7
-category c917;
-#line 7
-category c918;
-#line 7
-category c919;
-#line 7
-category c920;
-#line 7
-category c921;
-#line 7
-category c922;
-#line 7
-category c923;
-#line 7
-category c924;
-#line 7
-category c925;
-#line 7
-category c926;
-#line 7
-category c927;
-#line 7
-category c928;
-#line 7
-category c929;
-#line 7
-category c930;
-#line 7
-category c931;
-#line 7
-category c932;
-#line 7
-category c933;
-#line 7
-category c934;
-#line 7
-category c935;
-#line 7
-category c936;
-#line 7
-category c937;
-#line 7
-category c938;
-#line 7
-category c939;
-#line 7
-category c940;
-#line 7
-category c941;
-#line 7
-category c942;
-#line 7
-category c943;
-#line 7
-category c944;
-#line 7
-category c945;
-#line 7
-category c946;
-#line 7
-category c947;
-#line 7
-category c948;
-#line 7
-category c949;
-#line 7
-category c950;
-#line 7
-category c951;
-#line 7
-category c952;
-#line 7
-category c953;
-#line 7
-category c954;
-#line 7
-category c955;
-#line 7
-category c956;
-#line 7
-category c957;
-#line 7
-category c958;
-#line 7
-category c959;
-#line 7
-category c960;
-#line 7
-category c961;
-#line 7
-category c962;
-#line 7
-category c963;
-#line 7
-category c964;
-#line 7
-category c965;
-#line 7
-category c966;
-#line 7
-category c967;
-#line 7
-category c968;
-#line 7
-category c969;
-#line 7
-category c970;
-#line 7
-category c971;
-#line 7
-category c972;
-#line 7
-category c973;
-#line 7
-category c974;
-#line 7
-category c975;
-#line 7
-category c976;
-#line 7
-category c977;
-#line 7
-category c978;
-#line 7
-category c979;
-#line 7
-category c980;
-#line 7
-category c981;
-#line 7
-category c982;
-#line 7
-category c983;
-#line 7
-category c984;
-#line 7
-category c985;
-#line 7
-category c986;
-#line 7
-category c987;
-#line 7
-category c988;
-#line 7
-category c989;
-#line 7
-category c990;
-#line 7
-category c991;
-#line 7
-category c992;
-#line 7
-category c993;
-#line 7
-category c994;
-#line 7
-category c995;
-#line 7
-category c996;
-#line 7
-category c997;
-#line 7
-category c998;
-#line 7
-category c999;
-#line 7
-category c1000;
-#line 7
-category c1001;
-#line 7
-category c1002;
-#line 7
-category c1003;
-#line 7
-category c1004;
-#line 7
-category c1005;
-#line 7
-category c1006;
-#line 7
-category c1007;
-#line 7
-category c1008;
-#line 7
-category c1009;
-#line 7
-category c1010;
-#line 7
-category c1011;
-#line 7
-category c1012;
-#line 7
-category c1013;
-#line 7
-category c1014;
-#line 7
-category c1015;
-#line 7
-category c1016;
-#line 7
-category c1017;
-#line 7
-category c1018;
-#line 7
-category c1019;
-#line 7
-category c1020;
-#line 7
-category c1021;
-#line 7
-category c1022;
-#line 7
-category c1023;
-#line 7
-
-
-# Generate level definitions for each sensitivity and category.
-level s0:c0.c1023;
-#line 10
-
-######################################
-# Attribute declarations
-#
-
-# All types used for processes.
-attribute domain;
-
-# Domains that are allowed all permissions ("unconfined").
-attribute unconfineddomain;
-
-# All domains used for apps.
-attribute appdomain;
-
-# All types used for files that can exist on a labeled fs.
-# Do not use for pseudo file types.
-attribute file_type;
-
-# All types used for domain entry points.
-attribute exec_type;
-
-#line 1 "external/sepolicy/bluetooth.te"
-# bluetooth subsystem
-type bluetooth, domain;
-permissive bluetooth;
-
-#line 4
-typeattribute bluetooth appdomain;
-
-#line 5
-typeattribute bluetooth unconfineddomain;
-#line 5
-
-#line 1 "external/sepolicy/healthd.te"
-# healthd seclabel is specified in init.rc since
-# it lives in the rootfs and has no unique file type.
-type healthd, domain;
-permissive healthd;
-type healthd_exec, exec_type, file_type;
-
-# New domain is entered by executing the file.
-#line 7
-allow healthd healthd_exec:file { entrypoint read execute };
-
-###
-### Neverallow rules
-###
-### These are things that Android apps should NEVER be able to do
-###
-
-# Superuser capabilities.
-# bluetooth requires net_admin.
-neverallow { appdomain -unconfineddomain -bluetooth } self:capability *;
-
-# Added to make the neverallow rule make sense in a limited environment.
-# Added at the bottom to not throw off file seek numbers in test suite.
-# This is not a problem, because allow rules are processed after all types
-# are gathered.
-type testTYPE, appdomain, domain;
-
-# added rules for further testing (display full range of needed functionality)
-allow unconfineddomain {fs_type dev_type file_type}:{ chr_file file } ~{entrypoint relabelto};
-
-allow init {fs_type dev_type file_type}:{ dir { { chr_file blk_file } { file lnk_file sock_file fifo_file } } } relabelto;
-
-neverallow { appdomain -unconfineddomain } {
- audio_device
- camera_device
- dm_device
- radio_device
- gps_device
- rpmsg_device
-}:chr_file { read write };
\ No newline at end of file
diff --git a/tools/selinux/test/testrunner.py b/tools/selinux/test/testrunner.py
deleted file mode 100755
index bc424e9..0000000
--- a/tools/selinux/test/testrunner.py
+++ /dev/null
@@ -1,442 +0,0 @@
-#!/usr/bin/python
-import sys
-sys.path.append('../src')
-import unittest
-import SELinux_CTS
-from SELinux_CTS import SELinuxPolicy
-
-policy_file_name = 'policy_test.conf'
-types = set([
- 'bluetooth',
- 'healthd',
- 'healthd_exec',
- 'testTYPE' ]) #testTYPE added for neverallow rule to make sense
-attributes = {
- 'domain': set(['bluetooth', 'healthd', 'testTYPE']),
- 'unconfineddomain': set(['bluetooth']),
- 'appdomain': set(['bluetooth', 'testTYPE']),
- 'file_type': set(['healthd_exec']),
- 'exec_type': set(['healthd_exec']) }
-common_classes = {
- 'file': set([
- 'ioctl',
- 'read',
- 'write',
- 'create',
- 'getattr',
- 'setattr',
- 'lock',
- 'relabelfrom',
- 'relabelto',
- 'append',
- 'unlink',
- 'link',
- 'rename',
- 'execute',
- 'swapon',
- 'quotaon',
- 'mounton' ]) }
-classes = {
- 'capability': set([
- 'chown',
- 'dac_override',
- 'dac_read_search',
- 'fowner',
- 'fsetid',
- 'kill',
- 'setgid',
- 'setuid',
- 'setpcap',
- 'linux_immutable',
- 'net_bind_service',
- 'net_broadcast',
- 'net_admin',
- 'net_raw',
- 'ipc_lock',
- 'ipc_owner',
- 'sys_module',
- 'sys_rawio',
- 'sys_chroot',
- 'sys_ptrace',
- 'sys_pacct',
- 'sys_admin',
- 'sys_boot',
- 'sys_nice',
- 'sys_resource',
- 'sys_time',
- 'sys_tty_config',
- 'mknod',
- 'lease',
- 'audit_write',
- 'audit_control',
- 'setfcap' ]),
- 'file': (set([
- 'execute_no_trans',
- 'entrypoint',
- 'execmod',
- 'open',
- 'audit_access' ]) | common_classes['file']) }
-
-# allow healthd healthd_exec:file { entrypoint read execute };
-allow_rules = [
- { 'source_types': {
- 'set': set([
- 'healthd']),
- 'flags': { 'complement': False } },
- 'target_types': {
- 'set': set([
- 'healthd_exec']),
- 'flags': { 'complement': False } },
- 'classes': {
- 'set': set([
- 'file']),
- 'flags': { 'complement': False } },
- 'permissions': {
- 'set': set([
- 'entrypoint',
- 'read',
- 'execute' ]),
- 'flags': { 'complement': False } } } ]
-
-# neverallow { appdomain -unconfineddomain -bluetooth } self:capability *;
-neverallow_rules = [
- { 'source_types': {
- 'set': set([
- 'appdomain',
- '-unconfineddomain',
- '-bluetooth' ]),
- 'flags': { 'complement': False } },
- 'target_types': {
- 'set': set([
- 'self']),
- 'flags': { 'complement': False } },
- 'classes': {
- 'set': set([
- 'capability']),
- 'flags': { 'complement': False } },
- 'permissions': {
- 'set': set([
- '*' ]),
- 'flags': { 'complement': False } } } ]
-
-expected_final_allow_list = [
- [ ('healthd', 'healthd_exec', 'file', 'entrypoint'),
- ('healthd', 'healthd_exec', 'file', 'read'),
- ('healthd', 'healthd_exec', 'file', 'execute') ] ]
-
-expected_final_neverallow_list = [
- [ ('testTYPE', 'testTYPE', 'capability', 'chown'),
- ('testTYPE', 'testTYPE', 'capability', 'dac_override'),
- ('testTYPE', 'testTYPE', 'capability', 'dac_read_search'),
- ('testTYPE', 'testTYPE', 'capability', 'fowner'),
- ('testTYPE', 'testTYPE', 'capability', 'fsetid'),
- ('testTYPE', 'testTYPE', 'capability', 'kill'),
- ('testTYPE', 'testTYPE', 'capability', 'setgid'),
- ('testTYPE', 'testTYPE', 'capability', 'setuid'),
- ('testTYPE', 'testTYPE', 'capability', 'setpcap'),
- ('testTYPE', 'testTYPE', 'capability', 'linux_immutable'),
- ('testTYPE', 'testTYPE', 'capability', 'net_bind_service'),
- ('testTYPE', 'testTYPE', 'capability', 'net_broadcast'),
- ('testTYPE', 'testTYPE', 'capability', 'net_admin'),
- ('testTYPE', 'testTYPE', 'capability', 'net_raw'),
- ('testTYPE', 'testTYPE', 'capability', 'ipc_lock'),
- ('testTYPE', 'testTYPE', 'capability', 'ipc_owner'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_module'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_rawio'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_chroot'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_ptrace'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_pacct'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_admin'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_boot'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_nice'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_resource'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_time'),
- ('testTYPE', 'testTYPE', 'capability', 'sys_tty_config'),
- ('testTYPE', 'testTYPE', 'capability', 'mknod'),
- ('testTYPE', 'testTYPE', 'capability', 'lease'),
- ('testTYPE', 'testTYPE', 'capability', 'audit_write'),
- ('testTYPE', 'testTYPE', 'capability', 'audit_control'),
- ('testTYPE', 'testTYPE', 'capability', 'setfcap') ] ]
-
-
-class SELinuxPolicyTests(unittest.TestCase):
-
-
- def setUp(self):
- self.test_policy = SELinuxPolicy()
- self.test_file = open(policy_file_name, 'r')
- self.test_policy.types = types
- self.test_policy.attributes = attributes
- self.test_policy.common_classes = common_classes
- self.test_policy.classes = classes
- self.test_policy.allow_rules = allow_rules
- self.test_policy.neverallow_rules = neverallow_rules
- return
-
- def testExpandAvcRule(self):
- #TODO: add more examples here to cover different cases
- expanded_allow_list = SELinux_CTS.expand_avc_rule(self.test_policy, self.test_policy.allow_rules[0])
- for a in expected_final_allow_list[0]:
- self.failUnless(a in expanded_allow_list)
- expanded_neverallow_list = SELinux_CTS.expand_avc_rule(self.test_policy, self.test_policy.neverallow_rules[0])
- for n in expected_final_neverallow_list[0]:
- self.failUnless(n in expanded_neverallow_list)
-
- def testExpandBrackets(self):
- #test position without bracket:
- self.test_file.seek(279)
- self.failIf(SELinux_CTS.expand_brackets(self.test_file))
-
- #test position with bracket:
- self.test_file.seek(26123)
- self.failUnless(SELinux_CTS.expand_brackets(self.test_file) == " entrypoint read execute ")
-
- #test position with nested brackets:
- self.test_file.seek(26873)
- self.failUnless(SELinux_CTS.expand_brackets(self.test_file)
- == " dir chr_file blk_file file lnk_file sock_file fifo_file ")
-
- def testGetAvcRuleComponent(self):
- #test against normal ('allow healthd healthd_exec:file ...)
- self.test_file.seek(26096)
- normal_src = { 'flags': { 'complement': False },
- 'set': set(['healthd']) }
- normal_tgt = { 'flags': { 'complement': False },
- 'set': set(['healthd_exec']) }
- normal_class = { 'flags': { 'complement': False },
- 'set': set(['file']) }
- normal_perm = { 'flags': { 'complement': False },
- 'set': set(['entrypoint', 'read', 'execute']) }
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == normal_src)
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == normal_tgt)
- c = SELinux_CTS.advance_past_whitespace(self.test_file)
- if c == ':':
- self.test_file.read(1)
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == normal_class)
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == normal_perm)
-
- #test against 'hard' ('init {fs_type ...' )
- self.test_file.seek(26838)
- hard_src = { 'flags': { 'complement': False },
- 'set': set(['init']) }
- hard_tgt = { 'flags': { 'complement': False },
- 'set': set(['fs_type', 'dev_type', 'file_type']) }
- hard_class = { 'flags': { 'complement': False },
- 'set': set(['dir', 'chr_file', 'blk_file', 'file', 'lnk_file', 'sock_file', 'fifo_file']) }
- hard_perm = { 'flags': { 'complement': False },
- 'set': set(['relabelto']) }
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == hard_src)
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == hard_tgt)
- #mimic ':' check:
- c = SELinux_CTS.advance_past_whitespace(self.test_file)
- if c == ':':
- self.test_file.read(1)
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == hard_class)
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == hard_perm)
-
- #test against 'multi-line' ('init {fs_type ...' )
- self.test_file.seek(26967)
- multi_src = { 'flags': { 'complement': False },
- 'set': set(['appdomain', '-unconfineddomain']) }
- multi_tgt = { 'flags': { 'complement': False },
- 'set': set(['audio_device', 'camera_device', 'dm_device', 'radio_device', 'gps_device', 'rpmsg_device']) }
- multi_class = { 'flags': { 'complement': False },
- 'set': set(['chr_file']) }
- multi_perm = { 'flags': { 'complement': False },
- 'set': set(['read', 'write']) }
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == multi_src)
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == multi_tgt)
- c = SELinux_CTS.advance_past_whitespace(self.test_file)
- if c == ':':
- self.test_file.read(1)
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == multi_class)
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == multi_perm)
-
- #test against 'complement'
- self.test_file.seek(26806)
- complement = { 'flags': { 'complement': True },
- 'set': set(['entrypoint', 'relabelto']) }
- self.failUnless(SELinux_CTS.get_avc_rule_component(self.test_file)
- == complement)
-
- def testGetLineType(self):
- self.failUnless(SELinux_CTS.get_line_type('type bluetooth, domain;')
- == SELinux_CTS.TYPE)
- self.failUnless(SELinux_CTS.get_line_type('attribute unconfineddomain;')
- == SELinux_CTS.ATTRIBUTE)
- self.failUnless(SELinux_CTS.get_line_type('typeattribute bluetooth appdomain;')
- == SELinux_CTS.TYPEATTRIBUTE)
- self.failUnless(SELinux_CTS.get_line_type('class file')
- == SELinux_CTS.CLASS)
- self.failUnless(SELinux_CTS.get_line_type('common file')
- == SELinux_CTS.COMMON)
- self.failUnless(SELinux_CTS.get_line_type('allow healthd healthd_exec:file { entrypoint read execute };')
- == SELinux_CTS.ALLOW_RULE)
- self.failUnless(SELinux_CTS.get_line_type('neverallow { appdomain -unconfineddomain -bluetooth } self:capability *;')
- == SELinux_CTS.NEVERALLOW_RULE)
- self.failUnless(SELinux_CTS.get_line_type('# FLASK')
- == SELinux_CTS.OTHER)
-
- def testIsMultiLine(self):
- self.failIf(SELinux_CTS.is_multi_line(SELinux_CTS.TYPE))
- self.failIf(SELinux_CTS.is_multi_line(SELinux_CTS.ATTRIBUTE))
- self.failIf(SELinux_CTS.is_multi_line(SELinux_CTS.TYPEATTRIBUTE))
- self.failUnless(SELinux_CTS.is_multi_line(SELinux_CTS.CLASS))
- self.failUnless(SELinux_CTS.is_multi_line(SELinux_CTS.COMMON))
- self.failUnless(SELinux_CTS.is_multi_line(SELinux_CTS.ALLOW_RULE))
- self.failUnless(SELinux_CTS.is_multi_line(SELinux_CTS.NEVERALLOW_RULE))
- self.failIf(SELinux_CTS.is_multi_line(SELinux_CTS.OTHER))
-
- def testProcessInheritsSegment(self):
- inherit_offset = 448 # needs changing if file changes
- self.test_file.seek(inherit_offset, 0)
- inherit_result = SELinux_CTS.process_inherits_segment(self.test_file)
- self.failUnless(inherit_result == 'file')
- return
-
- def testFromFileName(self):
- #using a special file, since the test_file has some lines which don't 'jive'
- clean_policy_file = 'policy_clean_test.conf'
- from_file_policy = SELinuxPolicy()
- from_file_policy.from_file_name(clean_policy_file)
- self.failUnless(from_file_policy.types == self.test_policy.types)
- self.failUnless(from_file_policy.attributes == self.test_policy.attributes)
- self.failUnless(from_file_policy.classes == self.test_policy.classes)
- self.failUnless(from_file_policy.common_classes == self.test_policy.common_classes)
- self.failUnless(from_file_policy.allow_rules == self.test_policy.allow_rules)
- self.failUnless(from_file_policy.neverallow_rules == self.test_policy.neverallow_rules)
-
- def testExpandPermissions(self):
- #test general case
- test_class_obj = 'file'
- general_set = set(['read', 'write', 'execute'])
- expanded_general_set = general_set
- self.failUnless(self.test_policy.expand_permissions(test_class_obj, general_set)
- == general_set)
- star_set = set(['*'])
- expanded_star_set = self.test_policy.classes['file'] #everything in the class
- self.failUnless(self.test_policy.expand_permissions(test_class_obj, star_set)
- == expanded_star_set)
- complement_set = set(['*', '-open'])
- expanded_complement_set = self.test_policy.classes['file'] - set(['open'])
- self.failUnless(self.test_policy.expand_permissions(test_class_obj, complement_set)
- == expanded_complement_set)
-
- def testExpandTypes(self):
-
- #test general case and '-' handling
- test_source_set = set([
- 'domain',
- '-bluetooth' ])
- expanded_test_source_set = set([
- 'healthd', 'testTYPE' ])
- self.failUnless(self.test_policy.expand_types(test_source_set) == expanded_test_source_set)
-
- #test '*' handling
- test_source_set = set([ '*' ])
- expanded_test_source_set = set([
- 'bluetooth', 'healthd', 'testTYPE' ])
- self.failUnless(self.test_policy.expand_types(test_source_set) == types)
- #test - handling
- test_source_set = set([
- '*',
- '-bluetooth'])
- expanded_test_source_set = set([
- 'healthd', 'healthd_exec', 'testTYPE' ])
- self.failUnless(self.test_policy.expand_types(test_source_set) == expanded_test_source_set)
-
- def testProcessAttributeLine(self):
- attribute_policy = SELinuxPolicy()
- #test with 'normal input'
- test_normal_string = 'attribute TEST_att;'
- test_attribute = 'TEST_att'
- attribute_policy.process_attribute_line(test_normal_string)
- self.failUnless( test_attribute in attribute_policy.attributes)
- #TODO: test on bogus inputs
-
- def testProcessClassLine(self):
- class_policy = SELinuxPolicy()
- #offsets need changing if test file changes
- common_offset = 279
- class_initial_offset = 212
- class_perm_offset = 437
- self.test_file.seek(common_offset, 0)
- line = self.test_file.readline()
- class_policy.process_common_line(line, self.test_file)
- self.test_file.seek(class_initial_offset, 0)
- line = self.test_file.readline()
- class_policy.process_class_line(line, self.test_file)
- self.failUnless('file' in class_policy.classes)
- self.test_file.seek(class_perm_offset, 0)
- line = self.test_file.readline()
- class_policy.process_class_line(line, self.test_file)
- self.failUnless(class_policy.classes['file'] == classes['file'])
-
- def testProcessCommonLine(self):
- common_policy = SELinuxPolicy()
- common_offset = 279 # needs changing if file changes
- self.test_file.seek(common_offset, 0)
- line = self.test_file.readline()
- common_policy.process_common_line(line, self.test_file)
- self.failUnless('file' in common_policy.common_classes )
- self.failUnless(common_policy.common_classes['file'] == common_classes['file'])
-
- def testProcessAvcRuleLine(self):
- avc_policy = SELinuxPolicy()
- allow_offset = 26091 # needs changing if file changes
- neverallow_offset = 26311 # needs changing if file changes
- self.test_file.seek(allow_offset, 0)
- line = self.test_file.readline()
- avc_policy.process_avc_rule_line(line, self.test_file)
- self.failUnless(avc_policy.allow_rules[0] == allow_rules[0] ) # always '0'?
- self.test_file.seek(neverallow_offset, 0)
- line = self.test_file.readline()
- avc_policy.process_avc_rule_line(line, self.test_file)
- self.failUnless(avc_policy.neverallow_rules[0] == neverallow_rules[0] ) # always '0'?
-
- def testProcessTypeLine(self):
- type_policy = SELinuxPolicy()
- test_normal_string = 'type TEST_type, TEST_att1, TEST_att2;'
- test_type = 'TEST_type'
- test_atts = ['TEST_att1', 'TEST_att2']
- #test with 'normal input'
- type_policy.process_type_line(test_normal_string)
- self.failUnless(test_type in type_policy.types)
- for a in test_atts:
- self.failUnless(a in type_policy.attributes)
- self.failUnless(test_type in type_policy.attributes[a])
- #TODO: test with domain only, no attributes
- # and test on bogus inputs
-
- def testProcessTypeattributeLine(self):
- typ_att_policy = SELinuxPolicy()
- test_normal_string = 'typeattribute TEST_type TEST_att1, TEST_att2;'
- test_type = 'TEST_type'
- test_atts = ['TEST_att1', 'TEST_att2']
- #test with 'normal input' (type should already be declared)
- typ_att_policy.process_type_line('type ' + test_type + ';')
- typ_att_policy.process_typeattribute_line(test_normal_string)
- self.failUnless(test_type in typ_att_policy.types)
- for a in test_atts:
- self.failUnless(a in typ_att_policy.attributes)
- self.failUnless(test_type in typ_att_policy.attributes[a])
- #TODO: test with domain only, no attributes
- # and test on bogus inputs
-
-def main():
- unittest.main()
-
-if __name__ == '__main__':
- main()