Merge "Add case for density=560" into lmp-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index a08c34f..8f7b820 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -34,13 +34,14 @@
     CtsAppTestStubs \
     CtsDeviceAdmin \
     CtsDeviceOpenGl \
+    CtsDeviceOwnerApp \
     CtsDeviceTaskswitchingAppA \
     CtsDeviceTaskswitchingAppB \
     CtsDeviceTaskswitchingControl \
     CtsDeviceUi \
+    CtsManagedProfileApp \
     CtsMonkeyApp \
     CtsMonkeyApp2 \
-    CtsProfileOwnerApp \
     CtsSomeAccessibilityServices \
     CtsThemeDeviceApp \
     SignatureTest \
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 95fe006..27439f0 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -728,21 +728,9 @@
             </intent-filter>
         </receiver>
 
-        <activity android:name=".sensors.AccelerometerTestActivity"
-                  android:label="@string/snsr_accel_test"
-                android:screenOrientation="nosensor">
-            <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_sensors" />
-            <meta-data android:name="test_required_features"
-                       android:value="android.hardware.sensor.accelerometer" />
-        </activity>
-
         <activity android:name=".sensors.AccelerometerMeasurementTestActivity"
                   android:label="@string/snsr_accel_m_test"
-                  android:screenOrientation="nosensor">
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.cts.intent.category.MANUAL_TEST"/>
@@ -752,20 +740,9 @@
                        android:value="android.hardware.sensor.accelerometer"/>
         </activity>
 
-        <activity android:name=".sensors.GyroscopeTestActivity" android:label="@string/snsr_gyro_test"
-                android:screenOrientation="nosensor">
-            <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_sensors" />
-            <meta-data android:name="test_required_features"
-                       android:value="android.hardware.sensor.gyroscope" />
-        </activity>
-
         <activity android:name=".sensors.GyroscopeMeasurementTestActivity"
                   android:label="@string/snsr_gyro_m_test"
-                  android:screenOrientation="nosensor">
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.cts.intent.category.MANUAL_TEST"/>
@@ -789,7 +766,7 @@
 
         <activity android:name=".sensors.MagneticFieldMeasurementTestActivity"
                   android:label="@string/snsr_mag_m_test"
-                  android:screenOrientation="nosensor">
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -801,7 +778,7 @@
 
         <activity android:name=".sensors.SensorValueAccuracyActivity"
                   android:label="@string/snsr_val_acc_test"
-                  android:screenOrientation="nosensor">
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -811,9 +788,10 @@
                        android:value="android.hardware.sensor.accelerometer" />
         </activity>
 
-        <activity android:name=".sensors.RotationVectorTestActivity"
+        <!-- TODO: enable when a full set of verifications can be implemented -->
+        <!--activity android:name=".sensors.RotationVectorTestActivity"
                   android:label="@string/snsr_rot_vec_test"
-                  android:screenOrientation="nosensor">
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -821,11 +799,11 @@
             <meta-data android:name="test_category" android:value="@string/test_category_sensors" />
             <meta-data android:name="test_required_features"
                        android:value="android.hardware.sensor.gyroscope" />
-        </activity>
+        </activity-->
 
         <activity android:name=".sensors.BatchingTestActivity"
                   android:label="@string/snsr_batch_test"
-                  android:screenOrientation="nosensor">
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -835,10 +813,10 @@
                        android:value="android.hardware.sensor.accelerometer" />
         </activity>
 
-        <!-- TODO: enable test when a more reliable way to identify time synchronization is available -->
+        <!-- TODO: enable when a more reliable way to identify time synchronization is available -->
         <!--activity android:name=".sensors.SensorSynchronizationTestActivity"
                   android:label="@string/snsr_synch_test"
-                  android:screenOrientation="nosensor">
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -850,7 +828,7 @@
 
         <activity android:name=".sensors.SingleSensorTestsActivity"
                   android:label="@string/snsr_single_sensor_tests"
-                  android:screenOrientation="nosensor">
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.cts.intent.category.MANUAL_TEST"/>
@@ -860,7 +838,7 @@
 
         <activity android:name=".sensors.SensorBatchingTestsActivity"
                   android:label="@string/snsr_sensor_batching_tests"
-                  android:screenOrientation="nosensor">
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.cts.intent.category.MANUAL_TEST"/>
@@ -869,7 +847,8 @@
         </activity>
 
         <activity android:name=".sensors.SensorIntegrationTestsActivity"
-                  android:label="@string/snsr_sensor_integration_tests">
+                  android:label="@string/snsr_sensor_integration_tests"
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.cts.intent.category.MANUAL_TEST"/>
@@ -878,7 +857,8 @@
         </activity>
 
         <activity android:name=".sensors.SensorTestActivity"
-                  android:label="@string/snsr_sensor_test">
+                  android:label="@string/snsr_sensor_test"
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.cts.intent.category.MANUAL_TEST"/>
@@ -886,6 +866,8 @@
             <meta-data android:name="test_category" android:value="@string/test_category_sensors"/>
         </activity>
 
+        <!-- End sensor tests definitions -->
+
         <activity android:name=".location.LocationModeOffTestActivity"
                 android:label="@string/location_mode_off_test">
             <intent-filter>
diff --git a/apps/CtsVerifier/proguard.flags b/apps/CtsVerifier/proguard.flags
index be17d8b..ca4680f 100644
--- a/apps/CtsVerifier/proguard.flags
+++ b/apps/CtsVerifier/proguard.flags
@@ -10,6 +10,9 @@
 -keepclassmembers class * extends com.android.cts.verifier.sensors.base.BaseSensorTestActivity {
     public <methods>;
 }
+-keepclassmembers class * extends android.hardware.cts.SensorTestCase {
+    public <methods>;
+}
 
 -keepclasseswithmembers class * extends com.android.cts.verifier.location.LocationModeTestActivity
 
diff --git a/apps/CtsVerifier/res/layout-land/sensor_test.xml b/apps/CtsVerifier/res/layout-land/sensor_test.xml
new file mode 100644
index 0000000..293b4b0
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-land/sensor_test.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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+
+    <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1">
+
+        <ScrollView
+                android:id="@+id/log_scroll_view"
+                android:fillViewport="true"
+                android:layout_height="match_parent"
+                android:layout_width="0dp"
+                android:layout_weight="1">
+
+            <LinearLayout
+                    android:id="@+id/log_layout"
+                    android:orientation="vertical"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"/>
+
+        </ScrollView>
+
+        <android.opengl.GLSurfaceView android:id="@+id/gl_surface_view"
+                android:visibility="gone"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"/>
+
+    </LinearLayout>
+
+    <include layout="@layout/snsr_next_button" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout-port/sensor_test.xml b/apps/CtsVerifier/res/layout-port/sensor_test.xml
new file mode 100644
index 0000000..eac5357
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-port/sensor_test.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <ScrollView android:id="@+id/log_scroll_view"
+            android:fillViewport="true"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:layout_width="match_parent">
+
+        <LinearLayout android:id="@+id/log_layout"
+                android:orientation="vertical"
+                android:layout_height="match_parent"
+                android:layout_width="match_parent"/>
+
+    </ScrollView>
+
+    <android.opengl.GLSurfaceView android:id="@+id/gl_surface_view"
+            android:visibility="gone"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:layout_width="match_parent"/>
+
+    <include layout="@layout/snsr_next_button"/>
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/snsr_next_button.xml b/apps/CtsVerifier/res/layout/snsr_next_button.xml
new file mode 100644
index 0000000..e7a6d72
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/snsr_next_button.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:gravity="center"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="@dimen/snsr_view_padding_bottom"
+        android:paddingTop="@dimen/snsr_view_padding_top"
+        >
+
+    <Button android:id="@+id/next_button"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:text="@string/next_button_text"
+            />
+
+    <Button android:id="@+id/pass_button"
+            android:visibility="gone"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableTop="@drawable/fs_good"
+            />
+
+    <Button android:id="@+id/fail_button"
+            android:visibility="gone"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableTop="@drawable/fs_error"
+            />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/snsr_rotvec.xml b/apps/CtsVerifier/res/layout/snsr_rotvec.xml
deleted file mode 100644
index 5d7bc8b..0000000
--- a/apps/CtsVerifier/res/layout/snsr_rotvec.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" >
-
-    <ScrollView android:id="@+id/log_scroll_view"
-                android:layout_height="0dp"
-                android:layout_width="wrap_content"
-                android:layout_weight="1" >
-
-        <LinearLayout android:id="@+id/log_layout"
-                      android:orientation="vertical"
-                      android:layout_width="wrap_content"
-                      android:layout_height="wrap_content" />
-
-    </ScrollView>
-
-    <android.opengl.GLSurfaceView android:id="@+id/gl_surface_view"
-            android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="2" />
-
-    <LinearLayout
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_weight="0"
-        android:paddingBottom="@dimen/snsr_view_padding_bottom"
-        android:paddingTop="@dimen/snsr_view_padding_top" >
-
-        <Button android:id="@+id/next_button"
-                android:layout_gravity="center_horizontal"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:text="@string/next_button_text" />
-
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/snsr_semi_auto_test.xml b/apps/CtsVerifier/res/layout/snsr_semi_auto_test.xml
deleted file mode 100644
index 27880ce..0000000
--- a/apps/CtsVerifier/res/layout/snsr_semi_auto_test.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" >
-
-    <ScrollView android:id="@+id/log_scroll_view"
-        android:fillViewport="true"
-        android:layout_height="0dp"
-        android:layout_width="match_parent"
-        android:layout_weight="1" >
-
-        <LinearLayout android:id="@+id/log_layout"
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent" />
-
-    </ScrollView>
-
-    <LinearLayout
-        android:orientation="horizontal"
-        android:gravity="center"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingBottom="@dimen/snsr_view_padding_bottom"
-        android:paddingTop="@dimen/snsr_view_padding_top" >
-
-        <Button android:id="@+id/next_button"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:text="@string/next_button_text" />
-
-        <Button android:id="@+id/pass_button"
-                android:visibility="gone"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:drawableTop="@drawable/fs_good"/>
-
-        <Button android:id="@+id/fail_button"
-                android:visibility="gone"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:drawableTop="@drawable/fs_error"/>
-
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 3a84f3b..38e0ced 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -470,8 +470,6 @@
     <string name="snsr_test_skipped">SKIPPED</string>
     <string name="snsr_test_fail">FAIL</string>
     <string name="snsr_executing_test">\nExecuting test case \'%1$s\'..\n</string>
-    <string name="snsr_orientation_portrait">[Device orientation]: Portrait.</string>
-    <string name="snsr_orientation_landscape">[Device orientation]: Landscape.</string>
 
     <!-- Strings to interact with users in Sensor Tests -->
     <string name="snsr_test_play_sound">A sound will be played once the verification is complete...</string>
@@ -495,17 +493,25 @@
     <string name="snsr_setting_location_mode">Location</string>
     <string name="snsr_setting_auto_screen_off_mode">Display Sleep</string>
     <string name="snsr_pass_on_error">Pass Anyway</string>
+    <string name="snsr_run_automated_tests">The screen will be turned off to execute the tests,
+        when tests complete, the device will vibrate and the screen will be turned back on.</string>
 
     <!-- Accelerometer -->
     <string name="snsr_accel_test">Accelerometer Test</string>
     <string name="snsr_accel_test_info">This test verifies that the accelerometer is working properly. As you move the device around through space, the triangle should always point down (i.e. in the direction of gravity.) If it does not, the accelerometer is improperly configured.</string>
     <string name="snsr_accel_m_test">Accelerometer Measurement Tests</string>
-    <string name="snsr_accel_test_face_up">Place the device in a flat surface with the screen facing the ceiling.</string>
-    <string name="snsr_accel_test_face_down">Place the device in a flat surface with the screen facing it.</string>
-    <string name="snsr_accel_test_right_side">Place the device in a flat surface resting vertically on its right side.</string>
-    <string name="snsr_accel_test_left_side">Place the device in a flat surface resting vertically on its left side.</string>
-    <string name="snsr_accel_test_top_side">Place the device in a flat surface resting vertically on its top side.</string>
-    <string name="snsr_accel_test_bottom_side">Place the device in a flat surface resting vertically on its bottom side.</string>
+    <string name="snsr_accel_test_face_up">Place the device on a flat surface with the screen
+        facing the ceiling.</string>
+    <string name="snsr_accel_test_face_down">Place the device on a flat surface with the screen
+        facing it.</string>
+    <string name="snsr_accel_test_right_side">Place the device in a flat surface resting vertically
+        on its right side.</string>
+    <string name="snsr_accel_test_left_side">Place the device in a flat surface resting vertically
+        on its left side.</string>
+    <string name="snsr_accel_test_top_side">Place the device in a flat surface resting vertically
+        on its top side.</string>
+    <string name="snsr_accel_test_bottom_side">Place the device in a flat surface resting vertically
+        on its bottom side.</string>
 
     <!-- Gyroscope -->
     <string name="snsr_gyro_test">Gyroscope Test</string>
@@ -517,17 +523,13 @@
     <string name="snsr_gyro_test_degrees_message">These values looks like degrees per second. These should be radians per second!</string>
     <string name="snsr_gyro_m_test">Gyroscope Measurement Test</string>
     <string name="snsr_gyro_device_placement">Place the device in a flat surface with the screen
-        facing the ceiling, make sure the device aligns with the orientation specified for each
-        scenario. Then follow the instructions:</string>
+        facing the ceiling. Read the instructions for each scenario, before you perform the
+        test.</string>
     <string name="snsr_gyro_device_static">Leave the device static.</string>
     <string name="snsr_gyro_rotate_clockwise">Rotate the device clockwise.</string>
-    <string name="snsr_gyro_rotate_counter_clockwise">Rotate the device counter clockwise.</string>
-    <string name="snsr_gyro_rotate_right_side">Rotate the device on its right side until it stands on its side.</string>
-    <string name="snsr_gyro_rotate_left_side">Rotate the device on its left side until it stands on its side.</string>
-    <string name="snsr_gyro_rotate_top_side">Rotate the device on its top side until it stands perpendicular.</string>
-    <string name="snsr_gyro_rotate_bottom_side">Rotate the device on its bottom side util it stands perpendicular.</string>
-    <string name="snsr_gyro_rotate_clockwise_integration">Once you begin the test, you will need
-            to rotate the device %1$f degrees counter-clockwise.</string>
+    <string name="snsr_gyro_rotate_device">Once you begin the test, you will need to rotate the
+        device 360deg (one time) in the direction show by the animation, then place it back on the
+        flat surface.</string>
 
     <!-- Heart Rate -->
     <string name="snsr_heartrate_test">Heart Rate Test</string>
@@ -556,7 +558,8 @@
 
     <!-- Sensor Batching -->
     <string name="snsr_batch_test">Sensor Batching Tests</string>
-    <string name="snsr_batching_walking_needed">Once the test begins, you will have to walk.</string>
+    <string name="snsr_batching_walking_needed">Once the test begins, you will have to take the
+        device in your hand and walk.</string>
     <string name="snsr_batching_fifo_count">FifoReservedEventCount=%1$d. Expected to be at most FifoMaxEventCount=%2$d.</string>
 
     <!-- Sensor Synchronization -->
@@ -566,7 +569,6 @@
     <string name="snsr_step_counter_test">Step Counter and Detector Tests</string>
     <string name="snsr_step_counter_test_walking">Once the test begins, you will need to walk, and tap on the screen with each step you take.</string>
     <string name="snsr_step_counter_test_still">Once the test begins, you will need to remain still and hold the device still in your hand.</string>
-    <string name="snsr_step_counter_test_waving">Once the test begins, you will need to wave the device in your hand throughout the test.</string>
     <string name="snsr_step_counter_expected_steps">At least %1$d steps are expected to be reported. Reported=%2$d.</string>
     <string name="snsr_step_counter_detected_reported">Steps reported by user=%1$d. Steps counted=%2$d. Delta=%3$d. Tolerance=%4$d.</string>
     <string name="snsr_step_detector_detected_reported">Steps reported by user=%1$d. Steps detected=%2$d. Delta=%3$d. Tolerance=%4$d.</string>
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 945e9ab..dfcf120 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
@@ -107,10 +107,11 @@
 
     private String delayedVerifyMeasurements(int descriptionResId, float ... expectations)
             throws Throwable {
-        appendText(descriptionResId);
-        appendText(R.string.snsr_test_play_sound);
-        waitForUser();
-        Thread.sleep(TimeUnit.MILLISECONDS.convert(10, TimeUnit.SECONDS));
+        SensorTestLogger logger = getTestLogger();
+        logger.logInstructions(descriptionResId);
+        logger.logWaitForSound();
+        waitForUserToBegin();
+        Thread.sleep(TimeUnit.MILLISECONDS.convert(7, TimeUnit.SECONDS));
 
         try {
             return verifyMeasurements(expectations);
@@ -121,9 +122,10 @@
 
     private String verifyMeasurements(int descriptionResId, float ... expectations)
             throws Throwable {
-        appendText(descriptionResId);
-        appendText(R.string.snsr_device_steady);
-        waitForUser();
+        SensorTestLogger logger = getTestLogger();
+        logger.logInstructions(descriptionResId);
+        logger.logInstructions(R.string.snsr_device_steady);
+        waitForUserToBegin();
 
         return verifyMeasurements(expectations);
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerTestActivity.java
index e350f16..0d4f755 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerTestActivity.java
@@ -18,6 +18,7 @@
 
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
+import com.android.cts.verifier.sensors.renderers.GLArrowSensorTestRenderer;
 
 import android.content.Context;
 import android.hardware.Sensor;
@@ -30,7 +31,10 @@
  * CTS Verifier case for verifying correct integration of accelerometer.
  * Displays a wedge using OpenGL that, on a correctly-integrated device, always
  * points down.
+ *
+ * @deprecated It has been replaced by {@link AccelerometerMeasurementTestActivity}
  */
+@Deprecated
 public class AccelerometerTestActivity extends PassFailButtons.Activity {
     private GLSurfaceView mGLSurfaceView;
 
@@ -44,7 +48,8 @@
 
         mSensorManager = (SensorManager) getApplicationContext().getSystemService(
                 Context.SENSOR_SERVICE);
-        GLArrowSensorTestRenderer renderer = new GLArrowSensorTestRenderer(this, Sensor.TYPE_ACCELEROMETER);
+        GLArrowSensorTestRenderer renderer =
+                new GLArrowSensorTestRenderer(this, Sensor.TYPE_ACCELEROMETER);
         mListener = renderer;
 
         setContentView(R.layout.pass_fail_gl);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GLArrowSensorTestRenderer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GLArrowSensorTestRenderer.java
deleted file mode 100644
index fb20ac6..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GLArrowSensorTestRenderer.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.verifier.sensors;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.nio.ShortBuffer;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.opengl.GLSurfaceView;
-import android.opengl.GLU;
-import android.opengl.GLUtils;
-
-import com.android.cts.verifier.R;
-
-public class GLArrowSensorTestRenderer implements GLSurfaceView.Renderer, SensorEventListener {
-
-    /**
-     * A representation of a 3D triangular wedge or arrowhead shape, suitable
-     * for pointing a direction.
-     */
-    private static class Wedge {
-        private final static int VERTS = 6;
-
-        /**
-         * Storage for the vertices.
-         */
-        private FloatBuffer mFVertexBuffer;
-
-        /**
-         * Storage for the drawing sequence of the vertices. This contains
-         * integer indices into the mFVertextBuffer structure.
-         */
-        private ShortBuffer mIndexBuffer;
-
-        /**
-         * Storage for the texture used on the surface of the wedge.
-         */
-        private FloatBuffer mTexBuffer;
-
-        public Wedge() {
-            // Buffers to be passed to gl*Pointer() functions
-            // must be direct & use native ordering
-
-            ByteBuffer vbb = ByteBuffer.allocateDirect(VERTS * 6 * 4);
-            vbb.order(ByteOrder.nativeOrder());
-            mFVertexBuffer = vbb.asFloatBuffer();
-
-            ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
-            tbb.order(ByteOrder.nativeOrder());
-            mTexBuffer = tbb.asFloatBuffer();
-
-            ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 8 * 2);
-            ibb.order(ByteOrder.nativeOrder());
-            mIndexBuffer = ibb.asShortBuffer();
-
-            /**
-             * Coordinates of the vertices making up a simple wedge. Six total
-             * vertices, representing two isosceles triangles, side by side,
-             * centered on the origin separated by 0.25 units, with elongated
-             * ends pointing down the negative Z axis.
-             */
-            float[] coords;
-            if (GLArrowSensorTestRenderer.mSensorType == Sensor.TYPE_ACCELEROMETER) {
-                float[] verts = {
-                        // X, Y, Z
-                        -0.125f, -0.25f, -0.25f,
-                        -0.125f, 0.25f, -0.25f,
-                        -0.125f, 0.0f, 0.559016994f,
-                        0.125f, -0.25f, -0.25f,
-                        0.125f, 0.25f, -0.25f,
-                        0.125f, 0.0f, 0.559016994f,
-                };
-                coords = verts.clone();
-            } else {
-                float[] verts = {
-                        // X, Y, Z
-                        -0.25f, -0.25f, -0.125f,
-                        -0.25f, 0.25f, -0.125f,
-                        0.559016994f, 0.0f, -0.125f,
-                        -0.25f, -0.25f, 0.125f,
-                        -0.25f, 0.25f, 0.125f,
-                        0.559016994f, 0.0f, 0.125f,
-                };
-                coords = verts.clone();
-            }
-            
-            for (int i = 0; i < VERTS; i++) {
-                for (int j = 0; j < 3; j++) {
-                    mFVertexBuffer.put(coords[i * 3 + j] * 2.0f);
-                }
-            }
-
-            for (int i = 0; i < VERTS; i++) {
-                for (int j = 0; j < 2; j++) {
-                    mTexBuffer.put(coords[i * 3 + j] * 2.0f + 0.5f);
-                }
-            }
-
-            // left face
-            mIndexBuffer.put((short) 0);
-            mIndexBuffer.put((short) 1);
-            mIndexBuffer.put((short) 2);
-
-            // right face
-            mIndexBuffer.put((short) 5);
-            mIndexBuffer.put((short) 4);
-            mIndexBuffer.put((short) 3);
-
-            // top side, 2 triangles to make rect
-            mIndexBuffer.put((short) 2);
-            mIndexBuffer.put((short) 5);
-            mIndexBuffer.put((short) 3);
-            mIndexBuffer.put((short) 3);
-            mIndexBuffer.put((short) 0);
-            mIndexBuffer.put((short) 2);
-
-            // bottom side, 2 triangles to make rect
-            mIndexBuffer.put((short) 5);
-            mIndexBuffer.put((short) 2);
-            mIndexBuffer.put((short) 1);
-            mIndexBuffer.put((short) 1);
-            mIndexBuffer.put((short) 4);
-            mIndexBuffer.put((short) 5);
-
-            // base, 2 triangles to make rect
-            mIndexBuffer.put((short) 0);
-            mIndexBuffer.put((short) 3);
-            mIndexBuffer.put((short) 4);
-            mIndexBuffer.put((short) 4);
-            mIndexBuffer.put((short) 1);
-            mIndexBuffer.put((short) 0);
-
-            mFVertexBuffer.position(0);
-            mTexBuffer.position(0);
-            mIndexBuffer.position(0);
-        }
-
-        public void draw(GL10 gl) {
-            gl.glFrontFace(GL10.GL_CCW);
-            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
-            gl.glEnable(GL10.GL_TEXTURE_2D);
-            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
-            gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
-        }
-    }
-
-    /**
-     * A representation of the Z-axis in vector form.
-     */
-    protected static final float[] Z_AXIS = new float[] {
-            0, 0, 1
-    };
-
-    /**
-     * Computes the cross product of two vectors, storing the resulting
-     * pseudovector in out. All arrays must be length 3 or more, and out is
-     * overwritten.
-     * 
-     * @param left the left operand of the cross product
-     * @param right the right operand of the cross product
-     * @param out the array into which to store the cross-product pseudovector's
-     *            data
-     */
-    public static void crossProduct(float[] left, float[] right, float[] out) {
-        out[0] = left[1] * right[2] - left[2] * right[1];
-        out[1] = left[2] * right[0] - left[0] * right[2];
-        out[2] = left[0] * right[1] - left[1] * right[0];
-    }
-
-    /**
-     * Computes the dot product of two vectors.
-     * 
-     * @param left the first dot product operand
-     * @param right the second dot product operand
-     * @return the dot product of left and right
-     */
-    public static float dotProduct(float[] left, float[] right) {
-        return left[0] * right[0] + left[1] * right[1] + left[2] * right[2];
-    }
-
-    /**
-     * Normalizes the input vector into a unit vector.
-     * 
-     * @param vector the vector to normalize. Contents are overwritten.
-     */
-    public static void normalize(float[] vector) {
-        double mag = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2]
-                * vector[2]);
-        vector[0] /= mag;
-        vector[1] /= mag;
-        vector[2] /= mag;
-    }
-
-    /**
-     * The angle around mCrossProd to rotate to align Z-axis with gravity.
-     */
-    protected float mAngle;
-
-    private Context mContext;
-
-    /**
-     * The (pseudo)vector around which to rotate to align Z-axis with gravity.
-     */
-    protected float[] mCrossProd = new float[3];
-
-    private int mTextureID;
-    private static int mSensorType;
-
-    private Wedge mWedge;
-
-    /**
-     * It's a constructor. Can you dig it?
-     * 
-     * @param context the Android Context that owns this renderer
-     * @param type of arrow. Possible values: 0 = points towards gravity. 1 =
-     *            points towards reference North
-     */
-    public GLArrowSensorTestRenderer(Context context, int type) {
-        mContext = context;
-        mSensorType = type;
-        mWedge = new Wedge();
-    }
-
-    public void onAccuracyChanged(Sensor arg0, int arg1) {
-        // no-op
-    }
-
-    /**
-     * Actually draws the wedge.
-     */
-    public void onDrawFrame(GL10 gl) {
-        // set up the texture for drawing
-        gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);
-        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
-        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
-        gl.glActiveTexture(GL10.GL_TEXTURE0);
-        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
-        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
-        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
-
-        // clear the screen and draw
-        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-        gl.glMatrixMode(GL10.GL_MODELVIEW);
-        gl.glLoadIdentity();
-        if(mSensorType==Sensor.TYPE_ACCELEROMETER) {
-            gl.glRotatef(-mAngle * 180 / (float) Math.PI, mCrossProd[0], mCrossProd[1], mCrossProd[2]);
-        } else {
-            gl.glMultMatrixf(mRotationMatrix, 0);
-        }
-        mWedge.draw(gl);
-    }
-
-    private final float[] mRotationMatrix = new float[16];
-
-    public void onSensorChanged(SensorEvent event) {
-        int type = event.sensor.getType();
-        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
-            /*
-             * For this test we want *only* accelerometer data, so we can't use
-             * the convenience methods on SensorManager; so compute manually.
-             */
-            normalize(event.values);
-
-            /*
-             * Because we need to invert gravity (because the accelerometer
-             * vector actually points up), that constitutes a 180-degree
-             * rotation around X, which means we need to invert Y.
-             */
-            event.values[1] *= -1;
-
-            crossProduct(event.values, Z_AXIS, mCrossProd);
-            mAngle = (float) Math.acos(dotProduct(event.values, Z_AXIS));
-        } else if (type == Sensor.TYPE_ROTATION_VECTOR
-                || type == Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR
-                || type == Sensor.TYPE_GAME_ROTATION_VECTOR) {
-            float[] rotationMatrixTmp = new float[16];
-
-            SensorManager.getRotationMatrixFromVector(rotationMatrixTmp, event.values);
-            SensorManager.remapCoordinateSystem(rotationMatrixTmp,
-                    SensorManager.AXIS_MINUS_X, SensorManager.AXIS_Y, mRotationMatrix);
-        }
-
-    }
-
-    public void onSurfaceChanged(GL10 gl, int w, int h) {
-        gl.glViewport(0, 0, w, h);
-        float ratio = (float) w / h;
-        gl.glMatrixMode(GL10.GL_PROJECTION);
-        gl.glLoadIdentity();
-        gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
-        GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
-    }
-
-    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
-        // set up general OpenGL config
-        gl.glClearColor(0.6f, 0f, 0.4f, 1); // a nice purpley magenta
-        gl.glShadeModel(GL10.GL_SMOOTH);
-        gl.glEnable(GL10.GL_DEPTH_TEST);
-        gl.glEnable(GL10.GL_TEXTURE_2D);
-
-        // create the texture we use on the wedge
-        int[] textures = new int[1];
-        gl.glGenTextures(1, textures, 0);
-        mTextureID = textures[0];
-
-        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
-        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
-        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
-        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
-        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
-        gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
-
-        InputStream is = mContext.getResources().openRawResource(R.raw.sns_texture);
-        Bitmap bitmap;
-        try {
-            bitmap = BitmapFactory.decodeStream(is);
-        } finally {
-            try {
-                is.close();
-            } catch (IOException e) {
-                // Ignore.
-            }
-        }
-
-        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
-        bitmap.recycle();
-    }
-}
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 11a741b..13a695c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
@@ -18,119 +18,153 @@
 
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.sensors.base.SensorCtsVerifierTestActivity;
+import com.android.cts.verifier.sensors.renderers.GLRotationGuideRenderer;
 
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
 import android.hardware.cts.helpers.TestSensorEnvironment;
 import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
-import android.hardware.cts.helpers.sensorverification.SigNumVerification;
+import android.hardware.cts.helpers.sensorverification.GyroscopeIntegrationVerification;
+
+import java.util.concurrent.TimeUnit;
 
 /**
- * Semi-automated test that focuses on characteristics associated with Accelerometer measurements.
+ * Semi-automated test that focuses on characteristics associated with Gyroscope measurements.
  */
 public class GyroscopeMeasurementTestActivity extends SensorCtsVerifierTestActivity {
+    private static final float THRESHOLD_AXIS_UNDER_ROTATION_DEG = 10.0f;
+    private static final float THRESHOLD_AXIS_UNDER_NO_ROTATION_DEG = 50.0f;
+    private static final int ROTATE_360_DEG = 360;
+    private static final int ROTATION_COLLECTION_SEC = 10;
+
+    private static final int X_AXIS = 0;
+    private static final int Y_AXIS = 1;
+    private static final int Z_AXIS = 2;
+
+    private final GLRotationGuideRenderer mRenderer = new GLRotationGuideRenderer();
+
     public GyroscopeMeasurementTestActivity() {
         super(GyroscopeMeasurementTestActivity.class);
     }
 
     @Override
     protected void activitySetUp() {
-        appendText(R.string.snsr_gyro_device_placement);
+        getTestLogger().logInstructions(R.string.snsr_gyro_device_placement);
+        waitForUserToContinue();
+        initializeGlSurfaceView(mRenderer);
+    }
+
+    @Override
+    protected void activityCleanUp() {
+        closeGlSurfaceView();
     }
 
     public String testDeviceStatic() throws Throwable {
         return verifyMeasurements(
                 R.string.snsr_gyro_device_static,
-                true /*portrait*/,
-                0, 0, 0);
+                -1 /* rotationAxis */,
+                0 /* expectationDeg */);
     }
 
     public String testRotateClockwise() throws Throwable {
-        return verifyMeasurements(
-                R.string.snsr_gyro_rotate_clockwise,
-                true /*portrait*/,
-                0, 0, -1);
+        return verifyMeasurements(R.string.snsr_gyro_rotate_device, Z_AXIS, -ROTATE_360_DEG);
     }
 
     public String testRotateCounterClockwise() throws Throwable {
-        return verifyMeasurements(
-                R.string.snsr_gyro_rotate_counter_clockwise,
-                true /*portrait*/,
-                0, 0, +1);
+        return verifyMeasurements(R.string.snsr_gyro_rotate_device, Z_AXIS, ROTATE_360_DEG);
     }
 
     public String testRotateRightSide() throws Throwable {
-        return verifyMeasurements(
-                R.string.snsr_gyro_rotate_right_side,
-                true /*portrait*/,
-                0, +1, 0);
+        return verifyMeasurements(R.string.snsr_gyro_rotate_device, Y_AXIS, ROTATE_360_DEG);
     }
 
     public String testRotateLeftSide() throws Throwable {
-        return verifyMeasurements(
-                R.string.snsr_gyro_rotate_left_side,
-                true /*portrait*/,
-                0, -1, 0);
+        return verifyMeasurements(R.string.snsr_gyro_rotate_device, Y_AXIS, -ROTATE_360_DEG);
     }
 
     public String testRotateTopSide() throws Throwable {
-        return verifyMeasurements(
-                R.string.snsr_gyro_rotate_top_side,
-                false /*portrait*/,
-                -1, 0, 0);
+        return verifyMeasurements(R.string.snsr_gyro_rotate_device, X_AXIS, -ROTATE_360_DEG);
     }
 
     public String testRotateBottomSide() throws Throwable {
-        return verifyMeasurements(
-                R.string.snsr_gyro_rotate_bottom_side,
-                false /*portrait*/,
-                +1, 0, 0);
+        return verifyMeasurements(R.string.snsr_gyro_rotate_device, X_AXIS, ROTATE_360_DEG);
     }
 
     /**
-     * This test verifies that the Gyroscope measures angular speeds with the right direction.
-     * The test does not measure the range or scale, apart from filtering small readings that
-     * deviate from zero.
+     * This test verifies that the Gyroscope measures the appropriate angular position.
      *
-     * The test takes a set of samples from the sensor under test and calculates the mean of each
-     * axis that the sensor data collects. It then compares it against the test expectations that
-     * are represented by signed values. It verifies that the readings have the right direction.
-
-     * The reference values are coupled to the orientation of the device. The test is susceptible to
-     * errors when the device is not oriented properly, the device has moved to slowly, or it has
-     * moved in more than the direction conducted.
-     *
-     * The error message associated with the test provides the required data needed to identify any
-     * possible issue. It provides:
-     * - the thread id on which the failure occurred
-     * - the sensor type and sensor handle that caused the failure
-     * - the values representing the expectation of the test
-     * - the mean of values sampled from the sensor
+     * The test takes a set of samples from the sensor under test and calculates the angular
+     * position for each axis that the sensor data collects. It then compares it against the test
+     * expectations that are represented by signed values. It verifies that the readings have the
+     * right magnitude.
      */
-    private String verifyMeasurements(
-            int scenarioInstructionsResId,
-            boolean usePortraitOrientation,
-            int ... expectations) throws Throwable {
-        if (usePortraitOrientation) {
-            appendText(R.string.snsr_orientation_portrait);
-        } else {
-            appendText(R.string.snsr_orientation_landscape);
-        }
-        appendText(scenarioInstructionsResId);
-        waitForUser();
-
-        Thread.sleep(500 /*ms*/);
+    private String verifyMeasurements(int instructionsResId, int rotationAxis, int expectationDeg)
+            throws Throwable {
+        SensorTestLogger logger = getTestLogger();
+        setRendererRotation(rotationAxis, expectationDeg >= 0);
+        logger.logInstructions(instructionsResId);
+        waitForUserToBegin();
+        logger.logWaitForSound();
 
         TestSensorEnvironment environment = new TestSensorEnvironment(
                 getApplicationContext(),
                 Sensor.TYPE_GYROSCOPE,
                 SensorManager.SENSOR_DELAY_FASTEST);
-        TestSensorOperation verifySignum =
-                new TestSensorOperation(environment, 100 /* event count */);
-        verifySignum.addVerification(new SigNumVerification(
-                expectations,
-                new float[]{0.2f, 0.2f, 0.2f} /*noiseThreshold*/));
-        verifySignum.execute();
+        TestSensorOperation sensorOperation =
+                new TestSensorOperation(environment, ROTATION_COLLECTION_SEC, TimeUnit.SECONDS);
+
+        int gyroscopeAxes = environment.getSensorAxesCount();
+        int[] expectationsDeg = getExpectationsDeg(gyroscopeAxes, rotationAxis, expectationDeg);
+        float[] thresholdsDeg = getThresholdsDeg(gyroscopeAxes, rotationAxis);
+        GyroscopeIntegrationVerification integrationVerification =
+                new GyroscopeIntegrationVerification(expectationsDeg, thresholdsDeg);
+        sensorOperation.addVerification(integrationVerification);
+
+        try {
+            sensorOperation.execute();
+        } finally {
+            playSound();
+        }
         return null;
     }
+
+    private int[] getExpectationsDeg(int axes, int rotationAxis, int expectationDeg) {
+        int[] expectationsDeg = new int[axes];
+        for (int i = 0; i < axes; ++i) {
+            // tests assume that rotation is expected on one axis at a time
+            expectationsDeg[i] = (i == rotationAxis) ? expectationDeg : 0;
+        }
+        return expectationsDeg;
+    }
+
+    private float[] getThresholdsDeg(int axes, int rotationAxis) {
+        float[] thresholdsDeg = new float[axes];
+        for (int i = 0; i < axes; ++i) {
+            // tests set a high threshold on the axes where rotation is not expected, to account
+            // for movement from the operator
+            // the rotation axis has a lower threshold to ensure the gyroscope's accuracy
+            thresholdsDeg[i] = (i == rotationAxis)
+                    ? THRESHOLD_AXIS_UNDER_ROTATION_DEG
+                    : THRESHOLD_AXIS_UNDER_NO_ROTATION_DEG;
+        }
+        return thresholdsDeg;
+    }
+
+    private void setRendererRotation(int rotationAxis, boolean positiveRotation) {
+        int axis1 = 0;
+        int axis2 = 0;
+        int axis3 = 0;
+        switch (rotationAxis) {
+            case X_AXIS:
+                axis1 = positiveRotation ? 1 : -1;
+                break;
+            case Y_AXIS:
+                axis2 = positiveRotation ? 1 : -1;
+                break;
+            case Z_AXIS:
+                axis3 = positiveRotation ? 1 : -1;
+                break;
+        }
+        mRenderer.setRotation(axis1, axis2, axis3);
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeTestActivity.java
index ea6ca4c..f886e75 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeTestActivity.java
@@ -18,6 +18,7 @@
 
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
+import com.android.cts.verifier.sensors.renderers.GLRotationGuideRenderer;
 
 import android.app.AlertDialog;
 import android.content.Intent;
@@ -26,41 +27,29 @@
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.opengl.GLSurfaceView;
-import android.opengl.GLU;
 import android.os.Bundle;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.TextView;
 
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.nio.ShortBuffer;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
 /**
  * Manual test for testing the gyroscope sensor. This test consists of 6 steps for all the
  * different ways to rotate the device along the x, y, and z axis. It also raises a warning
  * if the values seem to high and may be degrees.
+ *
+ * @deprecated It has been replaced by {@link GyroscopeMeasurementTestActivity}
  */
+@Deprecated
 public class GyroscopeTestActivity extends PassFailButtons.Activity {
 
     private static final int NUM_STAGES = 6;
     private static final String STAGE_INDEX_EXTRA = "stageIndex";
 
-    private static final int BACKGROUND_BLACK = 0;
-    private static final int BACKGROUND_RED = 1;
-    private static final int BACKGROUND_GREEN = 2;
-
-    private AtomicInteger mBackgroundColor = new AtomicInteger(BACKGROUND_BLACK);
-
     private SensorManager mSensorManager;
     private Sensor mSensor;
     private SensorListener mSensorListener;
     private GLSurfaceView mGLSurfaceView;
+    private GLRotationGuideRenderer mRenderer;
     private TextView mProgressText;
     private TextView mSensorText;
 
@@ -89,8 +78,9 @@
                 settings.mExpectPositiveValue);
 
         mGLSurfaceView = (GLSurfaceView) findViewById(R.id.gl_surface_view);
-        mGLSurfaceView.setRenderer(new RotationGuideRenderer(settings.mRotateX, settings.mRotateY,
-                settings.mRotateZ));
+        mRenderer = new GLRotationGuideRenderer();
+        mRenderer.setRotation(settings.mRotateX, settings.mRotateY, settings.mRotateZ);
+        mGLSurfaceView.setRenderer(mRenderer);
 
         mProgressText = (TextView) findViewById(R.id.progress);
         mProgressText.setText(String.format(getString(R.string.snsr_gyro_test_progress),
@@ -169,168 +159,6 @@
         mSensorManager.unregisterListener(mSensorListener, mSensor);
     }
 
-    /** Renders a spinning block to indicate how the device should be rotated in the test. */
-    class RotationGuideRenderer implements GLSurfaceView.Renderer {
-
-        private static final double ANGLE_INCREMENT = 1.0;
-
-        private final Monolith mMonolith = new Monolith();
-
-        private float mAngle = 0.0f;
-
-        private float mRotateX;
-
-        private float mRotateY;
-
-        private float mRotateZ;
-
-        public RotationGuideRenderer(float rotateX, float rotateY, float rotateZ) {
-            mRotateX = rotateX;
-            mRotateY = rotateY;
-            mRotateZ = rotateZ;
-        }
-
-        @Override
-        public void onDrawFrame(GL10 gl) {
-            clearBackground(gl);
-            gl.glMatrixMode(GL10.GL_MODELVIEW);
-            gl.glLoadIdentity();
-            gl.glRotatef(mAngle, mRotateX, mRotateY, mRotateZ);
-            mMonolith.draw(gl);
-            mAngle += ANGLE_INCREMENT;
-        }
-
-        private void clearBackground(GL10 gl) {
-            switch (mBackgroundColor.get()) {
-                case BACKGROUND_GREEN:
-                    gl.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
-                    break;
-
-                case BACKGROUND_RED:
-                    gl.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
-                    break;
-
-                default:
-                    gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-                    break;
-            }
-            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-        }
-
-        @Override
-        public void onSurfaceChanged(GL10 gl, int width, int height) {
-            gl.glViewport(0, 0, width, height);
-            gl.glMatrixMode(GL10.GL_PROJECTION);
-            gl.glLoadIdentity();
-            float ratio = (float) width / height;
-            gl.glFrustumf(-ratio, ratio, -1, 1, 3, 15);
-            GLU.gluLookAt(gl, 0, 0, 10, 0, 0, 0, 0, 1, 0);
-        }
-
-        @Override
-        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
-            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
-            gl.glEnable(GL10.GL_LIGHTING);
-            gl.glEnable(GL10.GL_LIGHT0);
-            gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, new float[] {0.75f, 0.75f, 0.75f, 1f}, 0);
-        }
-    }
-
-    /** Rectangular block that is rotated by {@link RotationGuideRenderer}. */
-    class Monolith {
-
-        private static final int NUM_VERTICES = 8;
-
-        private static final int NUM_INDICES = 36;
-
-        private FloatBuffer mVertexBuffer;
-
-        private ShortBuffer mIndexBuffer;
-
-        public Monolith() {
-            mVertexBuffer = ByteBuffer.allocateDirect(NUM_VERTICES * 3 * 4)
-                    .order(ByteOrder.nativeOrder())
-                    .asFloatBuffer();
-
-            float[] coordinates = {
-                    -0.65f, -1, 0.2f,
-                    -0.65f, 1, 0.2f,
-                    0.65f, 1, 0.2f,
-                    0.65f, -1, 0.2f,
-
-                    -0.65f, -1, -0.2f,
-                    -0.65f, 1, -0.2f,
-                    0.65f, 1, -0.2f,
-                    0.65f, -1, -0.2f,
-            };
-
-            for (int i = 0; i < coordinates.length; i++) {
-                mVertexBuffer.put(coordinates[i]);
-            }
-
-            mIndexBuffer = ByteBuffer.allocateDirect(NUM_INDICES * 2)
-                    .order(ByteOrder.nativeOrder())
-                    .asShortBuffer();
-
-            // Front
-            mIndexBuffer.put((short) 0);
-            mIndexBuffer.put((short) 1);
-            mIndexBuffer.put((short) 2);
-            mIndexBuffer.put((short) 0);
-            mIndexBuffer.put((short) 2);
-            mIndexBuffer.put((short) 3);
-
-            // Back
-            mIndexBuffer.put((short) 7);
-            mIndexBuffer.put((short) 6);
-            mIndexBuffer.put((short) 5);
-            mIndexBuffer.put((short) 7);
-            mIndexBuffer.put((short) 5);
-            mIndexBuffer.put((short) 4);
-
-            // Right
-            mIndexBuffer.put((short) 3);
-            mIndexBuffer.put((short) 2);
-            mIndexBuffer.put((short) 6);
-            mIndexBuffer.put((short) 3);
-            mIndexBuffer.put((short) 6);
-            mIndexBuffer.put((short) 7);
-
-            // Left
-            mIndexBuffer.put((short) 4);
-            mIndexBuffer.put((short) 5);
-            mIndexBuffer.put((short) 1);
-            mIndexBuffer.put((short) 4);
-            mIndexBuffer.put((short) 1);
-            mIndexBuffer.put((short) 0);
-
-            // Top
-            mIndexBuffer.put((short) 1);
-            mIndexBuffer.put((short) 5);
-            mIndexBuffer.put((short) 6);
-            mIndexBuffer.put((short) 1);
-            mIndexBuffer.put((short) 6);
-            mIndexBuffer.put((short) 2);
-
-            // Bottom
-            mIndexBuffer.put((short) 3);
-            mIndexBuffer.put((short) 7);
-            mIndexBuffer.put((short) 4);
-            mIndexBuffer.put((short) 3);
-            mIndexBuffer.put((short) 4);
-            mIndexBuffer.put((short) 0);
-
-            mVertexBuffer.position(0);
-            mIndexBuffer.position(0);
-        }
-
-        public void draw(GL10 gl) {
-            gl.glColor4f(0.5f, 0.5f, 0.5f, 1f);
-            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
-            gl.glDrawElements(GL10.GL_TRIANGLES, NUM_INDICES, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
-        }
-    }
-
     class SensorListener implements SensorEventListener {
 
         /** Throw away other events that are smaller than this. */
@@ -350,18 +178,33 @@
             float value = event.values[mEventIndex];
             if (value > MOVING_AMOUNT) {
                 if (mExpectPositive) {
-                    updateWidgets(value, BACKGROUND_GREEN, R.drawable.fs_good);
+                    updateWidgets(
+                            value,
+                            GLRotationGuideRenderer.BACKGROUND_GREEN,
+                            R.drawable.fs_good);
                 } else {
-                    updateWidgets(value, BACKGROUND_RED, R.drawable.fs_error);
+                    updateWidgets(
+                            value,
+                            GLRotationGuideRenderer.BACKGROUND_RED,
+                            R.drawable.fs_error);
                 }
             } else if (value < -MOVING_AMOUNT) {
                 if (mExpectPositive) {
-                    updateWidgets(value, BACKGROUND_RED, R.drawable.fs_error);
+                    updateWidgets(
+                            value,
+                            GLRotationGuideRenderer.BACKGROUND_RED,
+                            R.drawable.fs_error);
                 } else {
-                    updateWidgets(value, BACKGROUND_GREEN, R.drawable.fs_good);
+                    updateWidgets(
+                            value,
+                            GLRotationGuideRenderer.BACKGROUND_GREEN,
+                            R.drawable.fs_good);
                 }
             } else {
-                updateWidgets(value, BACKGROUND_BLACK, R.drawable.fs_indeterminate);
+                updateWidgets(
+                        value,
+                        GLRotationGuideRenderer.BACKGROUND_BLACK,
+                        R.drawable.fs_indeterminate);
             }
 
             if (value > 10) {
@@ -371,7 +214,7 @@
 
         void updateWidgets(float sensorValue, int backgroundColor, int icon) {
             synchronized (GyroscopeTestActivity.this) {
-                mBackgroundColor.set(backgroundColor);
+                mRenderer.setBackgroundColor(backgroundColor);
             }
             mSensorText.setText(String.format("%+.2f", sensorValue));
             mSensorText.setCompoundDrawablesWithIntrinsicBounds(0, 0, icon, 0);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RotationVectorTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RotationVectorTestActivity.java
index 6526ed1..cd94128 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RotationVectorTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RotationVectorTestActivity.java
@@ -18,6 +18,7 @@
 
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.sensors.base.SensorCtsVerifierTestActivity;
+import com.android.cts.verifier.sensors.renderers.GLArrowSensorTestRenderer;
 
 import junit.framework.Assert;
 
@@ -27,10 +28,9 @@
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.hardware.cts.helpers.SensorNotSupportedException;
-import android.opengl.GLSurfaceView;
+import android.hardware.cts.helpers.SensorTestStateNotSupportedException;
 import android.os.Bundle;
 import android.util.Log;
-import android.view.View;
 
 import java.util.concurrent.TimeUnit;
 
@@ -46,10 +46,9 @@
         extends SensorCtsVerifierTestActivity
         implements SensorEventListener {
     public RotationVectorTestActivity() {
-        super(RotationVectorTestActivity.class, R.layout.snsr_rotvec);
+        super(RotationVectorTestActivity.class);
     }
 
-    private GLSurfaceView mGLSurfaceView;
     private SensorManager mSensorManager;
     private SensorEventListener mListener;
 
@@ -82,10 +81,11 @@
                 && mSensor[GEOMAGNETIC_ROTATION_VECTOR_INDEX] == null
                 && mSensor[GAME_ROTATION_VECTOR_INDEX] == null) {
             // if none of the sensors is supported, skip the test by throwing an exception
-            throw new IllegalStateException("Rotation vectors are not supported.");
+            throw new SensorTestStateNotSupportedException("Rotation vectors are not supported.");
         }
 
         // TODO: take reference value automatically when device is 'still'
+        clearText();
         appendText(R.string.snsr_rotation_vector_set_reference);
         waitForUser();
 
@@ -107,12 +107,7 @@
         waitForUser();
 
         clearText();
-        runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mGLSurfaceView.setVisibility(View.GONE);
-            }
-        });
+        closeGlSurfaceView();
 
         float[] finalVector = new float[16];
         for (int i = 0; i < MAX_SENSORS_AVAILABLE; ++i) {
@@ -183,8 +178,7 @@
                 new GLArrowSensorTestRenderer(this, Sensor.TYPE_ROTATION_VECTOR);
         mListener = renderer;
 
-        mGLSurfaceView = (GLSurfaceView) findViewById(R.id.gl_surface_view);
-        mGLSurfaceView.setRenderer(renderer);
+        initializeGlSurfaceView(renderer);
     }
 
     @Override
@@ -192,13 +186,11 @@
         super.onPause();
         mSensorManager.unregisterListener(mListener);
         mSensorManager.unregisterListener(this);
-        mGLSurfaceView.onPause();
     }
 
     @Override
     protected void onResume() {
         super.onResume();
-        mGLSurfaceView.onResume();
 
         // listener for rendering
         boolean renderListenerRegistered = false;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SensorSynchronizationTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SensorSynchronizationTestActivity.java
index eeb4bf0..b5ffc2a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SensorSynchronizationTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SensorSynchronizationTestActivity.java
@@ -1,7 +1,7 @@
 
 package com.android.cts.verifier.sensors;
 
-import com.android.cts.verifier.sensors.base.BaseSensorSemiAutomatedTestActivity;
+import com.android.cts.verifier.sensors.base.SensorCtsVerifierTestActivity;
 
 import junit.framework.Assert;
 
@@ -25,8 +25,11 @@
  */
 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
 public class SensorSynchronizationTestActivity
-        extends BaseSensorSemiAutomatedTestActivity
+        extends SensorCtsVerifierTestActivity
         implements SensorEventListener {
+    public SensorSynchronizationTestActivity() {
+        super(SensorSynchronizationTestActivity.class);
+    }
 
     private final double NANOS_PER_MILLI = 1e6;
     private final int DATA_COLLECTION_TIME_IN_MS = 5000;
@@ -132,7 +135,7 @@
         Assert.assertTrue("Gyroscope did not detect any movement", gyrMovementDetected);
     }
 
-    private void executeCrossSensorTest() throws Throwable {
+    public String testCrossSensorSynchronization() throws Throwable {
         appendText("This test provides a rough indication of cross-sensor timestamp synchronization.");
         appendText("Hold device still in hand and click 'Next'");
         waitForUser();
@@ -144,6 +147,7 @@
 
         stopDataCollection();
         analyzeData();
+        return null;
     }
 
     protected double angleBetweenVecsDegrees(float[] vec1, float[] vec2) {
@@ -156,11 +160,6 @@
     }
 
     @Override
-    protected void onRun() throws Throwable {
-        executeCrossSensorTest();
-    }
-
-    @Override
     public void onSensorChanged(SensorEvent sensorEvent) {
         mSensorEvents.add(new TestSensorEvent(sensorEvent, SystemClock.elapsedRealtimeNanos()));
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SensorValueAccuracyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SensorValueAccuracyActivity.java
index 4f20a1f..b6d7cd6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SensorValueAccuracyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SensorValueAccuracyActivity.java
@@ -58,9 +58,6 @@
     private static final float RANGE_ATMOSPHERIC_PRESSURE = 35f;
     private static final float AMBIENT_TEMPERATURE_AVERAGE = 22.5f;
     private static final float AMBIENT_TEMPERATURE_THRESHOLD = 7.5f;
-    private static final double ONE_HUNDRED_EIGHTY_DEGREES = 180.0f;
-
-    private static final double GYROSCOPE_INTEGRATION_THRESHOLD_DEGREES = 10.0f;
 
     private SensorManager mSensorManager;
 
@@ -99,7 +96,7 @@
     }
 
     public String testGyroscopeCalibratedUncalibrated() throws Throwable {
-        appendText(R.string.snsr_keep_device_rotating_clockwise);
+        getTestLogger().logInstructions(R.string.snsr_keep_device_rotating_clockwise);
         return verifyCalibratedUncalibrated(
                 Sensor.TYPE_GYROSCOPE,
                 Sensor.TYPE_GYROSCOPE_UNCALIBRATED,
@@ -107,60 +104,6 @@
     }
 
     /**
-     * Verifies that the measurements of the gyroscope correspond to predefined angular positions.
-     * The test uses a routine to integrate gyroscope's readings on a predefined rotation to
-     * ensure that it corresponds to the expected angular position.
-     */
-    // TODO: refactor the integration routine into a SensorTestVerification
-    // TODO: use the new verification in GyroscopeMeasurement tests
-    public String testGyroscopeIntegration() throws Throwable {
-        Sensor gyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
-        if (gyroscope == null) {
-            throw new SensorNotSupportedException(Sensor.TYPE_GYROSCOPE);
-        }
-
-        appendText(R.string.snsr_no_interaction);
-        String rotationInstructions = getString(
-                R.string.snsr_gyro_rotate_clockwise_integration,
-                ONE_HUNDRED_EIGHTY_DEGREES);
-        appendText(rotationInstructions);
-        waitForUser();
-
-        startDataCollection(gyroscope);
-        appendText(R.string.snsr_test_play_sound);
-        Thread.sleep(TimeUnit.SECONDS.toMillis(10));
-        stopDataCollection();
-        playSound();
-
-        // run the verification
-        double integratedGyroscope = 0;
-        long lastTimestamp = 0;
-        for (TestSensorEvent event : mSensorEvents) {
-            float[] eventValues = event.values.clone();
-            long eventTimestamp = event.timestamp;
-            if (lastTimestamp != 0) {
-                long timeDeltaNs = eventTimestamp - lastTimestamp;
-                long nanosecondsInOneSecond = TimeUnit.SECONDS.toNanos(1);
-                integratedGyroscope += eventValues[2] * timeDeltaNs / nanosecondsInOneSecond;
-            }
-            lastTimestamp = eventTimestamp;
-        }
-        integratedGyroscope = Math.toDegrees(integratedGyroscope);
-
-        String integrationMessage = String.format(
-                "Gyroscope integration expected to be=%fdeg. Found=%fdeg, Tolerance=%fdeg",
-                ONE_HUNDRED_EIGHTY_DEGREES,
-                integratedGyroscope,
-                GYROSCOPE_INTEGRATION_THRESHOLD_DEGREES);
-        Assert.assertEquals(
-                integrationMessage,
-                ONE_HUNDRED_EIGHTY_DEGREES,
-                integratedGyroscope,
-                GYROSCOPE_INTEGRATION_THRESHOLD_DEGREES);
-        return integrationMessage;
-    }
-
-    /**
      * Validates the norm of a sensor.
      */
     // TODO: fix up EventOrdering, EventGap and timestamp>0 Verifications so they can be added to
@@ -170,8 +113,8 @@
             int instructionsResId,
             float expectedNorm,
             float threshold) {
-        appendText(instructionsResId);
-        waitForUser();
+        getTestLogger().logInstructions(instructionsResId);
+        waitForUserToBegin();
 
         TestSensorEnvironment environment =
                 new TestSensorEnvironment(getApplicationContext(), sensorType, SENSOR_RATE);
@@ -208,8 +151,9 @@
             int calibratedSensorType,
             int uncalibratedSensorType,
             float threshold) throws Throwable {
-        appendText(R.string.snsr_no_interaction);
-        waitForUser();
+        SensorTestLogger logger = getTestLogger();
+        logger.logInstructions(R.string.snsr_no_interaction);
+        waitForUserToBegin();
 
         Sensor calibratedSensor = mSensorManager.getDefaultSensor(calibratedSensorType);
         if (calibratedSensor == null) {
@@ -224,7 +168,7 @@
         final long timeout = TimeUnit.SECONDS.toMillis(10);
         startDataCollection(calibratedSensor);
         startDataCollection(uncalibratedSensor);
-        appendText(R.string.snsr_test_play_sound);
+        logger.logWaitForSound();
         Thread.sleep(timeout);
         stopDataCollection();
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
index fbc56c2..a84a045 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
@@ -67,7 +67,7 @@
                 false /* vibrate */);
     }
 
-    public String testNotTriggerAfterCancell() throws Throwable {
+    public String testNotTriggerAfterCancel() throws Throwable {
         return runTest(
                 R.string.snsr_significant_motion_test_cancel,
                 false /* isMotionExpected */,
@@ -107,12 +107,13 @@
     }
 
     public String testTriggerDeactivation() throws Throwable {
-        appendText(R.string.snsr_significant_motion_test_deactivation);
-        waitForUser();
+        SensorTestLogger logger = getTestLogger();
+        logger.logInstructions(R.string.snsr_significant_motion_test_deactivation);
+        waitForUserToBegin();
 
         TriggerVerifier verifier = new TriggerVerifier();
         mSensorManager.requestTriggerSensor(verifier, mSensorSignificantMotion);
-        appendText(R.string.snsr_test_play_sound);
+        logger.logWaitForSound();
 
         // wait for the first event to trigger
         verifier.verifyEventTriggered();
@@ -137,8 +138,9 @@
             boolean isMotionExpected,
             boolean cancelEventNotification,
             boolean vibrate) throws Throwable {
-        appendText(instructionsResId);
-        waitForUser();
+        SensorTestLogger logger = getTestLogger();
+        logger.logInstructions(instructionsResId);
+        waitForUserToBegin();
 
         if (vibrate) {
             vibrate(VIBRATE_DURATION_MILLIS);
@@ -154,7 +156,7 @@
                     getString(R.string.snsr_significant_motion_cancelation),
                     mSensorManager.cancelTriggerSensor(verifier, mSensorSignificantMotion));
         }
-        appendText(R.string.snsr_test_play_sound);
+        logger.logWaitForSound();
 
         String result;
         try {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/StepCounterTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/StepCounterTestActivity.java
index f66d754..76d12d9 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/StepCounterTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/StepCounterTestActivity.java
@@ -117,13 +117,6 @@
                 true /* vibrate */);
     }
 
-    public String testWaving() throws Throwable {
-       return runTest(
-               R.string.snsr_step_counter_test_waving,
-               0 /* expectedSteps */,
-               false /* vibrate */);
-    }
-
     /**
      * @param instructionsResId Resource ID containing instruction to be shown to testers
      * @param expectedSteps Number of steps expected in this test
@@ -146,7 +139,7 @@
             vibrate(VIBRATE_PATTERN);
         }
         startMeasurements();
-        appendText(R.string.snsr_test_play_sound);
+        getTestLogger().logWaitForSound();
 
         Thread.sleep(TimeUnit.SECONDS.toMillis(TEST_DURATION_SECONDS));
         mCheckForMotion = false;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorSemiAutomatedTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorSemiAutomatedTestActivity.java
deleted file mode 100644
index 9f2f5c4..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorSemiAutomatedTestActivity.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 com.android.cts.verifier.sensors.base;
-
-import com.android.cts.verifier.sensors.reporting.SensorTestDetails;
-
-import android.hardware.cts.helpers.SensorTestStateNotSupportedException;
-
-/**
- * Base class to author a single Sensor semi-automated test case.
- *
- * @deprecated use {@link BaseSensorTestActivity} instead.
- */
-@Deprecated
-public abstract class BaseSensorSemiAutomatedTestActivity extends BaseSensorTestActivity {
-    public BaseSensorSemiAutomatedTestActivity() {
-        super(BaseSensorSemiAutomatedTestActivity.class);
-    }
-
-    @Override
-    public SensorTestDetails executeTests() {
-        String summary = "";
-        SensorTestDetails.ResultCode resultCode = SensorTestDetails.ResultCode.PASS;
-        try {
-            onRun();
-        } catch(SensorTestStateNotSupportedException e) {
-            // the sensor state is not supported in the device, log a warning and skip the test
-            resultCode = SensorTestDetails.ResultCode.SKIPPED;
-            summary = e.getMessage();
-        } catch(Throwable e) {
-            resultCode = SensorTestDetails.ResultCode.FAIL;
-            summary = e.getMessage();
-        }
-        return new SensorTestDetails(getTestClassName(), resultCode, summary);
-    }
-
-    /**
-     * This is the method that subclasses will implement to define the operations that need to be
-     * verified.
-     * Any exception thrown will cause the test to fail, additionally mAssert can be used to verify
-     * the tests state.
-     *
-     * throws Throwable
-     */
-    @Deprecated
-    protected abstract void onRun() throws Throwable;
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java
index 68e72c3..068869f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java
@@ -30,6 +30,7 @@
 import android.hardware.cts.helpers.ActivityResultMultiplexedLatch;
 import android.hardware.cts.helpers.SensorTestStateNotSupportedException;
 import android.media.MediaPlayer;
+import android.opengl.GLSurfaceView;
 import android.os.Bundle;
 import android.os.Vibrator;
 import android.provider.Settings;
@@ -86,6 +87,9 @@
     private Button mPassButton;
     private Button mFailButton;
 
+    private GLSurfaceView mGLSurfaceView;
+    private boolean mUsingGlSurfaceView;
+
     /**
      * Constructor to be used by subclasses.
      *
@@ -93,7 +97,7 @@
      *                  implemented by subclasses.
      */
     protected BaseSensorTestActivity(Class testClass) {
-        this(testClass, R.layout.snsr_semi_auto_test);
+        this(testClass, R.layout.sensor_test);
     }
 
     /**
@@ -102,7 +106,7 @@
      * @param testClass The class that contains the tests. It is dependant on test executor
      *                  implemented by subclasses.
      * @param layoutId The Id of the layout to use for the test UI. The layout must contain all the
-     *                 elements in the base layout {@code R.layout.snsr_semi_auto_test}.
+     *                 elements in the base layout {@code R.layout.sensor_test}.
      */
     protected BaseSensorTestActivity(Class testClass, int layoutId) {
         mTestClass = testClass;
@@ -121,12 +125,29 @@
         mNextButton.setOnClickListener(this);
         mPassButton = (Button) findViewById(R.id.pass_button);
         mFailButton = (Button) findViewById(R.id.fail_button);
+        mGLSurfaceView = (GLSurfaceView) findViewById(R.id.gl_surface_view);
 
         updateNextButton(false /*enabled*/);
         new Thread(this).start();
     }
 
     @Override
+    protected void onPause() {
+        super.onPause();
+        if (mUsingGlSurfaceView) {
+            mGLSurfaceView.onPause();
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (mUsingGlSurfaceView) {
+            mGLSurfaceView.onResume();
+        }
+    }
+
+    @Override
     public void onClick(View target) {
         mSemaphore.release();
     }
@@ -146,59 +167,44 @@
      */
     @Override
     public void run() {
-        SensorTestDetails testDetails = null;
-        try {
-            mSensorFeaturesDeactivator.requestDeactivationOfFeatures();
-            activitySetUp();
-        } catch (SensorTestStateNotSupportedException e) {
-            testDetails = new SensorTestDetails(
-                    getTestClassName(),
-                    SensorTestDetails.ResultCode.SKIPPED,
-                    e.getMessage());
-        } catch (Throwable e) {
-            testDetails = new SensorTestDetails(
-                    getTestClassName(),
-                    SensorTestDetails.ResultCode.FAIL,
-                    "[ActivitySetUp] " + e.getMessage());
-        }
+        String testName = getTestClassName();
 
-        // TODO: implement execution filters:
-        //      - execute all tests and report results officially
-        //      - execute single tests or failed tests only
-        if (testDetails == null) {
-            testDetails = executeTests();
-        }
-
-        try {
-            activityCleanUp();
-            mSensorFeaturesDeactivator.requestToRestoreFeatures();
-        } catch (Throwable e) {
-            testDetails = new SensorTestDetails(
-                    getTestClassName(),
-                    SensorTestDetails.ResultCode.FAIL,
-                    "[ActivityCleanUp] " + e.getMessage());
+        // guarantee the proper clean up of tests based on the operations that successfully ran
+        SensorTestDetails testDetails = deactivateSensorFeatures();
+        if (testDetails.getResultCode() == SensorTestDetails.ResultCode.PASS) {
+            // sensor features
+            testDetails = executeActivitySetUp();
+            if (testDetails.getResultCode() == SensorTestDetails.ResultCode.PASS) {
+                // activity set up
+                // TODO: implement execution filters:
+                //      - execute all tests and report results officially
+                //      - execute single test or failed tests only
+                testDetails = executeTests();
+                try {
+                    activityCleanUp();
+                } catch (Throwable e) {
+                    testDetails = new SensorTestDetails(
+                            testName,
+                            SensorTestDetails.ResultCode.FAIL,
+                            "[ActivityCleanUp] " + e.getMessage());
+                }
+                // end activity set up
+            }
+            try {
+                mSensorFeaturesDeactivator.requestToRestoreFeatures();
+            } catch (Throwable e) {
+                testDetails = new SensorTestDetails(
+                        testName,
+                        SensorTestDetails.ResultCode.FAIL,
+                        "[RestoreSensorFeatures] " + e.getMessage());
+            }
+            // end sensor features
         }
         mTestLogger.logTestDetails(testDetails);
 
         // because we cannot enforce test failures in several devices, set the test UI so the
         // operator can report the result of the test
-        if (testDetails.getResultCode() == SensorTestDetails.ResultCode.FAIL) {
-            mTestLogger.logInstructions(R.string.snsr_test_complete_with_errors);
-            enableTestResultButton(
-                    mPassButton,
-                    R.string.snsr_pass_on_error,
-                    testDetails.cloneAndChangeResultCode(SensorTestDetails.ResultCode.PASS));
-            enableTestResultButton(
-                    mFailButton,
-                    R.string.fail_button_text,
-                    testDetails.cloneAndChangeResultCode(SensorTestDetails.ResultCode.FAIL));
-        } else {
-            mTestLogger.logInstructions(R.string.snsr_test_complete);
-            enableTestResultButton(
-                    mPassButton,
-                    R.string.pass_button_text,
-                    testDetails.cloneAndChangeResultCode(SensorTestDetails.ResultCode.PASS));
-        }
+        promptUserToSetResult(testDetails);
     }
 
     /**
@@ -231,11 +237,6 @@
     }
 
     @Deprecated
-    protected void appendText(int resId, int textColor) {
-        mTestLogger.logInstructions(resId);
-    }
-
-    @Deprecated
     protected void appendText(String text, int textColor) {
         appendText(text);
     }
@@ -316,6 +317,38 @@
         return latch.await();
     }
 
+    /**
+     * Initializes and shows the {@link GLSurfaceView} available to tests.
+     * NOTE: initialization can be performed only once, usually inside {@link #activitySetUp()}.
+     */
+    protected void initializeGlSurfaceView(final GLSurfaceView.Renderer renderer) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mGLSurfaceView.setVisibility(View.VISIBLE);
+                mGLSurfaceView.setRenderer(renderer);
+                mUsingGlSurfaceView = true;
+            }
+        });
+    }
+
+    /**
+     * Closes and hides the {@link GLSurfaceView}.
+     */
+    protected void closeGlSurfaceView() {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                if (!mUsingGlSurfaceView) {
+                    return;
+                }
+                mGLSurfaceView.setVisibility(View.GONE);
+                mGLSurfaceView.onPause();
+                mUsingGlSurfaceView = false;
+            }
+        });
+    }
+
     protected void playSound() {
         MediaPlayer player = MediaPlayer.create(this, Settings.System.DEFAULT_NOTIFICATION_URI);
         if (player == null) {
@@ -384,6 +417,63 @@
         }
     }
 
+    private SensorTestDetails deactivateSensorFeatures() {
+        String testName = getTestClassName();
+        try {
+            mSensorFeaturesDeactivator.requestDeactivationOfFeatures();
+        } catch (Throwable e) {
+            return new SensorTestDetails(
+                    testName,
+                    SensorTestDetails.ResultCode.FAIL,
+                    "[DeactivateSensorFeatures] " + e.getMessage());
+        }
+        return new SensorTestDetails(
+                testName,
+                SensorTestDetails.ResultCode.PASS,
+                null /* summary */);
+    }
+
+    private SensorTestDetails executeActivitySetUp() {
+        String testName = getTestClassName();
+        try {
+            activitySetUp();
+        } catch (SensorTestStateNotSupportedException e) {
+            return new SensorTestDetails(
+                    testName,
+                    SensorTestDetails.ResultCode.SKIPPED,
+                    e.getMessage());
+        } catch (Throwable e) {
+            return new SensorTestDetails(
+                    testName,
+                    SensorTestDetails.ResultCode.FAIL,
+                    "[ActivitySetUp] " + e.getMessage());
+        }
+        return new SensorTestDetails(
+                testName,
+                SensorTestDetails.ResultCode.PASS,
+                null /* summary */);
+    }
+
+    private void promptUserToSetResult(SensorTestDetails testDetails) {
+        if (testDetails.getResultCode() == SensorTestDetails.ResultCode.FAIL) {
+            mTestLogger.logInstructions(R.string.snsr_test_complete_with_errors);
+            enableTestResultButton(
+                    mPassButton,
+                    R.string.snsr_pass_on_error,
+                    testDetails.cloneAndChangeResultCode(SensorTestDetails.ResultCode.PASS));
+            enableTestResultButton(
+                    mFailButton,
+                    R.string.fail_button_text,
+                    testDetails.cloneAndChangeResultCode(SensorTestDetails.ResultCode.FAIL));
+        } else {
+            mTestLogger.logInstructions(R.string.snsr_test_complete);
+            enableTestResultButton(
+                    mPassButton,
+                    R.string.pass_button_text,
+                    testDetails.cloneAndChangeResultCode(SensorTestDetails.ResultCode.PASS));
+        }
+    }
+
     private void updateNextButton(final boolean enabled) {
         runOnUiThread(new Runnable() {
             @Override
@@ -443,6 +533,10 @@
             textAppender.append();
         }
 
+        public void logWaitForSound() {
+            logInstructions(R.string.snsr_test_play_sound);
+        }
+
         public void logTestDetails(SensorTestDetails testDetails) {
             String name = testDetails.getName();
             String summary = testDetails.getSummary();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsTestActivity.java
index 4d2813c..77f3a41 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsTestActivity.java
@@ -18,6 +18,7 @@
 package com.android.cts.verifier.sensors.base;
 
 import com.android.cts.verifier.R;
+import com.android.cts.verifier.sensors.helpers.SensorTestScreenManipulator;
 import com.android.cts.verifier.sensors.reporting.SensorTestDetails;
 
 import junit.framework.Test;
@@ -36,7 +37,11 @@
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.RunnerBuilder;
 
+import android.app.KeyguardManager;
+import android.content.Context;
 import android.hardware.cts.SensorTestCase;
+import android.os.PowerManager;
+import android.view.WindowManager;
 
 import java.util.concurrent.TimeUnit;
 
@@ -49,6 +54,9 @@
  */
 public abstract class SensorCtsTestActivity extends BaseSensorTestActivity {
 
+    private SensorTestScreenManipulator mScreenManipulator;
+    private PowerManager.WakeLock mWakeLock;
+
     /**
      * Constructor for a CTS test executor. It will execute a standalone CTS test class.
      *
@@ -60,8 +68,33 @@
 
     @Override
     protected void activitySetUp() {
-        getTestLogger().logInstructions(R.string.snsr_no_interaction);
+        mScreenManipulator = new SensorTestScreenManipulator(getApplicationContext());
+        mScreenManipulator.initialize(this);
+        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+        mWakeLock =  powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SensorCtsTests");
+
+        SensorTestLogger logger = getTestLogger();
+        logger.logInstructions(R.string.snsr_no_interaction);
+        logger.logInstructions(R.string.snsr_run_automated_tests);
         waitForUserToBegin();
+
+        // automated CTS tests run with the USB connected, so the AP doesn't go to sleep
+        // here we are not connected to USB, so we need to hold a wake-lock to avoid going to sleep
+        mWakeLock.acquire();
+        mScreenManipulator.turnScreenOff();
+    }
+
+    @Override
+    protected void activityCleanUp() {
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+        mScreenManipulator.turnScreenOn();
+        mWakeLock.release();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mScreenManipulator.releaseScreenOn();
     }
 
     /**
@@ -150,7 +183,6 @@
             if (!mCurrentTestReported) {
                 getTestLogger().logTestPass(description.getMethodName(), null /* testSummary */);
             }
-            playSound();
         }
 
         public void testFailure(Failure failure) throws Exception {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsVerifierTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsVerifierTestActivity.java
index 148e457..09753cc 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsVerifierTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsVerifierTestActivity.java
@@ -39,10 +39,7 @@
     private volatile int mTestFailedCounter;
 
     /**
-     * Constructor for a CtsVerifier test executor. It executes tests defined in the same class.
-     *
-     * @param testClass The test class to execute, this is the same subclass implementing the
-     *                  executor. It must be a subclass of {@link SensorCtsVerifierTestActivity}
+     * {@inheritDoc}
      */
     protected SensorCtsVerifierTestActivity(
             Class<? extends SensorCtsVerifierTestActivity> testClass) {
@@ -50,12 +47,7 @@
     }
 
     /**
-     * Constructor for a CtsVerifier test executor. It executes tests defined in the same class.
-     *
-     * @param testClass The test class to execute, this is the same subclass implementing the
-     *                  executor. It must be a subclass of {@link SensorCtsVerifierTestActivity}
-     * @param layoutId The Id of the layout to use for the test UI. The layout must contain all the
-     *                 elements in the base layout {@code R.layout.snsr_semi_auto_test}.
+     * {@inheritDoc}
      */
     protected SensorCtsVerifierTestActivity(
             Class<? extends SensorCtsVerifierTestActivity> testClass,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorSettingContainer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorSettingContainer.java
index 27fa699..9fa40e3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorSettingContainer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorSettingContainer.java
@@ -20,8 +20,6 @@
 import com.android.cts.verifier.sensors.base.BaseSensorTestActivity;
 import com.android.cts.verifier.sensors.base.ISensorTestStateContainer;
 
-import android.util.Log;
-
 /**
  * A helper class for {@link SensorFeaturesDeactivator}. It abstracts the responsibility of handling
  * device settings that affect sensors.
@@ -29,7 +27,6 @@
  * This class is not thread safe. It is meant to be used only by {@link SensorFeaturesDeactivator}.
  */
 abstract class SensorSettingContainer {
-    private static final String TAG = "SensorSettingContainer";
     private final String mAction;
     private final int mSettingNameResId;
 
@@ -47,8 +44,23 @@
     public synchronized void requestToSetMode(
             ISensorTestStateContainer stateContainer,
             boolean modeOn) {
+        trySetMode(stateContainer, modeOn);
+        if (getCurrentSettingMode() != modeOn) {
+            String message = stateContainer.getString(
+                    R.string.snsr_setting_mode_not_set,
+                    getSettingName(stateContainer),
+                    modeOn);
+            throw new IllegalStateException(message);
+        }
+    }
+
+    public synchronized void requestToResetMode(ISensorTestStateContainer stateContainer) {
+        trySetMode(stateContainer, mCapturedModeOn);
+    }
+
+    private void trySetMode(ISensorTestStateContainer stateContainer, boolean modeOn) {
         BaseSensorTestActivity.SensorTestLogger logger = stateContainer.getTestLogger();
-        String settingName = stateContainer.getString(mSettingNameResId);
+        String settingName = getSettingName(stateContainer);
         if (getCurrentSettingMode() == modeOn) {
             logger.logInstructions(R.string.snsr_setting_mode_set, settingName, modeOn);
             return;
@@ -57,26 +69,16 @@
         logger.logInstructions(R.string.snsr_setting_mode_request, settingName, modeOn);
         logger.logInstructions(R.string.snsr_on_complete_return);
         stateContainer.waitForUserToContinue();
-
         stateContainer.executeActivity(mAction);
-        if (getCurrentSettingMode() != modeOn) {
-            String message = stateContainer
-                    .getString(R.string.snsr_setting_mode_not_set, settingName, modeOn);
-            throw new IllegalStateException(message);
-        }
-    }
-
-    public synchronized void requestToResetMode(ISensorTestStateContainer stateContainer) {
-        try {
-            requestToSetMode(stateContainer, mCapturedModeOn);
-        } catch (IllegalStateException e) {
-            Log.e(TAG, "Error restoring state of action: " + mAction, e);
-        }
     }
 
     private boolean getCurrentSettingMode() {
         return getSettingMode() != 0;
     }
 
+    private String getSettingName(ISensorTestStateContainer stateContainer) {
+        return stateContainer.getString(mSettingNameResId);
+    }
+
     protected abstract int getSettingMode();
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorTestScreenManipulator.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorTestScreenManipulator.java
index 8986cd9..bfe2ba7 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorTestScreenManipulator.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorTestScreenManipulator.java
@@ -27,25 +27,55 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.PowerManager;
 import android.text.TextUtils;
 
 /**
  * A class that provides functionality to manipulate the state of the device's screen.
+ *
+ * The implementation uses a simple state machine with 3 states: keep-screen-off, keep-screen-on,
+ * and a free-state where the class does not affect the system's state.
+ *
+ * The list of transitions and their handlers are:
+ *      keep-screen-on --(turnScreenOff)--> keep-screen-off
+ *      keep-screen-on --(releaseScreenOn)--> free-state
+ *
+ *      keep-screen-off --(turnScreenOn)--> keep-screen-on
+ *      keep-screen-off --(wakeUpScreen)--> free-state
+ *
+ *      free-state --(turnScreenOff)--> keep-screen-off
+ *      free-state --(turnScreenOn)--> keep-screen-on
+ *
+ * NOTES:
+ * - the operator still can turn on/off the screen by pressing the power button
+ * - this class must be used by a single client, that can manage the state of the instance, likely
+ * - in a single-threaded environment
  */
 public class SensorTestScreenManipulator {
 
     private final Context mContext;
     private final DevicePolicyManager mDevicePolicyManager;
     private final ComponentName mComponentName;
+    private final PowerManager.WakeLock mWakeUpScreenWakeLock;
+    private final PowerManager.WakeLock mKeepScreenWakeLock;
 
-    private volatile InternalBroadcastReceiver mBroadcastReceiver;
-    private volatile boolean mTurnOffScreenOnPowerDisconnected;
+    private InternalBroadcastReceiver mBroadcastReceiver;
+    private boolean mTurnOffScreenOnPowerDisconnected;
 
     public SensorTestScreenManipulator(Context context) {
         mContext = context;
         mComponentName = SensorDeviceAdminReceiver.getComponentName(context);
         mDevicePolicyManager =
                 (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
+
+        int levelAndFlags = PowerManager.FULL_WAKE_LOCK
+                | PowerManager.ON_AFTER_RELEASE
+                | PowerManager.ACQUIRE_CAUSES_WAKEUP;
+        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mWakeUpScreenWakeLock = powerManager.newWakeLock(levelAndFlags, "SensorTestWakeUpScreen");
+        mWakeUpScreenWakeLock.setReferenceCounted(false);
+        mKeepScreenWakeLock = powerManager.newWakeLock(levelAndFlags, "SensorTestKeepScreenOn");
+        mWakeUpScreenWakeLock.setReferenceCounted(false);
     }
 
     /**
@@ -90,10 +120,48 @@
      */
     public synchronized void turnScreenOff() {
         ensureDeviceAdminInitialized();
+        releaseScreenOn();
         mDevicePolicyManager.lockNow();
     }
 
     /**
+     * Instruct the device to wake up the screen immediately, the screen will remain on for a bit,
+     * but the system might turn the screen off in the near future.
+     */
+    public synchronized void wakeUpScreen() {
+        mWakeUpScreenWakeLock.acquire();
+        // release right away, the screen still remains on for a bit, but not indefinitely
+        mWakeUpScreenWakeLock.release();
+    }
+
+    /**
+     * Instructs the device to turn on the screen immediately.
+     *
+     * The screen will remain on until the client invokes {@link #releaseScreenOn()}, or the user
+     * presses the device's power button.
+     */
+    public synchronized void turnScreenOn() {
+        if (mKeepScreenWakeLock.isHeld()) {
+            // recover from cases when we could get out of sync, this can happen because the user
+            // can press the power button, and other wake-locks can prevent intents to be received
+            mKeepScreenWakeLock.release();
+        }
+        mKeepScreenWakeLock.acquire();
+    }
+
+    /**
+     * Indicates that the client does not require the screen to remain on anymore.
+     *
+     * See {@link #turnScreenOn()} for more information.
+     */
+    public synchronized void releaseScreenOn() {
+        if (!mKeepScreenWakeLock.isHeld()) {
+            return;
+        }
+        mKeepScreenWakeLock.release();
+    }
+
+    /**
      * Queues a request to turn off the screen off when the device has been disconnected from a
      * power source (usually upon USB disconnected).
      *
@@ -124,14 +192,14 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
 
-            if (mTurnOffScreenOnPowerDisconnected &&
-                    TextUtils.equals(action, Intent.ACTION_POWER_DISCONNECTED)) {
-                turnScreenOff();
-
-                // reset the flag after it has triggered once, we try to avoid cases when the test
-                // might leave the receiver enabled after itself,
-                // this approach still provides a way to multiplex one time requests
-                mTurnOffScreenOnPowerDisconnected = false;
+            if (TextUtils.equals(action, Intent.ACTION_POWER_DISCONNECTED)) {
+                if (mTurnOffScreenOnPowerDisconnected) {
+                    turnScreenOff();
+                    // reset the flag after it has triggered once, we try to avoid cases when the test
+                    // might leave the receiver enabled after itself,
+                    // this approach still provides a way to multiplex one time requests
+                    mTurnOffScreenOnPowerDisconnected = false;
+                }
             }
         }
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/GLArrowSensorTestRenderer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/GLArrowSensorTestRenderer.java
new file mode 100644
index 0000000..f2f33c1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/GLArrowSensorTestRenderer.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.sensors.renderers;
+
+import com.android.cts.verifier.R;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.opengl.GLUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * Renders a wedge to indicate the direction of sensor data.
+ */
+public class GLArrowSensorTestRenderer implements GLSurfaceView.Renderer, SensorEventListener {
+    // A representation of the Z-axis in vector form.
+    private static final float[] Z_AXIS = new float[] {0, 0, 1};
+
+    // The (pseudo)vector around which to rotate to align Z-axis with gravity.
+    private final float[] mCrossProd = new float[3];
+    private final float[] mRotationMatrix = new float[16];
+
+    private final int mSensorType;
+    private final Context mContext;
+    private final Wedge mWedge;
+
+    // The angle around mCrossProd to rotate to align Z-axis with gravity.
+    private float mAngle;
+    private int mTextureID;
+
+    /**
+     * It's a constructor. Can you dig it?
+     *
+     * @param context the Android Context that owns this renderer
+     * @param type of arrow. Possible values: 0 = points towards gravity. 1 =
+     *            points towards reference North
+     */
+    public GLArrowSensorTestRenderer(Context context, int type) {
+        mContext = context;
+        mSensorType = type;
+        mWedge = new Wedge(mSensorType);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onDrawFrame(GL10 gl) {
+        // set up the texture for drawing
+        gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+        gl.glActiveTexture(GL10.GL_TEXTURE0);
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
+        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
+
+        // clear the screen and draw
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+
+        if (mSensorType == Sensor.TYPE_ACCELEROMETER) {
+            gl.glRotatef(
+                    -mAngle * 180 / (float) Math.PI,
+                    mCrossProd[0],
+                    mCrossProd[1],
+                    mCrossProd[2]);
+        } else {
+            gl.glMultMatrixf(mRotationMatrix, 0);
+        }
+        mWedge.draw(gl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSurfaceChanged(GL10 gl, int w, int h) {
+        gl.glViewport(0, 0, w, h);
+        float ratio = (float) w / h;
+        gl.glMatrixMode(GL10.GL_PROJECTION);
+        gl.glLoadIdentity();
+        gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
+        GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        // set up general OpenGL config
+        gl.glClearColor(0.6f, 0f, 0.4f, 1); // a nice purpley magenta
+        gl.glShadeModel(GL10.GL_SMOOTH);
+        gl.glEnable(GL10.GL_DEPTH_TEST);
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+
+        // create the texture we use on the wedge
+        int[] textures = new int[1];
+        gl.glGenTextures(1, textures, 0);
+        mTextureID = textures[0];
+
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
+        gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
+
+        InputStream is = mContext.getResources().openRawResource(R.raw.sns_texture);
+        Bitmap bitmap;
+        try {
+            bitmap = BitmapFactory.decodeStream(is);
+        } finally {
+            try {
+                is.close();
+            } catch (IOException e) {
+                // Ignore.
+            }
+        }
+
+        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
+        bitmap.recycle();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onAccuracyChanged(Sensor arg0, int arg1) {
+        // no-op
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        int type = event.sensor.getType();
+        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+            /*
+             * For this test we want *only* accelerometer data, so we can't use
+             * the convenience methods on SensorManager; so compute manually.
+             */
+            normalize(event.values);
+
+            /*
+             * Because we need to invert gravity (because the accelerometer
+             * vector actually points up), that constitutes a 180-degree
+             * rotation around X, which means we need to invert Y.
+             */
+            event.values[1] *= -1;
+
+            crossProduct(event.values, Z_AXIS, mCrossProd);
+            mAngle = (float) Math.acos(dotProduct(event.values, Z_AXIS));
+        } else if (type == Sensor.TYPE_ROTATION_VECTOR
+                || type == Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR
+                || type == Sensor.TYPE_GAME_ROTATION_VECTOR) {
+            float[] rotationMatrixTmp = new float[16];
+
+            SensorManager.getRotationMatrixFromVector(rotationMatrixTmp, event.values);
+            SensorManager.remapCoordinateSystem(rotationMatrixTmp,
+                    SensorManager.AXIS_MINUS_X, SensorManager.AXIS_Y, mRotationMatrix);
+        }
+
+    }
+
+    /**
+     * Computes the cross product of two vectors, storing the resulting pseudo-vector in out. All
+     * arrays must be length 3 or more, and out is overwritten.
+     *
+     * @param left the left operand of the cross product
+     * @param right the right operand of the cross product
+     * @param out the array into which to store the cross-product pseudo-vector's data
+     */
+    public static void crossProduct(float[] left, float[] right, float[] out) {
+        out[0] = left[1] * right[2] - left[2] * right[1];
+        out[1] = left[2] * right[0] - left[0] * right[2];
+        out[2] = left[0] * right[1] - left[1] * right[0];
+    }
+
+    /**
+     * Computes the dot product of two vectors.
+     *
+     * @param left the first dot product operand
+     * @param right the second dot product operand
+     * @return the dot product of left and right
+     */
+    public static float dotProduct(float[] left, float[] right) {
+        return left[0] * right[0] + left[1] * right[1] + left[2] * right[2];
+    }
+
+    /**
+     * Normalizes the input vector into a unit vector.
+     *
+     * @param vector the vector to normalize. Contents are overwritten.
+     */
+    public static void normalize(float[] vector) {
+        double mag = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2]
+                * vector[2]);
+        vector[0] /= mag;
+        vector[1] /= mag;
+        vector[2] /= mag;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/GLRotationGuideRenderer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/GLRotationGuideRenderer.java
new file mode 100644
index 0000000..6f2109f
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/GLRotationGuideRenderer.java
@@ -0,0 +1,113 @@
+/*
+ * 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.sensors.renderers;
+
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * Renders a spinning block to indicate how the device should be rotated in the test.
+ */
+public class GLRotationGuideRenderer implements GLSurfaceView.Renderer {
+    public static final int BACKGROUND_BLACK = 0;
+    public static final int BACKGROUND_RED = 1;
+    public static final int BACKGROUND_GREEN = 2;
+    private static final double ANGLE_INCREMENT = 1.0;
+
+    private final Monolith mMonolith = new Monolith();
+    private final AtomicInteger mBackgroundColor = new AtomicInteger(BACKGROUND_BLACK);
+
+    private float mAngle;
+    private float mRotateX;
+    private float mRotateY;
+    private float mRotateZ;
+
+    /**
+     * Sets the rotation of the monolith.
+     */
+    public void setRotation(float rotateX, float rotateY, float rotateZ) {
+        mRotateX = rotateX;
+        mRotateY = rotateY;
+        mRotateZ = rotateZ;
+    }
+
+    /**
+     * Sets the background color.
+     */
+    public void setBackgroundColor(int value) {
+        mBackgroundColor.set(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onDrawFrame(GL10 gl) {
+        clearBackground(gl);
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        gl.glRotatef(mAngle, mRotateX, mRotateY, mRotateZ);
+        mMonolith.draw(gl);
+        mAngle += ANGLE_INCREMENT;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSurfaceChanged(GL10 gl, int width, int height) {
+        gl.glViewport(0, 0, width, height);
+        gl.glMatrixMode(GL10.GL_PROJECTION);
+        gl.glLoadIdentity();
+        float ratio = (float) width / height;
+        gl.glFrustumf(-ratio, ratio, -1, 1, 3, 15);
+        GLU.gluLookAt(gl, 0, 0, 10, 0, 0, 0, 0, 1, 0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnable(GL10.GL_LIGHTING);
+        gl.glEnable(GL10.GL_LIGHT0);
+        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, new float[] {0.75f, 0.75f, 0.75f, 1f}, 0);
+    }
+
+    private void clearBackground(GL10 gl) {
+        switch (mBackgroundColor.get()) {
+            case BACKGROUND_GREEN:
+                gl.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+                break;
+
+            case BACKGROUND_RED:
+                gl.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+                break;
+
+            default:
+                gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+                break;
+        }
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/Monolith.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/Monolith.java
new file mode 100644
index 0000000..56e230d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/Monolith.java
@@ -0,0 +1,118 @@
+/*
+ * 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.sensors.renderers;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * Rectangular block that is rotated by {@link GLRotationGuideRenderer}.
+ */
+class Monolith {
+    private static final int NUM_VERTICES = 8;
+    private static final int NUM_INDICES = 36;
+
+    private final FloatBuffer mVertexBuffer;
+    private final ShortBuffer mIndexBuffer;
+
+    public Monolith() {
+        mVertexBuffer = ByteBuffer.allocateDirect(NUM_VERTICES * 3 * 4)
+                .order(ByteOrder.nativeOrder())
+                .asFloatBuffer();
+
+        float[] coordinates = {
+                -0.65f, -1, 0.2f,
+                -0.65f, 1, 0.2f,
+                0.65f, 1, 0.2f,
+                0.65f, -1, 0.2f,
+
+                -0.65f, -1, -0.2f,
+                -0.65f, 1, -0.2f,
+                0.65f, 1, -0.2f,
+                0.65f, -1, -0.2f,
+        };
+
+        for (int i = 0; i < coordinates.length; i++) {
+            mVertexBuffer.put(coordinates[i]);
+        }
+
+        mIndexBuffer = ByteBuffer.allocateDirect(NUM_INDICES * 2)
+                .order(ByteOrder.nativeOrder())
+                .asShortBuffer();
+
+        // Front
+        mIndexBuffer.put((short) 0);
+        mIndexBuffer.put((short) 1);
+        mIndexBuffer.put((short) 2);
+        mIndexBuffer.put((short) 0);
+        mIndexBuffer.put((short) 2);
+        mIndexBuffer.put((short) 3);
+
+        // Back
+        mIndexBuffer.put((short) 7);
+        mIndexBuffer.put((short) 6);
+        mIndexBuffer.put((short) 5);
+        mIndexBuffer.put((short) 7);
+        mIndexBuffer.put((short) 5);
+        mIndexBuffer.put((short) 4);
+
+        // Right
+        mIndexBuffer.put((short) 3);
+        mIndexBuffer.put((short) 2);
+        mIndexBuffer.put((short) 6);
+        mIndexBuffer.put((short) 3);
+        mIndexBuffer.put((short) 6);
+        mIndexBuffer.put((short) 7);
+
+        // Left
+        mIndexBuffer.put((short) 4);
+        mIndexBuffer.put((short) 5);
+        mIndexBuffer.put((short) 1);
+        mIndexBuffer.put((short) 4);
+        mIndexBuffer.put((short) 1);
+        mIndexBuffer.put((short) 0);
+
+        // Top
+        mIndexBuffer.put((short) 1);
+        mIndexBuffer.put((short) 5);
+        mIndexBuffer.put((short) 6);
+        mIndexBuffer.put((short) 1);
+        mIndexBuffer.put((short) 6);
+        mIndexBuffer.put((short) 2);
+
+        // Bottom
+        mIndexBuffer.put((short) 3);
+        mIndexBuffer.put((short) 7);
+        mIndexBuffer.put((short) 4);
+        mIndexBuffer.put((short) 3);
+        mIndexBuffer.put((short) 4);
+        mIndexBuffer.put((short) 0);
+
+        mVertexBuffer.position(0);
+        mIndexBuffer.position(0);
+    }
+
+    public void draw(GL10 gl) {
+        gl.glColor4f(0.5f, 0.5f, 0.5f, 1f);
+        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
+        gl.glDrawElements(GL10.GL_TRIANGLES, NUM_INDICES, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/Wedge.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/Wedge.java
new file mode 100644
index 0000000..bee75d6
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/renderers/Wedge.java
@@ -0,0 +1,146 @@
+/*
+ * 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.sensors.renderers;
+
+import android.hardware.Sensor;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A representation of a 3D triangular wedge or arrowhead shape, suitable for pointing a direction.
+ */
+class Wedge {
+    private final static int VERTS = 6;
+
+    // Storage for the vertices.
+    private final FloatBuffer mFVertexBuffer;
+
+    // Storage for the drawing sequence of the vertices. This contains integer indices into the
+    // mFVertextBuffer structure.
+    private final ShortBuffer mIndexBuffer;
+
+    // Storage for the texture used on the surface of the wedge.
+    private final FloatBuffer mTexBuffer;
+
+    public Wedge(int sensorType) {
+        // Buffers to be passed to gl*Pointer() functions
+        // must be direct & use native ordering
+
+        ByteBuffer vbb = ByteBuffer.allocateDirect(VERTS * 6 * 4);
+        vbb.order(ByteOrder.nativeOrder());
+        mFVertexBuffer = vbb.asFloatBuffer();
+
+        ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
+        tbb.order(ByteOrder.nativeOrder());
+        mTexBuffer = tbb.asFloatBuffer();
+
+        ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 8 * 2);
+        ibb.order(ByteOrder.nativeOrder());
+        mIndexBuffer = ibb.asShortBuffer();
+
+        // Coordinates of the vertices making up a simple wedge. Six total vertices, representing
+        // two isosceles triangles, side by side, centered on the origin separated by 0.25 units,
+        // with elongated ends pointing down the negative Z axis.
+        float[] coords;
+        if (sensorType == Sensor.TYPE_ACCELEROMETER) {
+            float[] verts = {
+                    // X, Y, Z
+                    -0.125f, -0.25f, -0.25f,
+                    -0.125f, 0.25f, -0.25f,
+                    -0.125f, 0.0f, 0.559016994f,
+                    0.125f, -0.25f, -0.25f,
+                    0.125f, 0.25f, -0.25f,
+                    0.125f, 0.0f, 0.559016994f,
+            };
+            coords = verts.clone();
+        } else {
+            float[] verts = {
+                    // X, Y, Z
+                    -0.25f, -0.25f, -0.125f,
+                    -0.25f, 0.25f, -0.125f,
+                    0.559016994f, 0.0f, -0.125f,
+                    -0.25f, -0.25f, 0.125f,
+                    -0.25f, 0.25f, 0.125f,
+                    0.559016994f, 0.0f, 0.125f,
+            };
+            coords = verts.clone();
+        }
+
+        for (int i = 0; i < VERTS; i++) {
+            for (int j = 0; j < 3; j++) {
+                mFVertexBuffer.put(coords[i * 3 + j] * 2.0f);
+            }
+        }
+
+        for (int i = 0; i < VERTS; i++) {
+            for (int j = 0; j < 2; j++) {
+                mTexBuffer.put(coords[i * 3 + j] * 2.0f + 0.5f);
+            }
+        }
+
+        // left face
+        mIndexBuffer.put((short) 0);
+        mIndexBuffer.put((short) 1);
+        mIndexBuffer.put((short) 2);
+
+        // right face
+        mIndexBuffer.put((short) 5);
+        mIndexBuffer.put((short) 4);
+        mIndexBuffer.put((short) 3);
+
+        // top side, 2 triangles to make rect
+        mIndexBuffer.put((short) 2);
+        mIndexBuffer.put((short) 5);
+        mIndexBuffer.put((short) 3);
+        mIndexBuffer.put((short) 3);
+        mIndexBuffer.put((short) 0);
+        mIndexBuffer.put((short) 2);
+
+        // bottom side, 2 triangles to make rect
+        mIndexBuffer.put((short) 5);
+        mIndexBuffer.put((short) 2);
+        mIndexBuffer.put((short) 1);
+        mIndexBuffer.put((short) 1);
+        mIndexBuffer.put((short) 4);
+        mIndexBuffer.put((short) 5);
+
+        // base, 2 triangles to make rect
+        mIndexBuffer.put((short) 0);
+        mIndexBuffer.put((short) 3);
+        mIndexBuffer.put((short) 4);
+        mIndexBuffer.put((short) 4);
+        mIndexBuffer.put((short) 1);
+        mIndexBuffer.put((short) 0);
+
+        mFVertexBuffer.position(0);
+        mTexBuffer.position(0);
+        mIndexBuffer.position(0);
+    }
+
+    public void draw(GL10 gl) {
+        gl.glFrontFace(GL10.GL_CCW);
+        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
+        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/Android.mk b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
similarity index 95%
rename from hostsidetests/devicepolicy/app/ProfileOwner/Android.mk
rename to hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
index baf540b..e621933 100644
--- a/hostsidetests/devicepolicy/app/ProfileOwner/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
@@ -16,7 +16,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_PACKAGE_NAME := CtsProfileOwnerApp
+LOCAL_PACKAGE_NAME := CtsDeviceOwnerApp
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
new file mode 100644
index 0000000..7a196bf
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
@@ -0,0 +1,59 @@
+<?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.deviceowner" >
+
+    <uses-sdk android:minSdkVersion="20"/>
+
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <receiver
+            android:name="com.android.cts.deviceowner.BaseDeviceOwnerTest$BasicAdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                       android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+        <activity android:name="com.android.cts.deviceowner.ExampleIntentReceivingActivity1">
+            <intent-filter>
+                <action android:name="com.android.cts.deviceowner.EXAMPLE_ACTION" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="com.android.cts.deviceowner.ExampleIntentReceivingActivity2">
+            <intent-filter>
+                <action android:name="com.android.cts.deviceowner.EXAMPLE_ACTION" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name="com.android.cts.deviceowner.LockTaskUtilityActivity" />
+        <activity
+            android:name="com.android.cts.deviceowner.ApplicationRestrictionActivity" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.cts.deviceowner"
+                     android:label="Device Owner CTS tests"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/DeviceOwner/res/xml/device_admin.xml
new file mode 100644
index 0000000..fe58d38
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/res/xml/device_admin.xml
@@ -0,0 +1,6 @@
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+    <uses-policies>
+        <reset-password />
+        <limit-password />
+    </uses-policies>
+</device-admin>
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionActivity.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionActivity.java
new file mode 100644
index 0000000..4d8e4f2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionActivity.java
@@ -0,0 +1,94 @@
+/*
+ * 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.deviceowner;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.UserManager;
+
+/**
+ * Test activity for setApplicationRestrictions().
+ *
+ * The actual test will set restrictions for this package, and the purpose of this
+ * activity is to listen for the ACTION_APPLICATION_RESTRICTIONS_CHANGED broadcast
+ * and relay the retrieved restriction bundle back to the test for validation.
+ */
+public class ApplicationRestrictionActivity extends Activity {
+
+    // Incoming intent type
+    public static final String FINISH = "finishActivity";
+
+    // Outgoing broadcast
+    public static final String REGISTERED_ACTION =
+            "com.android.cts.deviceowner.APP_RESTRICTION_REGISTERED";
+    public static final String RESTRICTION_ACTION =
+            "com.android.cts.deviceowner.APP_RESTRICTION_VALUE";
+
+    private UserManager mUserManager;
+
+    private final BroadcastReceiver mAppRestrictionReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            broadcastRestriction();
+        }
+    };
+
+    private void broadcastRestriction() {
+        Bundle restrictions = mUserManager.getApplicationRestrictions(getPackageName());
+        Intent intent = new Intent(RESTRICTION_ACTION);
+        intent.putExtra("value", restrictions);
+        sendBroadcast(intent);
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        handleIntent(intent);
+    }
+
+    @Override
+    protected void onCreate(android.os.Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        handleIntent(getIntent());
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        IntentFilter filter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
+        registerReceiver(mAppRestrictionReceiver, filter);
+        sendBroadcast(new Intent(REGISTERED_ACTION));
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        unregisterReceiver(mAppRestrictionReceiver);
+    }
+
+    private void handleIntent(Intent intent) {
+        if (intent.getBooleanExtra(FINISH, false)) {
+            finish();
+        }
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionsTest.java
new file mode 100644
index 0000000..5e03de9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionsTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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.deviceowner;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Functionality tests for setApplicationRestrictions and getApplicationRestrictions
+ * in DevicePolicyManager.
+ *
+ * First of all, these two APIs are executed locally to assert that what you set
+ * can later be retrieved via the getter. It also fires up an external activity
+ * (which runs in com.google.android.xts.gmscore, unlike the test code itself
+ * which runs in the test target package com.google.android.gms due to
+ * instrumentation) to observe an application's view of its restrictions.
+ * The activity listens to ACTION_APPLICATION_RESTRICTIONS_CHANGED broadcast
+ * which is fired by the system whenever its restriction is modified,
+ * and relays the value back to this test for verification.
+ */
+public class ApplicationRestrictionsTest extends BaseDeviceOwnerTest {
+
+    private static final String[] testStrings = new String[] {
+            "<bad/>",
+            ">worse!\"£$%^&*()'<",
+            "<JSON>\"{ \\\"One\\\": { \\\"OneOne\\\": \\\"11\\\", \\\""
+                    + "OneTwo\\\": \\\"12\\\" }, \\\"Two\\\": \\\"2\\\" } <JSON/>\""
+    };
+
+    private final Semaphore mOnRegisteredSemaphore = new Semaphore(0);
+    private final Semaphore mOnRestrictionSemaphore = new Semaphore(0);
+    private Bundle mReceivedRestrictions;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ApplicationRestrictionActivity.REGISTERED_ACTION);
+        filter.addAction(ApplicationRestrictionActivity.RESTRICTION_ACTION);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mContext.unregisterReceiver(mReceiver);
+        super.tearDown();
+    }
+
+    public void testSetApplicationRestrictions() {
+        final String CTS_PACKAGE = PACKAGE_NAME;
+        final String OTHER_PACKAGE = CTS_PACKAGE + "dummy";
+
+        startAndWait();
+
+        Bundle bundle0 = createBundle0();
+        Bundle bundle1 = createBundle1();
+
+        // Test setting restrictions
+        mDevicePolicyManager.setApplicationRestrictions(getWho(), CTS_PACKAGE, bundle0);
+        mDevicePolicyManager.setApplicationRestrictions(getWho(), OTHER_PACKAGE, bundle1);
+
+        // Retrieve restrictions locally and make sure they are what we put in.
+        assertBundle0(mDevicePolicyManager.getApplicationRestrictions(getWho(), CTS_PACKAGE));
+        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(getWho(), OTHER_PACKAGE));
+
+        // The test activity should have received a change_restriction broadcast
+        // and relay the value back to us.
+        assertBundle0(waitForChangedRestriction());
+
+        // Test overwriting
+        mDevicePolicyManager.setApplicationRestrictions(getWho(), CTS_PACKAGE, bundle1);
+        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(getWho(), CTS_PACKAGE));
+        assertBundle1(waitForChangedRestriction());
+
+        // Cleanup
+        mDevicePolicyManager.setApplicationRestrictions(getWho(), CTS_PACKAGE, new Bundle());
+        assertTrue(
+                mDevicePolicyManager.getApplicationRestrictions(getWho(), CTS_PACKAGE).isEmpty());
+        assertTrue(waitForChangedRestriction().isEmpty());
+        mDevicePolicyManager.setApplicationRestrictions(getWho(), OTHER_PACKAGE, new Bundle());
+        assertTrue(
+                mDevicePolicyManager.getApplicationRestrictions(getWho(), OTHER_PACKAGE).isEmpty());
+
+        finish();
+    }
+
+    // Should be consistent with assertBundle0
+    private Bundle createBundle0() {
+        Bundle result = new Bundle();
+        // Tests for four allowed types: Integer, Boolean, String and String[]
+        // Also test for string escaping handling
+        result.putBoolean("boolean_0", false);
+        result.putBoolean("boolean_1", true);
+        result.putInt("integer", 0x7fffffff);
+        // If a null is stored, "" will be read back
+        result.putString("empty", "");
+        result.putString("string", "text");
+        result.putStringArray("string[]", testStrings);
+        return result;
+    }
+
+    // Should be consistent with createBundle0
+    private void assertBundle0(Bundle bundle) {
+        assertEquals(6, bundle.size());
+        assertEquals(false, bundle.getBoolean("boolean_0"));
+        assertEquals(true, bundle.getBoolean("boolean_1"));
+        assertEquals(0x7fffffff, bundle.getInt("integer"));
+        assertEquals("", bundle.getString("empty"));
+        assertEquals("text", bundle.getString("string"));
+
+        String[] strings = bundle.getStringArray("string[]");
+        assertTrue(strings != null && strings.length == testStrings.length);
+        for (int i = 0; i < strings.length; i++) {
+            assertEquals(strings[i], testStrings[i]);
+        }
+    }
+
+    // Should be consistent with assertBundle1
+    private Bundle createBundle1() {
+        Bundle result = new Bundle();
+        result.putInt("dummy", 1);
+        return result;
+    }
+
+    // Should be consistent with createBundle1
+    private void assertBundle1(Bundle bundle) {
+        assertEquals(1, bundle.size());
+        assertEquals(1, bundle.getInt("dummy"));
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (ApplicationRestrictionActivity.REGISTERED_ACTION.equals(action)) {
+                mOnRegisteredSemaphore.release();
+            } else if (ApplicationRestrictionActivity.RESTRICTION_ACTION.equals(action)) {
+                mReceivedRestrictions = intent.getBundleExtra("value");
+                mOnRestrictionSemaphore.release();
+            }
+        }
+    };
+
+    private void startTestActivity(String command) {
+        Intent intent = new Intent();
+        intent.setClassName(PACKAGE_NAME, ApplicationRestrictionActivity.class.getName());
+        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        if (command != null) {
+            intent.putExtra(command, true);
+        }
+        mContext.startActivity(intent);
+    }
+
+    private void startAndWait() {
+        startTestActivity(null);
+        // Wait until the activity has registered its broadcast receiver and ready for incoming
+        // restriction changes.
+        try {
+            assertTrue(mOnRegisteredSemaphore.tryAcquire(5, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            fail("Start ApplicationRestrictionActivity interrupted");
+        }
+    }
+
+    private Bundle waitForChangedRestriction() {
+        try {
+            assertTrue(mOnRestrictionSemaphore.tryAcquire(5, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            fail("getRestrictionsAndWait() interrupted");
+        }
+
+        return mReceivedRestrictions;
+    }
+
+    private void finish() {
+        startTestActivity(ApplicationRestrictionActivity.FINISH);
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
new file mode 100644
index 0000000..e4f5134
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.deviceowner;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+/**
+ * Base class for device-owner based tests.
+ *
+ * This class handles making sure that the test is the device owner
+ * and that it has an active admin registered, so that all tests may
+ * assume these are done. The admin component can be accessed through
+ * {@link #getWho()}.
+ */
+public class BaseDeviceOwnerTest extends AndroidTestCase {
+
+    public static class BasicAdminReceiver extends DeviceAdminReceiver {
+    }
+
+    public static final String PACKAGE_NAME = BaseDeviceOwnerTest.class.getPackage().getName();
+
+    protected DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        assertTrue(mDevicePolicyManager.isAdminActive(getWho()));
+        assertTrue(mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME));
+    }
+
+    public static ComponentName getWho() {
+        return new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName());
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CaCertManagementTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CaCertManagementTest.java
new file mode 100644
index 0000000..9127dab
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CaCertManagementTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.deviceowner;
+
+import static com.android.cts.deviceowner.FakeKeys.FAKE_RSA_1;
+import static com.android.cts.deviceowner.FakeKeys.FAKE_DSA_1;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.Certificate;
+import java.util.List;
+
+public class CaCertManagementTest extends BaseDeviceOwnerTest {
+    public void testCanRetrieveListOfInstalledCaCerts() {
+        List<byte[]> caCerts = mDevicePolicyManager.getInstalledCaCerts(getWho());
+        assertNotNull(caCerts);
+    }
+
+    public void testCanInstallAndUninstallACaCert()
+    throws CertificateException {
+        assertFalse(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
+        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+        assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_RSA_1.caCertificate));
+        assertTrue(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
+        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+        mDevicePolicyManager.uninstallCaCert(getWho(), FAKE_RSA_1.caCertificate);
+        assertFalse(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
+        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+    }
+
+    public void testUninstallationIsSelective() throws CertificateException {
+        assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_RSA_1.caCertificate));
+        assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_DSA_1.caCertificate));
+        mDevicePolicyManager.uninstallCaCert(getWho(), FAKE_DSA_1.caCertificate);
+        assertTrue(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
+        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+        mDevicePolicyManager.uninstallCaCert(getWho(), FAKE_RSA_1.caCertificate);
+    }
+
+    public void testCanUninstallAllUserCaCerts() throws CertificateException {
+        assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_RSA_1.caCertificate));
+        assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_DSA_1.caCertificate));
+        mDevicePolicyManager.uninstallAllUserCaCerts(getWho());
+        assertFalse(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
+        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+    }
+
+    private boolean hasCaCertInstalled(byte [] caCert) throws CertificateException {
+        boolean result = mDevicePolicyManager.hasCaCertInstalled(getWho(), caCert);
+        assertEquals(result, containsCertificate(
+            mDevicePolicyManager.getInstalledCaCerts(getWho()), caCert));
+        return result;
+    }
+
+    private static boolean containsCertificate(List<byte[]> certificates, byte [] toMatch)
+            throws CertificateException {
+        Certificate certificateToMatch = readCertificate(toMatch);
+        for (byte[] certBuffer : certificates) {
+            Certificate cert = readCertificate(certBuffer);
+            if (certificateToMatch.equals(cert)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static Certificate readCertificate(byte[] certBuffer) throws CertificateException {
+        final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        return certFactory.generateCertificate(new ByteArrayInputStream(certBuffer));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java
new file mode 100644
index 0000000..f10124a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.deviceowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+public class ClearDeviceOwnerTest extends AndroidTestCase {
+
+    private DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        if (mDevicePolicyManager != null) {
+            removeActiveAdmin(BaseDeviceOwnerTest.getWho());
+            if (mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceOwnerTest.PACKAGE_NAME)) {
+                mDevicePolicyManager.clearDeviceOwnerApp(BaseDeviceOwnerTest.PACKAGE_NAME);
+            }
+            assertFalse(mDevicePolicyManager.isAdminActive(BaseDeviceOwnerTest.getWho()));
+            assertFalse(mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceOwnerTest.PACKAGE_NAME));
+        }
+
+        super.tearDown();
+    }
+
+    // This test clears the device owner and active admin on tearDown(). To be called from the host
+    // side test once a test case is finished.
+    public void testClearDeviceOwner() {
+    }
+
+    private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
+        if (mDevicePolicyManager.isAdminActive(cn)) {
+            mDevicePolicyManager.removeActiveAdmin(cn);
+            for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
+                Thread.sleep(100);
+            }
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/ProfileOwnerSetupTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceOwnerSetupTest.java
similarity index 61%
copy from hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/ProfileOwnerSetupTest.java
copy to hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceOwnerSetupTest.java
index 6fc0eb9..e6441ef 100644
--- a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/ProfileOwnerSetupTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceOwnerSetupTest.java
@@ -13,15 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.profileowner;
+
+package com.android.cts.deviceowner;
 
 
-public class ProfileOwnerSetupTest extends BaseProfileOwnerTest {
+public class DeviceOwnerSetupTest extends BaseDeviceOwnerTest {
 
-    // This test verifies that the setUp assertions on the base class are working to verify
-    // we are the profile owner and have a valid active admin.
-    public void testProfileOwnerSetup() {
-        // Empty test. We just want the assertions from super.setUp() to be executed.
+    // This test verifies that the setup assertions are working to verify
+    // we are the device owner and have a valid active admin.
+    public void testEmptyTest() {
     }
 
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity1.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity1.java
new file mode 100644
index 0000000..03ca9a4
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity1.java
@@ -0,0 +1,34 @@
+/*
+ * 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.deviceowner;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class ExampleIntentReceivingActivity1 extends Activity {
+    public static final String CONFIRM_ACTION = "com.android.cts.deviceowner.CONFIRM_1";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (getIntent().getAction().equals(PersistentIntentResolvingTest.EXAMPLE_ACTION)) {
+            sendBroadcast(new Intent(CONFIRM_ACTION));
+        }
+        finish();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity2.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity2.java
new file mode 100644
index 0000000..65ccb36
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity2.java
@@ -0,0 +1,34 @@
+/*
+ * 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.deviceowner;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class ExampleIntentReceivingActivity2 extends Activity {
+    public static final String CONFIRM_ACTION = "com.android.cts.deviceowner.CONFIRM_2";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (getIntent().getAction().equals(PersistentIntentResolvingTest.EXAMPLE_ACTION)) {
+            sendBroadcast(new Intent(CONFIRM_ACTION));
+        }
+        finish();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/FakeKeys.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/FakeKeys.java
new file mode 100644
index 0000000..11df8e5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/FakeKeys.java
@@ -0,0 +1,469 @@
+/*
+ * 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.deviceowner;
+
+// Copied from cts/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
+
+public class FakeKeys {
+    /*
+     * The keys and certificates below are generated with:
+     *
+     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
+     * openssl req -newkey rsa:1024 -keyout userkey.pem -nodes -days 3650 -out userkey.req
+     * mkdir -p demoCA/newcerts
+     * touch demoCA/index.txt
+     * echo "01" > demoCA/serial
+     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
+     */
+    public static class FAKE_RSA_1 {
+        /**
+         * Generated from above and converted with:
+         *
+         * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
+         */
+        public static final byte[] privateKey = {
+            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
+            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
+            (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
+            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
+            (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
+            (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
+            (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
+            (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
+            (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
+            (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
+            (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
+            (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
+            (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
+            (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
+            (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
+            (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
+            (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
+            (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
+            (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
+            (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
+            (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
+            (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
+            (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
+            (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
+            (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
+            (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
+            (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
+            (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
+            (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
+            (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
+            (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
+            (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
+            (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
+            (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
+            (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
+            (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
+            (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
+            (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
+            (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
+            (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
+            (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
+            (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
+            (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
+            (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
+            (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
+            (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
+            (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
+            (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
+            (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
+            (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
+            (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
+            (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
+            (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
+            (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
+            (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
+            (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
+            (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
+            (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
+            (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
+            (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
+            (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
+            (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
+            (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
+            (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
+            (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
+            (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
+            (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
+            (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
+            (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
+            (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
+            (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
+            (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
+            (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
+            (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
+            (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
+            (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
+            (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
+            (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
+            (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
+            (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
+            (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
+            (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
+            (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
+            (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
+            (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
+            (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
+            (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
+            (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
+            (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
+            (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
+            (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
+            (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
+            (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
+            (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
+            (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
+            (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
+            (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
+            (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
+            (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
+            (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
+            (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
+            (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
+            (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
+            (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
+        };
+
+        /**
+         * Generated from above and converted with:
+         *
+         * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+         */
+        public static final byte[] caCertificate = {
+            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xce, (byte) 0x30, (byte) 0x82,
+            (byte) 0x02, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0x6a,
+            (byte) 0xa2, (byte) 0xf4, (byte) 0x2e, (byte) 0x55, (byte) 0x48, (byte) 0x0a,
+            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31,
+            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53,
+            (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43,
+            (byte) 0x41, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d,
+            (byte) 0x4d, (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61,
+            (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65,
+            (byte) 0x77, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12,
+            (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69,
+            (byte) 0x64, (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74,
+            (byte) 0x20, (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73,
+            (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32,
+            (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x34, (byte) 0x31, (byte) 0x36,
+            (byte) 0x35, (byte) 0x35, (byte) 0x34, (byte) 0x34, (byte) 0x5a, (byte) 0x17,
+            (byte) 0x0d, (byte) 0x32, (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31,
+            (byte) 0x32, (byte) 0x31, (byte) 0x36, (byte) 0x35, (byte) 0x35, (byte) 0x34,
+            (byte) 0x34, (byte) 0x5a, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b,
+            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31,
+            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41,
+            (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d,
+            (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69,
+            (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77,
+            (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41,
+            (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64,
+            (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20,
+            (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30,
+            (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
+            (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
+            (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
+            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa3, (byte) 0x72,
+            (byte) 0xab, (byte) 0xd0, (byte) 0xe4, (byte) 0xad, (byte) 0x2f, (byte) 0xe7,
+            (byte) 0xe2, (byte) 0x79, (byte) 0x07, (byte) 0x36, (byte) 0x3d, (byte) 0x0c,
+            (byte) 0x8d, (byte) 0x42, (byte) 0x9a, (byte) 0x0a, (byte) 0x33, (byte) 0x64,
+            (byte) 0xb3, (byte) 0xcd, (byte) 0xb2, (byte) 0xd7, (byte) 0x3a, (byte) 0x42,
+            (byte) 0x06, (byte) 0x77, (byte) 0x45, (byte) 0x29, (byte) 0xe9, (byte) 0xcb,
+            (byte) 0xb7, (byte) 0x4a, (byte) 0xd6, (byte) 0xee, (byte) 0xad, (byte) 0x01,
+            (byte) 0x91, (byte) 0x9b, (byte) 0x0c, (byte) 0x59, (byte) 0xa1, (byte) 0x03,
+            (byte) 0xfa, (byte) 0xf0, (byte) 0x5a, (byte) 0x7c, (byte) 0x4f, (byte) 0xf7,
+            (byte) 0x8d, (byte) 0x36, (byte) 0x0f, (byte) 0x1f, (byte) 0x45, (byte) 0x7d,
+            (byte) 0x1b, (byte) 0x31, (byte) 0xa1, (byte) 0x35, (byte) 0x0b, (byte) 0x00,
+            (byte) 0xed, (byte) 0x7a, (byte) 0xb6, (byte) 0xc8, (byte) 0x4e, (byte) 0xa9,
+            (byte) 0x86, (byte) 0x4c, (byte) 0x7b, (byte) 0x99, (byte) 0x57, (byte) 0x41,
+            (byte) 0x12, (byte) 0xef, (byte) 0x6b, (byte) 0xbc, (byte) 0x3d, (byte) 0x60,
+            (byte) 0xf2, (byte) 0x99, (byte) 0x1a, (byte) 0xcd, (byte) 0xed, (byte) 0x56,
+            (byte) 0xa4, (byte) 0xe5, (byte) 0x36, (byte) 0x9f, (byte) 0x24, (byte) 0x1f,
+            (byte) 0xdc, (byte) 0x89, (byte) 0x40, (byte) 0xc8, (byte) 0x99, (byte) 0x92,
+            (byte) 0xab, (byte) 0x4a, (byte) 0xb5, (byte) 0x61, (byte) 0x45, (byte) 0x62,
+            (byte) 0xff, (byte) 0xa3, (byte) 0x45, (byte) 0x65, (byte) 0xaf, (byte) 0xf6,
+            (byte) 0x27, (byte) 0x30, (byte) 0x51, (byte) 0x0e, (byte) 0x0e, (byte) 0xeb,
+            (byte) 0x79, (byte) 0x0c, (byte) 0xbe, (byte) 0xb3, (byte) 0x0a, (byte) 0x6f,
+            (byte) 0x29, (byte) 0x06, (byte) 0xdc, (byte) 0x2f, (byte) 0x6b, (byte) 0x51,
+            (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
+            (byte) 0x81, (byte) 0xb1, (byte) 0x30, (byte) 0x81, (byte) 0xae, (byte) 0x30,
+            (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e,
+            (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x33, (byte) 0x05,
+            (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60, (byte) 0xc7, (byte) 0xf9,
+            (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c, (byte) 0x8f, (byte) 0x6d,
+            (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e, (byte) 0x5d, (byte) 0x51,
+            (byte) 0x30, (byte) 0x7f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
+            (byte) 0x23, (byte) 0x04, (byte) 0x78, (byte) 0x30, (byte) 0x76, (byte) 0x80,
+            (byte) 0x14, (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f,
+            (byte) 0x60, (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73,
+            (byte) 0x5c, (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97,
+            (byte) 0x8e, (byte) 0x5d, (byte) 0x51, (byte) 0xa1, (byte) 0x53, (byte) 0xa4,
+            (byte) 0x51, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
+            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
+            (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
+            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
+            (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
+            (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
+            (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
+            (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
+            (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
+            (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
+            (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x82, (byte) 0x09,
+            (byte) 0x00, (byte) 0xe1, (byte) 0x6a, (byte) 0xa2, (byte) 0xf4, (byte) 0x2e,
+            (byte) 0x55, (byte) 0x48, (byte) 0x0a, (byte) 0x30, (byte) 0x0c, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05,
+            (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30,
+            (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
+            (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
+            (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
+            (byte) 0x8c, (byte) 0x30, (byte) 0x42, (byte) 0xfa, (byte) 0xeb, (byte) 0x1a,
+            (byte) 0x26, (byte) 0xeb, (byte) 0xda, (byte) 0x56, (byte) 0x32, (byte) 0xf2,
+            (byte) 0x9d, (byte) 0xa5, (byte) 0x24, (byte) 0xd8, (byte) 0x3a, (byte) 0xda,
+            (byte) 0x30, (byte) 0xa6, (byte) 0x8b, (byte) 0x46, (byte) 0xfe, (byte) 0xfe,
+            (byte) 0xdb, (byte) 0xf1, (byte) 0xe6, (byte) 0xe1, (byte) 0x7c, (byte) 0x1b,
+            (byte) 0xe7, (byte) 0x77, (byte) 0x00, (byte) 0xa1, (byte) 0x1c, (byte) 0x19,
+            (byte) 0x17, (byte) 0x73, (byte) 0xb0, (byte) 0xf0, (byte) 0x9d, (byte) 0xf3,
+            (byte) 0x4f, (byte) 0xb6, (byte) 0xbc, (byte) 0xc7, (byte) 0x47, (byte) 0x85,
+            (byte) 0x2a, (byte) 0x4a, (byte) 0xa1, (byte) 0xa5, (byte) 0x58, (byte) 0xf5,
+            (byte) 0xc5, (byte) 0x1a, (byte) 0x51, (byte) 0xb1, (byte) 0x04, (byte) 0x80,
+            (byte) 0xee, (byte) 0x3a, (byte) 0xec, (byte) 0x2f, (byte) 0xe1, (byte) 0xfd,
+            (byte) 0x58, (byte) 0xeb, (byte) 0xed, (byte) 0x82, (byte) 0x9e, (byte) 0x38,
+            (byte) 0xa3, (byte) 0x24, (byte) 0x75, (byte) 0xf7, (byte) 0x3e, (byte) 0xc2,
+            (byte) 0xc5, (byte) 0x27, (byte) 0xeb, (byte) 0x6f, (byte) 0x7b, (byte) 0x50,
+            (byte) 0xda, (byte) 0x43, (byte) 0xdc, (byte) 0x3b, (byte) 0x0b, (byte) 0x6f,
+            (byte) 0x78, (byte) 0x8f, (byte) 0xb0, (byte) 0x66, (byte) 0xe1, (byte) 0x12,
+            (byte) 0x87, (byte) 0x5f, (byte) 0x97, (byte) 0x7b, (byte) 0xca, (byte) 0x14,
+            (byte) 0x79, (byte) 0xf7, (byte) 0xe8, (byte) 0x6c, (byte) 0x72, (byte) 0xdb,
+            (byte) 0x91, (byte) 0x65, (byte) 0x17, (byte) 0x54, (byte) 0xe0, (byte) 0x74,
+            (byte) 0x1d, (byte) 0xac, (byte) 0x47, (byte) 0x04, (byte) 0x12, (byte) 0xe0,
+            (byte) 0xc3, (byte) 0x66, (byte) 0x19, (byte) 0x05, (byte) 0x2e, (byte) 0x7e,
+            (byte) 0xf1, (byte) 0x61
+        };
+    }
+
+    /*
+     * The keys and certificates below are generated with:
+     *
+     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
+     * openssl dsaparam -out dsaparam.pem 1024
+     * openssl req -newkey dsa:dsaparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
+     * mkdir -p demoCA/newcerts
+     * touch demoCA/index.txt
+     * echo "01" > demoCA/serial
+     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
+     */
+    public static class FAKE_DSA_1 {
+        /**
+         * Generated from above and converted with: openssl pkcs8 -topk8 -outform d
+         * -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
+         */
+        public static final byte[] privateKey = {
+            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x4c, (byte) 0x02, (byte) 0x01,
+            (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2c, (byte) 0x06,
+            (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38,
+            (byte) 0x04, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1f,
+            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xb3, (byte) 0x23,
+            (byte) 0xf7, (byte) 0x86, (byte) 0xbd, (byte) 0x3b, (byte) 0x86, (byte) 0xcc,
+            (byte) 0xc3, (byte) 0x91, (byte) 0xc0, (byte) 0x30, (byte) 0x32, (byte) 0x02,
+            (byte) 0x47, (byte) 0x35, (byte) 0x01, (byte) 0xef, (byte) 0xee, (byte) 0x98,
+            (byte) 0x13, (byte) 0x56, (byte) 0x49, (byte) 0x47, (byte) 0xb5, (byte) 0x20,
+            (byte) 0xa8, (byte) 0x60, (byte) 0xcb, (byte) 0xc0, (byte) 0xd5, (byte) 0x77,
+            (byte) 0xc1, (byte) 0x69, (byte) 0xcd, (byte) 0x18, (byte) 0x34, (byte) 0x92,
+            (byte) 0xf2, (byte) 0x6a, (byte) 0x2a, (byte) 0x10, (byte) 0x59, (byte) 0x1c,
+            (byte) 0x91, (byte) 0x20, (byte) 0x51, (byte) 0xca, (byte) 0x37, (byte) 0xb2,
+            (byte) 0x87, (byte) 0xa6, (byte) 0x8a, (byte) 0x02, (byte) 0xfd, (byte) 0x45,
+            (byte) 0x46, (byte) 0xf9, (byte) 0x76, (byte) 0xb1, (byte) 0x35, (byte) 0x38,
+            (byte) 0x8d, (byte) 0xff, (byte) 0x4c, (byte) 0x5d, (byte) 0x75, (byte) 0x8f,
+            (byte) 0x66, (byte) 0x15, (byte) 0x7d, (byte) 0x7b, (byte) 0xda, (byte) 0xdb,
+            (byte) 0x57, (byte) 0x39, (byte) 0xff, (byte) 0x91, (byte) 0x3f, (byte) 0xdd,
+            (byte) 0xe2, (byte) 0xb4, (byte) 0x22, (byte) 0x60, (byte) 0x4c, (byte) 0x32,
+            (byte) 0x3b, (byte) 0x9d, (byte) 0x34, (byte) 0x9f, (byte) 0xb9, (byte) 0x5d,
+            (byte) 0x75, (byte) 0xb9, (byte) 0xd3, (byte) 0x7f, (byte) 0x11, (byte) 0xba,
+            (byte) 0xb7, (byte) 0xc8, (byte) 0x32, (byte) 0xc6, (byte) 0xce, (byte) 0x71,
+            (byte) 0x91, (byte) 0xd3, (byte) 0x32, (byte) 0xaf, (byte) 0x4d, (byte) 0x7e,
+            (byte) 0x7c, (byte) 0x15, (byte) 0xf7, (byte) 0x71, (byte) 0x2c, (byte) 0x52,
+            (byte) 0x65, (byte) 0x4d, (byte) 0xa9, (byte) 0x81, (byte) 0x25, (byte) 0x35,
+            (byte) 0xce, (byte) 0x0b, (byte) 0x5b, (byte) 0x56, (byte) 0xfe, (byte) 0xf1,
+            (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xeb, (byte) 0x4e, (byte) 0x7f,
+            (byte) 0x7a, (byte) 0x31, (byte) 0xb3, (byte) 0x7d, (byte) 0x8d, (byte) 0xb2,
+            (byte) 0xf7, (byte) 0xaf, (byte) 0xad, (byte) 0xb1, (byte) 0x42, (byte) 0x92,
+            (byte) 0xf3, (byte) 0x6c, (byte) 0xe4, (byte) 0xed, (byte) 0x8b, (byte) 0x02,
+            (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x81, (byte) 0xc8, (byte) 0x36,
+            (byte) 0x48, (byte) 0xdb, (byte) 0x71, (byte) 0x2b, (byte) 0x91, (byte) 0xce,
+            (byte) 0x6d, (byte) 0xbc, (byte) 0xb8, (byte) 0xf9, (byte) 0xcb, (byte) 0x50,
+            (byte) 0x91, (byte) 0x10, (byte) 0x8a, (byte) 0xf8, (byte) 0x37, (byte) 0x50,
+            (byte) 0xda, (byte) 0x4f, (byte) 0xc8, (byte) 0x4d, (byte) 0x73, (byte) 0xcb,
+            (byte) 0x4d, (byte) 0xb0, (byte) 0x19, (byte) 0x54, (byte) 0x5a, (byte) 0xf3,
+            (byte) 0x6c, (byte) 0xc9, (byte) 0xd8, (byte) 0x96, (byte) 0xd9, (byte) 0xb0,
+            (byte) 0x54, (byte) 0x7e, (byte) 0x7d, (byte) 0xe2, (byte) 0x58, (byte) 0x0e,
+            (byte) 0x5f, (byte) 0xc0, (byte) 0xce, (byte) 0xb9, (byte) 0x5c, (byte) 0xe3,
+            (byte) 0xd3, (byte) 0xdf, (byte) 0xcf, (byte) 0x45, (byte) 0x74, (byte) 0xfb,
+            (byte) 0xe6, (byte) 0x20, (byte) 0xe7, (byte) 0xfc, (byte) 0x0f, (byte) 0xca,
+            (byte) 0xdb, (byte) 0xc0, (byte) 0x0b, (byte) 0xe1, (byte) 0x5a, (byte) 0x16,
+            (byte) 0x1d, (byte) 0xb3, (byte) 0x2e, (byte) 0xe5, (byte) 0x5f, (byte) 0x89,
+            (byte) 0x17, (byte) 0x73, (byte) 0x50, (byte) 0xd1, (byte) 0x4a, (byte) 0x60,
+            (byte) 0xb7, (byte) 0xaa, (byte) 0xf0, (byte) 0xc7, (byte) 0xc5, (byte) 0x03,
+            (byte) 0x4e, (byte) 0x36, (byte) 0x51, (byte) 0x9e, (byte) 0x2f, (byte) 0xfa,
+            (byte) 0xf3, (byte) 0xd6, (byte) 0x58, (byte) 0x14, (byte) 0x02, (byte) 0xb4,
+            (byte) 0x41, (byte) 0xd6, (byte) 0x72, (byte) 0x6f, (byte) 0x58, (byte) 0x5b,
+            (byte) 0x2d, (byte) 0x23, (byte) 0xc0, (byte) 0x75, (byte) 0x4f, (byte) 0x39,
+            (byte) 0xa8, (byte) 0x6a, (byte) 0xdf, (byte) 0x79, (byte) 0x21, (byte) 0xf2,
+            (byte) 0x77, (byte) 0x91, (byte) 0x3f, (byte) 0x1c, (byte) 0x4d, (byte) 0x48,
+            (byte) 0x78, (byte) 0xcd, (byte) 0xed, (byte) 0x79, (byte) 0x23, (byte) 0x04,
+            (byte) 0x17, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xc7, (byte) 0xe7,
+            (byte) 0xe2, (byte) 0x6b, (byte) 0x14, (byte) 0xe6, (byte) 0x31, (byte) 0x12,
+            (byte) 0xb2, (byte) 0x1e, (byte) 0xd4, (byte) 0xf2, (byte) 0x9b, (byte) 0x2c,
+            (byte) 0xf6, (byte) 0x54, (byte) 0x4c, (byte) 0x12, (byte) 0xe8, (byte) 0x22
+
+        };
+
+        /**
+         * Generated from above and converted with:
+         *
+         * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+         */
+        public static final byte[] caCertificate = new byte[] {
+            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8a, (byte) 0x30, (byte) 0x82,
+            (byte) 0x01, (byte) 0xf3, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x87, (byte) 0xc0,
+            (byte) 0x68, (byte) 0x7f, (byte) 0x42, (byte) 0x92, (byte) 0x0b, (byte) 0x7a,
+            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x5e, (byte) 0x31,
+            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55,
+            (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53,
+            (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74,
+            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30,
+            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
+            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
+            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
+            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
+            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
+            (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17, (byte) 0x30, (byte) 0x15,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c,
+            (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
+            (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
+            (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17,
+            (byte) 0x0d, (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32,
+            (byte) 0x37, (byte) 0x32, (byte) 0x33, (byte) 0x33, (byte) 0x31, (byte) 0x32,
+            (byte) 0x39, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33,
+            (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x35, (byte) 0x32, (byte) 0x33,
+            (byte) 0x33, (byte) 0x31, (byte) 0x32, (byte) 0x39, (byte) 0x5a, (byte) 0x30,
+            (byte) 0x5e, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02,
+            (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c,
+            (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
+            (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31,
+            (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e,
+            (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74,
+            (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69,
+            (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79,
+            (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17,
+            (byte) 0x30, (byte) 0x15, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x03, (byte) 0x0c, (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e,
+            (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c,
+            (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
+            (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
+            (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
+            (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
+            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa4, (byte) 0xc7,
+            (byte) 0x06, (byte) 0xba, (byte) 0xdf, (byte) 0x2b, (byte) 0xee, (byte) 0xd2,
+            (byte) 0xb9, (byte) 0xe4, (byte) 0x52, (byte) 0x21, (byte) 0x68, (byte) 0x2b,
+            (byte) 0x83, (byte) 0xdf, (byte) 0xe3, (byte) 0x9c, (byte) 0x08, (byte) 0x73,
+            (byte) 0xdd, (byte) 0x90, (byte) 0xea, (byte) 0x97, (byte) 0x0c, (byte) 0x96,
+            (byte) 0x20, (byte) 0xb1, (byte) 0xee, (byte) 0x11, (byte) 0xd5, (byte) 0xd4,
+            (byte) 0x7c, (byte) 0x44, (byte) 0x96, (byte) 0x2e, (byte) 0x6e, (byte) 0xa2,
+            (byte) 0xb2, (byte) 0xa3, (byte) 0x4b, (byte) 0x0f, (byte) 0x32, (byte) 0x90,
+            (byte) 0xaf, (byte) 0x5c, (byte) 0x6f, (byte) 0x00, (byte) 0x88, (byte) 0x45,
+            (byte) 0x4e, (byte) 0x9b, (byte) 0x26, (byte) 0xc1, (byte) 0x94, (byte) 0x3c,
+            (byte) 0xfe, (byte) 0x10, (byte) 0xbd, (byte) 0xda, (byte) 0xf2, (byte) 0x8d,
+            (byte) 0x03, (byte) 0x52, (byte) 0x32, (byte) 0x11, (byte) 0xff, (byte) 0xf6,
+            (byte) 0xf9, (byte) 0x6e, (byte) 0x8f, (byte) 0x0f, (byte) 0xc8, (byte) 0x0a,
+            (byte) 0x48, (byte) 0x39, (byte) 0x33, (byte) 0xb9, (byte) 0x0c, (byte) 0xb3,
+            (byte) 0x2b, (byte) 0xab, (byte) 0x7d, (byte) 0x79, (byte) 0x6f, (byte) 0x57,
+            (byte) 0x5b, (byte) 0xb8, (byte) 0x84, (byte) 0xb6, (byte) 0xcc, (byte) 0xe8,
+            (byte) 0x30, (byte) 0x78, (byte) 0xff, (byte) 0x92, (byte) 0xe5, (byte) 0x43,
+            (byte) 0x2e, (byte) 0xef, (byte) 0x66, (byte) 0x98, (byte) 0xb4, (byte) 0xfe,
+            (byte) 0xa2, (byte) 0x40, (byte) 0xf2, (byte) 0x1f, (byte) 0xd0, (byte) 0x86,
+            (byte) 0x16, (byte) 0xc8, (byte) 0x45, (byte) 0xc4, (byte) 0x52, (byte) 0xcb,
+            (byte) 0x31, (byte) 0x5c, (byte) 0x9f, (byte) 0x32, (byte) 0x3b, (byte) 0xf7,
+            (byte) 0x19, (byte) 0x08, (byte) 0xc7, (byte) 0x00, (byte) 0x21, (byte) 0x7d,
+            (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
+            (byte) 0x50, (byte) 0x30, (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16,
+            (byte) 0x04, (byte) 0x14, (byte) 0x47, (byte) 0x82, (byte) 0xa3, (byte) 0xf1,
+            (byte) 0xc2, (byte) 0x7e, (byte) 0x3a, (byte) 0xde, (byte) 0x4f, (byte) 0x30,
+            (byte) 0x4c, (byte) 0x7f, (byte) 0x72, (byte) 0x81, (byte) 0x15, (byte) 0x32,
+            (byte) 0xda, (byte) 0x7f, (byte) 0x58, (byte) 0x18, (byte) 0x30, (byte) 0x1f,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04,
+            (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x47,
+            (byte) 0x82, (byte) 0xa3, (byte) 0xf1, (byte) 0xc2, (byte) 0x7e, (byte) 0x3a,
+            (byte) 0xde, (byte) 0x4f, (byte) 0x30, (byte) 0x4c, (byte) 0x7f, (byte) 0x72,
+            (byte) 0x81, (byte) 0x15, (byte) 0x32, (byte) 0xda, (byte) 0x7f, (byte) 0x58,
+            (byte) 0x18, (byte) 0x30, (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03,
+            (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
+            (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
+            (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00,
+            (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x08, (byte) 0x7f,
+            (byte) 0x6a, (byte) 0x48, (byte) 0x90, (byte) 0x7b, (byte) 0x9b, (byte) 0x72,
+            (byte) 0x13, (byte) 0xa7, (byte) 0xef, (byte) 0x6b, (byte) 0x0b, (byte) 0x59,
+            (byte) 0xe5, (byte) 0x49, (byte) 0x72, (byte) 0x3a, (byte) 0xc8, (byte) 0x84,
+            (byte) 0xcc, (byte) 0x23, (byte) 0x18, (byte) 0x4c, (byte) 0xec, (byte) 0xc7,
+            (byte) 0xef, (byte) 0xcb, (byte) 0xa7, (byte) 0xbe, (byte) 0xe4, (byte) 0xef,
+            (byte) 0x8f, (byte) 0xc6, (byte) 0x06, (byte) 0x8c, (byte) 0xc0, (byte) 0xe4,
+            (byte) 0x2f, (byte) 0x2a, (byte) 0xc0, (byte) 0x35, (byte) 0x7d, (byte) 0x5e,
+            (byte) 0x19, (byte) 0x29, (byte) 0x8c, (byte) 0xb9, (byte) 0xf1, (byte) 0x1e,
+            (byte) 0xaf, (byte) 0x82, (byte) 0xd8, (byte) 0xe3, (byte) 0x88, (byte) 0xe1,
+            (byte) 0x31, (byte) 0xc8, (byte) 0x82, (byte) 0x1f, (byte) 0x83, (byte) 0xa9,
+            (byte) 0xde, (byte) 0xfe, (byte) 0x4b, (byte) 0xe2, (byte) 0x78, (byte) 0x64,
+            (byte) 0xed, (byte) 0xa4, (byte) 0x7b, (byte) 0xee, (byte) 0x8d, (byte) 0x71,
+            (byte) 0x1b, (byte) 0x44, (byte) 0xe6, (byte) 0xb7, (byte) 0xe8, (byte) 0xc5,
+            (byte) 0x9a, (byte) 0x93, (byte) 0x92, (byte) 0x6f, (byte) 0x6f, (byte) 0xdb,
+            (byte) 0xbd, (byte) 0xd7, (byte) 0x03, (byte) 0x85, (byte) 0xa9, (byte) 0x5f,
+            (byte) 0x53, (byte) 0x5f, (byte) 0x5d, (byte) 0x30, (byte) 0xc6, (byte) 0xd9,
+            (byte) 0xce, (byte) 0x34, (byte) 0xa8, (byte) 0xbe, (byte) 0x31, (byte) 0x47,
+            (byte) 0x1c, (byte) 0xa4, (byte) 0x7f, (byte) 0xc0, (byte) 0x2c, (byte) 0xbc,
+            (byte) 0xfe, (byte) 0x1a, (byte) 0x31, (byte) 0xd8, (byte) 0x77, (byte) 0x4d,
+            (byte) 0xfc, (byte) 0x45, (byte) 0x84, (byte) 0xfc, (byte) 0x45, (byte) 0x12,
+            (byte) 0xab, (byte) 0x50, (byte) 0xe4, (byte) 0x45, (byte) 0xe5, (byte) 0x11
+        };
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
new file mode 100644
index 0000000..fe2bdda
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.deviceowner;
+
+import static com.android.cts.deviceowner.FakeKeys.FAKE_RSA_1;
+
+import android.app.admin.DevicePolicyManager;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.Certificate;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+public class KeyManagementTest extends BaseDeviceOwnerTest {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        assertTrue(mDevicePolicyManager.resetPassword("test", 0));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager.setPasswordQuality(getWho(),
+                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+        mDevicePolicyManager.setPasswordMinimumLength(getWho(), 0);
+        assertTrue(mDevicePolicyManager.resetPassword("", 0));
+        super.tearDown();
+    }
+
+    public void testCanInstallValidRsaKeypair()
+            throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException {
+        final String alias = "com.android.test.valid-rsa-key-1";
+        final PrivateKey privKey = getPrivateKey(FAKE_RSA_1.privateKey , "RSA");
+        final Certificate cert = getCertificate(FAKE_RSA_1.caCertificate);
+        assertTrue(mDevicePolicyManager.installKeyPair(getWho(), privKey, cert, alias));
+    }
+
+    public void testNullKeyParamsFailGracefully()
+            throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException {
+        final String alias = "com.android.test.null-key-1";
+        final PrivateKey privKey = getPrivateKey(FAKE_RSA_1.privateKey, "RSA");
+        final Certificate cert = getCertificate(FAKE_RSA_1.caCertificate);
+        try {
+            assertFalse(mDevicePolicyManager.installKeyPair(getWho(), null, cert, alias));
+        } catch (NullPointerException accept) {
+            // Accept either false return value or NPE
+        }
+        try {
+            assertFalse(mDevicePolicyManager.installKeyPair(getWho(), privKey, null, alias));
+        } catch (NullPointerException accept) {
+            // Accept either false return value or NPE
+        }
+    }
+
+    public void testNullAdminComponentIsDenied()
+            throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException {
+        final String alias = "com.android.test.null-admin-1";
+        final PrivateKey privKey = getPrivateKey(FAKE_RSA_1.privateKey, "RSA");
+        final Certificate cert = getCertificate(FAKE_RSA_1.caCertificate);
+        try {
+            assertFalse(mDevicePolicyManager.installKeyPair(null, privKey, cert, alias));
+            fail("Exception should have been thrown for null ComponentName");
+        } catch (SecurityException | NullPointerException expected) {
+        }
+    }
+
+    PrivateKey getPrivateKey(final byte[] key, String type)
+            throws NoSuchAlgorithmException, InvalidKeySpecException {
+        return KeyFactory.getInstance(type).generatePrivate(
+                new PKCS8EncodedKeySpec(key));
+    }
+
+    Certificate getCertificate(byte[] cert) throws CertificateException {
+        return CertificateFactory.getInstance("X.509").generateCertificate(
+                new ByteArrayInputStream(cert));
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
new file mode 100644
index 0000000..c0ca8e2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
@@ -0,0 +1,293 @@
+/*
+ * 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.deviceowner;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.provider.Settings;
+
+// This is not a standard test of an android activity (such as
+// ActivityInstrumentationTestCase2) as it is attempting to test the actual
+// life cycle and how it is affected by lock task, rather than mock intents
+// and setup.
+public class LockTaskTest extends BaseDeviceOwnerTest {
+
+    private static final String TEST_PACKAGE = "com.google.android.example.somepackage";
+
+    /**
+     * The tests below need to keep detailed track of the state of the activity
+     * that is started and stopped frequently.  To do this it sends a number of
+     * broadcasts that are caught here and translated into booleans (as well as
+     * notify some locks in case we are waiting).  There is also an action used
+     * to specify that the activity has finished handling the current command
+     * (INTENT_ACTION).
+     */
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (LockTaskUtilityActivity.CREATE_ACTION.equals(action)) {
+                synchronized (mActivityRunningLock) {
+                    mIsActivityRunning = true;
+                    mActivityRunningLock.notify();
+                }
+            } else if (LockTaskUtilityActivity.DESTROY_ACTION.equals(action)) {
+                synchronized (mActivityRunningLock) {
+                    mIsActivityRunning = false;
+                    mActivityRunningLock.notify();
+                }
+            } else if (LockTaskUtilityActivity.RESUME_ACTION.equals(action)) {
+                synchronized (mActivityResumedLock) {
+                    mIsActivityResumed = true;
+                    mActivityResumedLock.notify();
+                }
+            } else if (LockTaskUtilityActivity.PAUSE_ACTION.equals(action)) {
+                synchronized (mActivityResumedLock) {
+                    mIsActivityResumed = false;
+                    mActivityResumedLock.notify();
+                }
+            } else if (LockTaskUtilityActivity.INTENT_ACTION.equals(action)) {
+                // Notify that intent has been handled.
+                synchronized (LockTaskTest.this) {
+                    mIntentHandled = true;
+                    LockTaskTest.this.notify();
+                }
+            }
+        }
+    };
+
+    private boolean mIsActivityRunning;
+    private boolean mIsActivityResumed;
+    private final Object mActivityRunningLock = new Object();
+    private final Object mActivityResumedLock = new Object();
+    private Boolean mIntentHandled;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(LockTaskUtilityActivity.CREATE_ACTION);
+        filter.addAction(LockTaskUtilityActivity.DESTROY_ACTION);
+        filter.addAction(LockTaskUtilityActivity.INTENT_ACTION);
+        filter.addAction(LockTaskUtilityActivity.RESUME_ACTION);
+        filter.addAction(LockTaskUtilityActivity.PAUSE_ACTION);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mContext.unregisterReceiver(mReceiver);
+        super.tearDown();
+    }
+
+    public void testSetLockTaskPackages() {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { TEST_PACKAGE });
+        assertTrue(mDevicePolicyManager.isLockTaskPermitted(TEST_PACKAGE));
+
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[0]);
+        assertFalse(mDevicePolicyManager.isLockTaskPermitted(TEST_PACKAGE));
+    }
+
+    // Start lock task, verify that ActivityManager knows thats what is going on.
+    public void testStartLockTask() {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+        startLockTask();
+        waitForResume();
+
+        // Verify that activity open and activity manager is in lock task.
+        ActivityManager activityManager = (ActivityManager)
+                mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        assertTrue(activityManager.isInLockTaskMode());
+        assertTrue(mIsActivityRunning);
+        assertTrue(mIsActivityResumed);
+
+        stopAndFinish(activityManager);
+    }
+
+    // Verifies that the act of finishing is blocked by ActivityManager in lock task.
+    // This results in onDestroy not being called until stopLockTask is called before finish.
+    public void testCannotFinish() {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+        startLockTask();
+
+        // If lock task has not exited then the activity shouldn't actually receive onDestroy.
+        finishAndWait();
+        ActivityManager activityManager = (ActivityManager)
+                mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        assertTrue(activityManager.isInLockTaskMode());
+        assertTrue(mIsActivityRunning);
+
+        stopAndFinish(activityManager);
+    }
+
+    // This test has the UtilityActivity trigger starting another activity (settings)
+    // this should be permitted as a part of lock task (since it isn't a new task).
+    // As a result onPause should be called as it goes to a new activity.
+// TODO: Reinstate once we make this test not flaky (if fails on Nexus 7 v2 most of the time,
+//       especially if testCannotStartActivityOutsideTask() is commented out.
+//    public void testStartActivityWithinTask() {
+//        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+//        startLockTask();
+//        waitForResume();
+//
+//        Intent launchIntent = new Intent(Settings.ACTION_SETTINGS);
+//        Intent lockTaskUtility = getLockTaskUtility();
+//        lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent);
+//        mContext.startActivity(lockTaskUtility);
+//
+//        synchronized (mActivityResumedLock) {
+//            if (mIsActivityResumed) {
+//                try {
+//                    mActivityResumedLock.wait(60000);
+//                } catch (InterruptedException e) {
+//                }
+//                assertFalse(mIsActivityResumed);
+//            }
+//        }
+//        stopAndFinish(null);
+//    }
+
+    // This launches an activity that is not part of the current task and therefore
+    // should be blocked.  This is verified by making sure that the activity does
+    // not get a call to onPause.
+// TODO: Reinstate once we make this test not flaky (if fails on Nexus 7 v2 most of the time) 
+//    public void testCannotStartActivityOutsideTask() {
+//        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+//        startLockTask();
+//        waitForResume();
+//
+//        Intent launchIntent = new Intent(Settings.ACTION_SETTINGS);
+//        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+//        mContext.startActivity(launchIntent);
+//
+//        synchronized (mActivityResumedLock) {
+//            try {
+//                mActivityResumedLock.wait(90000);
+//            } catch (InterruptedException e) {
+//            }
+//            assertTrue(mIsActivityResumed);
+//        }
+//        stopAndFinish(null);
+//    }
+
+    /**
+     * Call stopLockTask and finish on the LockTaskUtilityActivity.
+     *
+     * Verify that the activity is no longer running.
+     *
+     * If activityManager is not null then verify that the ActivityManager
+     * is no longer in lock task mode.
+     */
+    private void stopAndFinish(ActivityManager activityManager) {
+        stopLockTask();
+        finishAndWait();
+        if (activityManager != null) {
+            assertFalse(activityManager.isInLockTaskMode());
+        }
+        assertFalse(mIsActivityRunning);
+    }
+
+    /**
+     * Call finish on the LockTaskUtilityActivity and wait for
+     * onDestroy to be called.
+     */
+    private void finishAndWait() {
+        synchronized (mActivityRunningLock) {
+            finish();
+            if (mIsActivityRunning) {
+                try {
+                    mActivityRunningLock.wait(20000);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Wait for onPause to be called on the LockTaskUtilityActivity.
+     */
+    private void waitForResume() {
+        // It may take a moment for the resume to come in.
+        synchronized (mActivityResumedLock) {
+            if (!mIsActivityResumed) {
+                try {
+                    mActivityResumedLock.wait(20000);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Calls startLockTask on the LockTaskUtilityActivity
+     */
+    private void startLockTask() {
+        Intent intent = getLockTaskUtility();
+        intent.putExtra(LockTaskUtilityActivity.START_LOCK_TASK, true);
+        startAndWait(intent);
+    }
+
+    /**
+     * Calls stopLockTask on the LockTaskUtilityActivity
+     */
+    private void stopLockTask() {
+        Intent intent = getLockTaskUtility();
+        intent.putExtra(LockTaskUtilityActivity.STOP_LOCK_TASK, true);
+        startAndWait(intent);
+    }
+
+    /**
+     * Calls finish on the LockTaskUtilityActivity
+     */
+    private void finish() {
+        Intent intent = getLockTaskUtility();
+        intent.putExtra(LockTaskUtilityActivity.FINISH, true);
+        startAndWait(intent);
+    }
+
+    /**
+     * Sends a command intent to the LockTaskUtilityActivity and waits
+     * to receive the broadcast back confirming it has finished processing
+     * the command.
+     */
+    private void startAndWait(Intent intent) {
+        mIntentHandled = false;
+        synchronized (this) {
+            mContext.startActivity(intent);
+            // Give 20 secs to finish.
+            try {
+                wait(20000);
+            } catch (InterruptedException e) {
+            }
+            assertTrue(mIntentHandled);
+        }
+    }
+
+    /**
+     * Get basic intent that points at the LockTaskUtilityActivity.
+     *
+     * This intent includes the flags to make it act as single top.
+     */
+    private Intent getLockTaskUtility() {
+        Intent intent = new Intent();
+        intent.setClassName(PACKAGE_NAME, LockTaskUtilityActivity.class.getName());
+        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+        return intent;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivity.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivity.java
new file mode 100644
index 0000000..2901f5b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivity.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.deviceowner;
+
+import android.app.Activity;
+import android.content.Intent;
+
+public class LockTaskUtilityActivity extends Activity {
+
+    public static final String START_LOCK_TASK = "startLockTask";
+    public static final String STOP_LOCK_TASK = "stopLockTask";
+    public static final String START_ACTIVITY = "startActivity";
+    public static final String FINISH = "finish";
+
+    public static final String CREATE_ACTION = "com.android.cts.deviceowner.LOCK_TASK_CREATE";
+    public static final String DESTROY_ACTION = "com.android.cts.deviceowner.LOCK_TASK_DESTROY";
+    public static final String PAUSE_ACTION = "com.android.cts.deviceowner.LOCK_TASK_PAUSE";
+    public static final String RESUME_ACTION = "com.android.cts.deviceowner.LOCK_TASK_RESUME";
+    public static final String INTENT_ACTION = "com.android.cts.deviceowner.LOCK_TASK_INTENT";
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        handleIntent(intent);
+    }
+
+    @Override
+    protected void onCreate(android.os.Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        sendBroadcast(new Intent(CREATE_ACTION));
+        handleIntent(getIntent());
+    }
+
+    @Override
+    protected void onDestroy() {
+        sendBroadcast(new Intent(DESTROY_ACTION));
+        super.onDestroy();
+    }
+
+    @Override
+    protected void onResume() {
+        sendBroadcast(new Intent(RESUME_ACTION));
+        super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        sendBroadcast(new Intent(PAUSE_ACTION));
+        super.onPause();
+    }
+
+    private void handleIntent(Intent intent) {
+        if (intent.getBooleanExtra(START_LOCK_TASK, false)) {
+            startLockTask();
+        }
+        if (intent.getBooleanExtra(STOP_LOCK_TASK, false)) {
+            stopLockTask();
+        }
+        if (intent.hasExtra(START_ACTIVITY)) {
+            Intent i = intent.getParcelableExtra(START_ACTIVITY);
+            startActivity(i);
+        }
+        if (intent.getBooleanExtra(FINISH, false)) {
+            finish();
+        }
+        sendBroadcast(new Intent(INTENT_ACTION));
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PersistentIntentResolvingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PersistentIntentResolvingTest.java
new file mode 100644
index 0000000..fcef05f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PersistentIntentResolvingTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.deviceowner;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.SystemClock;
+
+public class PersistentIntentResolvingTest extends BaseDeviceOwnerTest {
+    public static final String EXAMPLE_ACTION = "com.android.cts.deviceowner.EXAMPLE_ACTION";
+
+    private boolean mReceivedConfirmationFrom1;
+    private boolean mReceivedConfirmationFrom2;
+    private BroadcastReceiver mReceiver;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ExampleIntentReceivingActivity1.CONFIRM_ACTION);
+        filter.addAction(ExampleIntentReceivingActivity2.CONFIRM_ACTION);
+
+        mReceiver = new ConfirmReceiver();
+        mContext.registerReceiver(mReceiver, filter);
+
+        synchronized(this) {
+            mReceivedConfirmationFrom1 = false;
+            mReceivedConfirmationFrom2 = false;
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager.clearPackagePersistentPreferredActivities(getWho(), PACKAGE_NAME);
+        mContext.unregisterReceiver(mReceiver);
+
+        super.tearDown();
+    }
+
+    public void testNoPersistentPreferredActivityYieldsResolverActivity() {
+        sendExampleIntent();
+        SystemClock.sleep(5000);
+
+        // Default behavior: intent results in resolver activity, since there are two potential
+        // receivers. No intent is received.
+        synchronized(this) {
+            assertFalse(mReceivedConfirmationFrom1);
+            assertFalse(mReceivedConfirmationFrom2);
+        }
+    }
+
+    public void testAddPersistentPreferredActivityYieldsReceptionAtTarget() {
+        addPersistentPreferredActivity();
+        sendExampleIntent();
+        SystemClock.sleep(5000);
+
+        // Persistent preferred activity present: intent should be received by activity 2.
+        synchronized(this) {
+            assertFalse(mReceivedConfirmationFrom1);
+            assertTrue(mReceivedConfirmationFrom2);
+        }
+    }
+
+    public void testAddAndClearPersistentPreferredActivitiesYieldsResolverActivity() {
+        addPersistentPreferredActivity();
+        mDevicePolicyManager.clearPackagePersistentPreferredActivities(getWho(), PACKAGE_NAME);
+
+        sendExampleIntent();
+        SystemClock.sleep(5000);
+
+        // Default behavior: intent results in resolver activity, since there are two potential
+        // receivers. No intent is received.
+        synchronized(this) {
+            assertFalse(mReceivedConfirmationFrom1);
+            assertFalse(mReceivedConfirmationFrom2);
+        }
+    }
+
+    public class ConfirmReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(ExampleIntentReceivingActivity1.CONFIRM_ACTION)) {
+                synchronized (PersistentIntentResolvingTest.this) {
+                    mReceivedConfirmationFrom1 = true;
+                }
+            } else if (intent.getAction().equals(ExampleIntentReceivingActivity2
+                            .CONFIRM_ACTION)) {
+                synchronized (PersistentIntentResolvingTest.this) {
+                    mReceivedConfirmationFrom2 = true;
+                }
+            }
+        }
+    }
+
+    private void sendExampleIntent() {
+        Intent exampleIntent = new Intent(EXAMPLE_ACTION);
+        exampleIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(exampleIntent);
+    }
+
+    private void addPersistentPreferredActivity() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(EXAMPLE_ACTION);
+        filter.addCategory(Intent.CATEGORY_DEFAULT);
+        ComponentName targetComponent = new ComponentName(PACKAGE_NAME,
+                ExampleIntentReceivingActivity2.class.getName());
+        mDevicePolicyManager.addPersistentPreferredActivity(getWho(), filter, targetComponent);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ScreenCaptureDisabledTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ScreenCaptureDisabledTest.java
new file mode 100644
index 0000000..59b9773
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ScreenCaptureDisabledTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.deviceowner;
+
+import android.app.admin.DevicePolicyManager;
+
+/**
+ * Tests for {@link DevicePolicyManager#setScreenCaptureDisabled} and
+ * {@link DevicePolicyManager#getScreenCaptureDisabled} APIs.
+ */
+public class ScreenCaptureDisabledTest extends BaseDeviceOwnerTest {
+
+    public void testSetScreenCaptureDisabled_false() throws Exception {
+        mDevicePolicyManager.setScreenCaptureDisabled(getWho(), false);
+        assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(getWho()));
+    }
+
+    public void testSetScreenCaptureDisabled_true() throws Exception {
+        mDevicePolicyManager.setScreenCaptureDisabled(getWho(), true);
+        assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(getWho()));
+    }
+
+    public void testSetScreenCaptureDisabled_anyAdminTrue() {
+        mDevicePolicyManager.setScreenCaptureDisabled(getWho(), true);
+        assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
+    }
+
+    public void testSetScreenCaptureDisabled_anyAdminFalse() {
+        mDevicePolicyManager.setScreenCaptureDisabled(getWho(), false);
+        assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/Android.mk b/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
similarity index 95%
copy from hostsidetests/devicepolicy/app/ProfileOwner/Android.mk
copy to hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
index baf540b..00dace0 100644
--- a/hostsidetests/devicepolicy/app/ProfileOwner/Android.mk
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
@@ -16,7 +16,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_PACKAGE_NAME := CtsProfileOwnerApp
+LOCAL_PACKAGE_NAME := CtsManagedProfileApp
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
new file mode 100644
index 0000000..2c11b5c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -0,0 +1,64 @@
+<?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.managedprofile">
+
+    <uses-sdk android:minSdkVersion="20"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <receiver
+            android:name="com.android.cts.managedprofile.BaseManagedProfileTest$BasicAdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                       android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+        <activity android:name=".PrimaryUserFilterSetterActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="com.android.cts.managedprofile.ACTION_TEST_SET_FILTERS" />
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".ManagedProfileActivity">
+            <intent-filter>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <action android:name="com.android.cts.managedprofile.ACTION_TEST_MANAGED_ACTIVITY" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".PrimaryUserActivity">
+            <intent-filter>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <action android:name="com.android.cts.managedprofile.ACTION_TEST_PRIMARY_ACTIVITY" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".AllUsersActivity">
+            <intent-filter>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <action android:name="com.android.cts.managedprofile.ACTION_TEST_ALL_ACTIVITY" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.cts.managedprofile"
+                     android:label="Managed Profile CTS Tests"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/res/values/strings.xml b/hostsidetests/devicepolicy/app/ManagedProfile/res/values/strings.xml
similarity index 100%
rename from hostsidetests/devicepolicy/app/ProfileOwner/res/values/strings.xml
rename to hostsidetests/devicepolicy/app/ManagedProfile/res/values/strings.xml
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
similarity index 100%
rename from hostsidetests/devicepolicy/app/ProfileOwner/res/xml/device_admin.xml
rename to hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
similarity index 78%
rename from hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
index e7ccc74..8a2a6ec 100644
--- a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.profileowner;
+package com.android.cts.managedprofile;
 
 import android.app.admin.DeviceAdminReceiver;
 import android.app.admin.DevicePolicyManager;
@@ -27,7 +27,7 @@
  * This class handles making sure that the test is the profile owner and that it has an active admin
  * registered, so that all tests may assume these are done.
  */
-public class BaseProfileOwnerTest extends AndroidTestCase {
+public class BaseManagedProfileTest extends AndroidTestCase {
 
     public static class BasicAdminReceiver extends DeviceAdminReceiver {
     }
@@ -44,9 +44,11 @@
        mDevicePolicyManager = (DevicePolicyManager)
                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
        assertNotNull(mDevicePolicyManager);
-       // TODO: Only check this if we are running as the profile user. Otherwise, maybe check
-       // that there is a profile and that the below holds for it? If we don't want to do these
-       // checks, we could get rid for this class altogether.
+
+       // TODO: Only check the below if we are running as the profile user. If running under the
+       // user owner, can we check that there is a profile and that the below holds for it? If we
+       // don't want to do these checks every time we could get rid of this class altogether and
+       // just have a single test case running under the profile user that do them.
        assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
        assertTrue(mDevicePolicyManager.isProfileOwnerApp(
                ADMIN_RECEIVER_COMPONENT.getPackageName()));
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/ProfileOwnerSetupTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileSetupTest.java
similarity index 84%
rename from hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/ProfileOwnerSetupTest.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileSetupTest.java
index 6fc0eb9..b95194e 100644
--- a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/ProfileOwnerSetupTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileSetupTest.java
@@ -13,14 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.profileowner;
+package com.android.cts.managedprofile;
 
 
-public class ProfileOwnerSetupTest extends BaseProfileOwnerTest {
+public class ManagedProfileSetupTest extends BaseManagedProfileTest {
 
     // This test verifies that the setUp assertions on the base class are working to verify
     // we are the profile owner and have a valid active admin.
-    public void testProfileOwnerSetup() {
+    public void testManagedProfileSetup() {
         // Empty test. We just want the assertions from super.setUp() to be executed.
     }
 
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/WipeDataTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
similarity index 93%
rename from hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/WipeDataTest.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
index 2213d3b..b548c96 100644
--- a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/WipeDataTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.profileowner;
+package com.android.cts.managedprofile;
 
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
@@ -22,7 +22,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 
-import com.android.cts.profileowner.BaseProfileOwnerTest.BasicAdminReceiver;
+import com.android.cts.managedprofile.BaseManagedProfileTest.BasicAdminReceiver;
 
 import org.junit.Ignore;
 
@@ -30,7 +30,7 @@
  * Test wipeData() for use in managed profile. If called from a managed profile, wipeData() should
  * remove the current managed profile. Also, no erasing of external storage should be allowed.
  */
-public class WipeDataTest extends BaseProfileOwnerTest {
+public class WipeDataTest extends BaseManagedProfileTest {
 
     private UserManager mUserManager;
 
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/AllUsersActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/AllUsersActivity.java
new file mode 100644
index 0000000..7260acd
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/AllUsersActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.managedprofile;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Activity that lives in both primary user and its profile.
+ */
+public class AllUsersActivity extends Activity {
+    private static final String TAG = AllUsersActivity.class.getName();
+
+    public static final String ACTION =
+            "com.android.cts.managedprofile.ACTION_TEST_ALL_ACTIVITY";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "Roger that!");
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileActivity.java
new file mode 100644
index 0000000..a91f633
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.managedprofile;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Activity that lives in the managed profile.
+ */
+public class ManagedProfileActivity extends Activity {
+    private static final String TAG = ManagedProfileActivity.class.getName();
+
+    public static final String ACTION =
+            "com.android.cts.managedprofile.ACTION_TEST_MANAGED_ACTIVITY";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "Roger that!");
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileTest.java
new file mode 100644
index 0000000..0e3822b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.managedprofile;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+
+/**
+ * Test for {@link DevicePolicyManager#addCrossProfileIntentFilter} API.
+ *
+ * Note that it expects that there is an activity responding to {@code PrimaryUserActivity.ACTION}
+ * in the primary profile, one to {@code ManagedProfileActivity.ACTION} in the secondary profile,
+ * and one to {@code AllUsersActivity.ACTION} in both profiles.
+ */
+public class ManagedProfileTest extends BaseManagedProfileTest {
+
+    private PackageManager mPackageManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mPackageManager = getContext().getPackageManager();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
+        super.tearDown();
+    }
+
+    public void testClearCrossProfileIntentFilters() {
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(PrimaryUserActivity.ACTION);
+        mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+
+        mDevicePolicyManager.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
+
+        assertTrue(mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).isEmpty());
+    }
+
+    public void testAddCrossProfileIntentFilter_primary() {
+        assertEquals(0, mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(PrimaryUserActivity.ACTION);
+        mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+    }
+
+    public void testAddCrossProfileIntentFilter_all() {
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(AllUsersActivity.ACTION), /* flags = */ 0).size());
+
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(AllUsersActivity.ACTION);
+        mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+
+        assertEquals(2, mPackageManager.queryIntentActivities(
+                new Intent(AllUsersActivity.ACTION), /* flags = */ 0).size());
+    }
+
+    public void testAddCrossProfileIntentFilter_managed() {
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(ManagedProfileActivity.ACTION), /* flags = */ 0).size());
+
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(ManagedProfileActivity.ACTION);
+        mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+
+        // We should still be resolving in the profile
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(ManagedProfileActivity.ACTION), /* flags = */ 0).size());
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserActivity.java
new file mode 100644
index 0000000..f6fa172
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.managedprofile;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Activity for that lives in the primary user.
+ */
+public class PrimaryUserActivity extends Activity {
+    private static final String TAG = PrimaryUserActivity.class.getName();
+
+    public static final String ACTION =
+            "com.android.cts.managedprofile.ACTION_TEST_PRIMARY_ACTIVITY";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "Roger that!");
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserFilterSetterActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserFilterSetterActivity.java
new file mode 100644
index 0000000..c00ced5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserFilterSetterActivity.java
@@ -0,0 +1,43 @@
+package com.android.cts.managedprofile;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.Log;
+
+import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
+
+/**
+ * Class that sets the cross-profile intent filters required to test intent filtering from
+ * the primary profile to the managed one.
+ */
+public class PrimaryUserFilterSetterActivity extends Activity {
+
+    public static final String TAG = PrimaryUserFilterSetterActivity.class.getName();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        PackageManager packageManager = getPackageManager();
+        DevicePolicyManager devicePolicyManager = (DevicePolicyManager)
+                getSystemService(Context.DEVICE_POLICY_SERVICE);
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(PrimaryUserActivity.ACTION);
+        devicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+
+        testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(ManagedProfileActivity.ACTION);
+        devicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+
+        testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(AllUsersActivity.ACTION);
+        devicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+        Log.i(TAG, "Roger that!");
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserTest.java
new file mode 100644
index 0000000..af400a7
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.managedprofile;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.test.AndroidTestCase;
+
+/**
+ * Test for {@link DevicePolicyManager#addCrossProfileIntentFilter} API, for
+ * {@code DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT}.
+ *
+ * Note that it expects that there is an activity responding to {@code PrimaryUserActivity.ACTION}
+ * in the primary profile, one to {@code ManagedProfileActivity.ACTION} in the secondary profile,
+ * and one to {@code AllUsersActivity.ACTION} in both profiles.
+ *
+ * Note that the {code DevicePolicyManager#clearCrossProfileIntentFilters} as well as more complex
+ * test scenarios can be found in {@link ManagedProfileTest}.
+ */
+public class PrimaryUserTest extends AndroidTestCase {
+
+    private PackageManager mPackageManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mPackageManager = getContext().getPackageManager();
+    }
+
+    public void testAddCrossProfileIntentFilter_primary() {
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+    }
+
+    public void testAddCrossProfileIntentFilter_all() {
+        assertEquals(2, mPackageManager.queryIntentActivities(
+                new Intent(AllUsersActivity.ACTION), /* flags = */ 0).size());
+    }
+
+    public void testAddCrossProfileIntentFilter_managed() {
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(ManagedProfileActivity.ACTION), /* flags = */ 0).size());
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml
deleted file mode 100644
index 1aaf99f..0000000
--- a/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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.profileowner">
-
-    <uses-sdk android:minSdkVersion="20"/>
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-        <receiver
-            android:name="com.android.cts.profileowner.BaseProfileOwnerTest$BasicAdminReceiver"
-            android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                       android:resource="@xml/device_admin" />
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
-            </intent-filter>
-        </receiver>
-    </application>
-
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-                     android:targetPackage="com.android.cts.profileowner"
-                     android:label="Profile Owner CTS Tests"/>
-</manifest>
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
similarity index 70%
rename from hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
rename to hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 6d51f9e..abd5a99 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -39,25 +39,20 @@
 import javax.annotation.Nullable;
 
 /**
- * Set of tests for Profile Owner use cases.
+ * Base class for device policy tests. It offers utility methods to run tests, set device or profile
+ * owner, etc.
  */
-public class ProfileOwnerTest extends DeviceTestCase implements IBuildReceiver {
+public class BaseDevicePolicyTest extends DeviceTestCase implements IBuildReceiver {
 
     private static final String RUNNER = "android.test.InstrumentationTestRunner";
 
-    private static final String PROFILE_OWNER_PKG = "com.android.cts.profileowner";
-    private static final String PROFILE_OWNER_APK = "CtsProfileOwnerApp.apk";
-
-    private static final String ADMIN_RECEIVER_TEST_CLASS =
-            PROFILE_OWNER_PKG + ".BaseProfileOwnerTest$BasicAdminReceiver";
-
     private static final String[] REQUIRED_DEVICE_FEATURES = new String[] {
         "android.software.managed_users",
         "android.software.device_admin" };
 
     private CtsBuildHelper mCtsBuild;
-    private int mUserId;
-    private boolean mHasFeature;
+
+    protected boolean mHasFeature;
 
     @Override
     public void setBuild(IBuildInfo buildInfo) {
@@ -68,102 +63,38 @@
     protected void setUp() throws Exception {
         super.setUp();
         assertNotNull(mCtsBuild);  // ensure build has been set before test is run.
-        mHasFeature = hasDeviceFeatures(REQUIRED_DEVICE_FEATURES);
-
-        if (mHasFeature) {
-            mUserId = createUser();
-            installApp(PROFILE_OWNER_APK);
-            setProfileOwner(PROFILE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS);
-        }
+        mHasFeature = getDevice().getApiLevel() >= 21 /* Build.VERSION_CODES.L */
+                && hasDeviceFeatures(REQUIRED_DEVICE_FEATURES);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        if (mHasFeature) {
-            // Remove the user that we created on setUp(), and the app that we installed.
-            String removeUserCommand = "pm remove-user " + mUserId;
-            CLog.logAndDisplay(LogLevel.INFO, "Output for command " + removeUserCommand + ": "
-                    + getDevice().executeShellCommand(removeUserCommand));
-            getDevice().uninstallPackage(PROFILE_OWNER_PKG);
-        }
-
-        super.tearDown();
-    }
-
-    /**
-     *  wipData() test removes the managed profile, so it needs to separated from other tests.
-     */
-    public void testWipeData() throws Exception {
-        if (!mHasFeature) {
-            return;
-        }
-        assertTrue(listUsers().contains(mUserId));
-        assertTrue(runDeviceTestsAsUser(PROFILE_OWNER_PKG, PROFILE_OWNER_PKG + ".WipeDataTest", mUserId));
-        // Note: the managed profile is removed by this test, which will make removeUserCommand in
-        // tearDown() to complain, but that should be OK since its result is not asserted.
-        assertFalse(listUsers().contains(mUserId));
-    }
-
-    public void testProfileOwner() throws Exception {
-        if (!mHasFeature) {
-            return;
-        }
-        String[] testClassNames = {
-                "ProfileOwnerSetupTest"
-        };
-        for (String className : testClassNames) {
-            String testClass = PROFILE_OWNER_PKG + "." + className;
-            assertTrue(runDeviceTestsAsUser(PROFILE_OWNER_PKG, testClass, mUserId));
-        }
-    }
-
-    private boolean hasDeviceFeatures(String[] requiredFeatures)
-            throws DeviceNotAvailableException {
-        // TODO: Move this logic to ITestDevice.
-        String command = "pm list features";
-        String commandOutput = getDevice().executeShellCommand(command);
-
-        // Extract the id of the new user.
-        HashSet<String> availableFeatures = new HashSet<String>();
-        for (String feature: commandOutput.split("\\s+")) {
-            // Each line in the output of the command has the format "feature:{FEATURE_VALUE}".
-            String[] tokens = feature.split(":");
-            assertTrue(tokens.length > 1);
-            assertEquals("feature", tokens[0]);
-            availableFeatures.add(tokens[1]);
-        }
-
-        for (String requiredFeature : requiredFeatures) {
-            if(!availableFeatures.contains(requiredFeature)) {
-                CLog.logAndDisplay(LogLevel.INFO, "Device doesn't have required feature "
-                        + requiredFeature + ". Tests won't run.");
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private void installApp(String fileName)
+    protected void installApp(String fileName)
             throws FileNotFoundException, DeviceNotAvailableException {
         String installResult = getDevice().installPackage(mCtsBuild.getTestApp(fileName), true);
         assertNull(String.format("Failed to install %s, Reason: %s", fileName, installResult),
                 installResult);
     }
 
-    private int createUser() throws DeviceNotAvailableException {
-        String command =
-                "pm create-user --profileOf 0 --managed TestProfile_" + System.currentTimeMillis();
+    /** Initializes the user with the given id. This is required so that apps can run on it. */
+    protected void startUser(int userId) throws DeviceNotAvailableException {
+        String command = "am start-user " + userId;
         String commandOutput = getDevice().executeShellCommand(command);
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
-
-        // Extract the id of the new user.
-        String[] tokens = commandOutput.split("\\s+");
-        assertTrue(tokens.length > 0);
-        assertEquals("Success:", tokens[0]);
-        return Integer.parseInt(tokens[tokens.length-1]);
+        assertTrue(commandOutput.startsWith("Success:"));
     }
 
-    private ArrayList<Integer> listUsers() throws DeviceNotAvailableException {
+    protected int getMaxNumberOfUsersSupported() throws DeviceNotAvailableException {
+        // TODO: move this to ITestDevice once it supports users
+        String command = "pm get-max-users";
+        String commandOutput = getDevice().executeShellCommand(command);
+        try {
+            return Integer.parseInt(commandOutput.substring(commandOutput.lastIndexOf(" ")).trim());
+        } catch (NumberFormatException e) {
+            fail("Failed to parse result: " + commandOutput);
+        }
+        return 0;
+    }
+
+    protected ArrayList<Integer> listUsers() throws DeviceNotAvailableException {
         String command = "pm list users";
         String commandOutput = getDevice().executeShellCommand(command);
 
@@ -183,28 +114,28 @@
         return users;
     }
 
-    private void setProfileOwner(String componentName) throws DeviceNotAvailableException {
-        String command = "dpm set-profile-owner '" + componentName + "' " + mUserId;
-        String commandOutput = getDevice().executeShellCommand(command);
-        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
-        assertTrue(commandOutput.startsWith("Success:"));
+    protected void removeUser(int userId) throws DeviceNotAvailableException  {
+        String removeUserCommand = "pm remove-user " + userId;
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + removeUserCommand + ": "
+                + getDevice().executeShellCommand(removeUserCommand));
     }
 
     /** Returns true if the specified tests passed. Tests are run as user owner. */
-    private boolean runDeviceTests(String pkgName, @Nullable String testClassName)
+    protected boolean runDeviceTests(String pkgName, @Nullable String testClassName)
             throws DeviceNotAvailableException {
         return runDeviceTests(pkgName, testClassName, null /*testMethodName*/, null /*userId*/);
     }
 
     /** Returns true if the specified tests passed. Tests are run as given user. */
-    private boolean runDeviceTestsAsUser(String pkgName, @Nullable String testClassName, int userId)
+    protected boolean runDeviceTestsAsUser(
+            String pkgName, @Nullable String testClassName, int userId)
             throws DeviceNotAvailableException {
         return runDeviceTests(pkgName, testClassName, null /*testMethodName*/, userId);
     }
 
     private boolean runDeviceTests(String pkgName, @Nullable String testClassName,
             @Nullable String testMethodName, @Nullable Integer userId)
-            throws DeviceNotAvailableException {
+                    throws DeviceNotAvailableException {
         TestRunResult runResult = (userId == null)
                 ? doRunTests(pkgName, testClassName, testMethodName)
                 : doRunTestsAsUser(pkgName, testClassName, testMethodName, userId);
@@ -214,8 +145,8 @@
 
     /** Helper method to run tests and return the listener that collected the results. */
     private TestRunResult doRunTests(
-            String pkgName, @Nullable String testClassName, @Nullable String testMethodName)
-            throws DeviceNotAvailableException {
+            String pkgName, String testClassName,
+            String testMethodName) throws DeviceNotAvailableException {
         RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
                 pkgName, RUNNER, getDevice().getIDevice());
         if (testClassName != null && testMethodName != null) {
@@ -263,4 +194,30 @@
             }
         }
     }
+
+    private boolean hasDeviceFeatures(String[] requiredFeatures)
+            throws DeviceNotAvailableException {
+        // TODO: Move this logic to ITestDevice.
+        String command = "pm list features";
+        String commandOutput = getDevice().executeShellCommand(command);
+
+        // Extract the id of the new user.
+        HashSet<String> availableFeatures = new HashSet<String>();
+        for (String feature: commandOutput.split("\\s+")) {
+            // Each line in the output of the command has the format "feature:{FEATURE_VALUE}".
+            String[] tokens = feature.split(":");
+            assertTrue(tokens.length > 1);
+            assertEquals("feature", tokens[0]);
+            availableFeatures.add(tokens[1]);
+        }
+
+        for (String requiredFeature : requiredFeatures) {
+            if(!availableFeatures.contains(requiredFeature)) {
+                CLog.logAndDisplay(LogLevel.INFO, "Device doesn't have required feature "
+                        + requiredFeature + ". Tests won't run.");
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
new file mode 100644
index 0000000..39e2b95
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.devicepolicy;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+/**
+ * Set of tests for Device Owner use cases.
+ */
+public class DeviceOwnerTest extends BaseDevicePolicyTest {
+
+    private static final String DEVICE_OWNER_PKG = "com.android.cts.deviceowner";
+    private static final String DEVICE_OWNER_APK = "CtsDeviceOwnerApp.apk";
+
+    private static final String ADMIN_RECEIVER_TEST_CLASS =
+            DEVICE_OWNER_PKG + ".BaseDeviceOwnerTest$BasicAdminReceiver";
+    private static final String CLEAR_DEVICE_OWNER_TEST_CLASS =
+            DEVICE_OWNER_PKG + ".ClearDeviceOwnerTest";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mHasFeature) {
+            installApp(DEVICE_OWNER_APK);
+            setDeviceOwner(DEVICE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            assertTrue("Failed to remove device owner.",
+                    runDeviceTests(DEVICE_OWNER_PKG, CLEAR_DEVICE_OWNER_TEST_CLASS));
+            getDevice().uninstallPackage(DEVICE_OWNER_PKG);
+        }
+
+        super.tearDown();
+    }
+
+    public void testApplicationRestrictions() throws Exception {
+        executeDeviceOwnerTest("ApplicationRestrictionsTest");
+    }
+
+    public void testCaCertManagement() throws Exception {
+        executeDeviceOwnerTest("CaCertManagementTest");
+    }
+
+    public void testDeviceOwnerSetup() throws Exception {
+        executeDeviceOwnerTest("DeviceOwnerSetupTest");
+    }
+
+    public void testKeyManagement() throws Exception {
+        executeDeviceOwnerTest("KeyManagementTest");
+    }
+
+    public void testLockTask() throws Exception {
+        executeDeviceOwnerTest("LockTaskTest");
+    }
+
+    public void testPersistentIntentResolving() throws Exception {
+        executeDeviceOwnerTest("PersistentIntentResolvingTest");
+    }
+
+    public void testScreenCaptureDisabled() throws Exception {
+        executeDeviceOwnerTest("ScreenCaptureDisabledTest");
+    }
+
+    private void executeDeviceOwnerTest(String testClassName) throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        String testClass = DEVICE_OWNER_PKG + "." + testClassName;
+        assertTrue(runDeviceTests(DEVICE_OWNER_PKG, testClass));
+    }
+
+    private void setDeviceOwner(String componentName) throws DeviceNotAvailableException {
+        String command = "dpm set-device-owner '" + componentName + "'";
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+        assertTrue(commandOutput.startsWith("Success:"));
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
new file mode 100644
index 0000000..85ffb4c
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.devicepolicy;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+/**
+ * Set of tests for Managed Profile use cases.
+ */
+public class ManagedProfileTest extends BaseDevicePolicyTest {
+
+    private static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
+    private static final String MANAGED_PROFILE_APK = "CtsManagedProfileApp.apk";
+
+    private static final String ADMIN_RECEIVER_TEST_CLASS =
+            MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
+
+    private int mUserId;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // We need multi user to be supported in order to create a profile of the user owner.
+        mHasFeature = mHasFeature && (getMaxNumberOfUsersSupported() > 1);
+
+        if (mHasFeature) {
+            mUserId = createManagedProfile();
+            installApp(MANAGED_PROFILE_APK);
+            setProfileOwner(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
+            startUser(mUserId);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            removeUser(mUserId);
+            getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
+        }
+
+        super.tearDown();
+    }
+
+    public void testManagedProfileSetup() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        assertTrue(runDeviceTestsAsUser(
+                MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".ManagedProfileSetupTest", mUserId));
+    }
+
+    /**
+     *  wipeData() test removes the managed profile, so it needs to separated from other tests.
+     */
+    public void testWipeData() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        assertTrue(listUsers().contains(mUserId));
+        assertTrue(runDeviceTestsAsUser(
+                MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".WipeDataTest", mUserId));
+        // Note: the managed profile is removed by this test, which will make removeUserCommand in
+        // tearDown() to complain, but that should be OK since its result is not asserted.
+        assertFalse(listUsers().contains(mUserId));
+    }
+
+// TODO: Reinstate once we find another way of disabling an activity for a user (adb pm disable does
+//   not work at the moment on non-eng builds.
+//    public void testCrossProfileIntentFilters() throws Exception {
+//        if (!mHasFeature) {
+//            return;
+//        }
+//        // Set up activities: ManagedProfileActivity will only be enabled in the managed profile and
+//        // PrimaryUserActivity only in the primary one
+//        disableActivityForUser("ManagedProfileActivity", 0);
+//        disableActivityForUser("PrimaryUserActivity", mUserId);
+//
+//        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
+//                MANAGED_PROFILE_PKG + ".ManagedProfileTest", mUserId));
+//
+//        // Set up filters from primary to managed profile
+//        String command = "am start -W --user " + mUserId  + " " + MANAGED_PROFILE_PKG
+//                + "/.PrimaryUserFilterSetterActivity";
+//        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+//              + getDevice().executeShellCommand(command));
+//        assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".PrimaryUserTest"));
+//        // TODO: Test with startActivity
+//        // TODO: Test with CtsVerifier for disambiguation cases
+//    }
+
+    private void disableActivityForUser(String activityName, int userId)
+            throws DeviceNotAvailableException {
+        String command = "pm disable --user " + userId + " " + MANAGED_PROFILE_PKG + "/."
+                + activityName;
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+                + getDevice().executeShellCommand(command));
+    }
+
+    private int createManagedProfile() throws DeviceNotAvailableException {
+        String command =
+                "pm create-user --profileOf 0 --managed TestProfile_" + System.currentTimeMillis();
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+
+        // Extract the id of the new user.
+        String[] tokens = commandOutput.split("\\s+");
+        assertTrue(tokens.length > 0);
+        assertEquals("Success:", tokens[0]);
+        return Integer.parseInt(tokens[tokens.length-1]);
+    }
+
+    private void setProfileOwner(String componentName, int userId)
+            throws DeviceNotAvailableException {
+        String command = "dpm set-profile-owner '" + componentName + "' " + userId;
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+        assertTrue(commandOutput.startsWith("Success:"));
+    }
+}
diff --git a/suite/cts/hostTests/uihost/src/com/android/cts/uihost/TaskSwitchingTest.java b/suite/cts/hostTests/uihost/src/com/android/cts/uihost/TaskSwitchingTest.java
index 100f448..894b824 100644
--- a/suite/cts/hostTests/uihost/src/com/android/cts/uihost/TaskSwitchingTest.java
+++ b/suite/cts/hostTests/uihost/src/com/android/cts/uihost/TaskSwitchingTest.java
@@ -115,7 +115,7 @@
         @Override
         public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
             // necessary as testMetrics passed from CollectingTestListerner is empty
-            mCtsReport = testMetrics.get("CTS_TEST_REPORT");
+            mCtsReport = testMetrics.get("CTS_TEST_RESULT");
             super.testEnded(test, testMetrics);
         }
     }
diff --git a/tests/core/ctscore.mk b/tests/core/ctscore.mk
index 95f4634..fea0b07 100644
--- a/tests/core/ctscore.mk
+++ b/tests/core/ctscore.mk
@@ -25,4 +25,8 @@
 
 LOCAL_JNI_SHARED_LIBRARIES := libjavacoretests
 
+# Include both the 32 and 64 bit versions of libjavacoretests,
+# where applicable.
+LOCAL_MULTILIB := both
+
 include $(BUILD_PACKAGE)
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index b7f7078..5ce84f7 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -40,9 +40,12 @@
     "android.webgl.cts.WebGLTest#test_conformance_textures_tex_image_and_sub_image_2d_with_video_rgba4444_html",
     "android.webgl.cts.WebGLTest#test_conformance_textures_tex_image_and_sub_image_2d_with_video_rgba5551_html",
     "android.webgl.cts.WebGLTest#test_conformance_textures_texture_npot_html",
-    "android.webgl.cts.WebGLTest#test_conformance_textures_texture_npot_video_html"
+    "android.webgl.cts.WebGLTest#test_conformance_textures_texture_npot_video_html",
+    "android.webgl.cts.WebGLTest#test_conformance_glsl_misc_empty_main_vert_html",
+    "android.webgl.cts.WebGLTest#test_conformance_glsl_misc_gl_position_unset_vert_html",
+    "android.webgl.cts.WebGLTest#test_conformance_misc_webgl_specific_html"
   ],
-  bug: 14639928
+  bug: 17748398
 },
 {
   description: "permissions for the API previously used in the test has changed, making it impossible to pass",
@@ -56,13 +59,6 @@
   bug: 17394321
 },
 {
-  description: "this test deadlocks on some devices, freezing CTS runs, marking known failure until resolved",
-  names: [
-    "android.hardware.camera2.cts.RobustnessTest#testMandatoryOutputCombinations"
-  ],
-  bug: 17511208
-},
-{
   description: "these tests require a good test scene, so they fail if run in random conditions",
   names: [
     "android.hardware.camera2.cts.AllocationTest#testBlackWhite",
diff --git a/tests/tests/content/AndroidManifest.xml b/tests/tests/content/AndroidManifest.xml
index b3de29f..a5caba8 100644
--- a/tests/tests/content/AndroidManifest.xml
+++ b/tests/tests/content/AndroidManifest.xml
@@ -177,6 +177,16 @@
 
         <activity android:name="android.content.cts.ClipboardManagerListenerActivity"/>
 
+        <activity android:name="com.android.cts.content.ImageCaptureActivity"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.media.action.IMAGE_CAPTURE" />
+                <action android:name="android.media.action.IMAGE_CAPTURE_SECURE" />
+                <action android:name="android.media.action.VIDEO_CAPTURE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
index e7b6ed7..62fc83a 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
@@ -641,7 +641,8 @@
     }
 
     public void testCheckCallingOrSelfPermission() {
-        int retValue = mContextWrapper.checkCallingOrSelfPermission("android.permission.GET_TASKS");
+        int retValue = mContextWrapper.checkCallingOrSelfPermission(
+                "android.permission.SET_WALLPAPER");
         assertEquals(PackageManager.PERMISSION_GRANTED, retValue);
     }
 
@@ -705,7 +706,7 @@
         }
 
         // Test with invalid uid and included granted permission.
-        returnValue = mContextWrapper.checkPermission("android.permission.GET_TASKS", 1, -11);
+        returnValue = mContextWrapper.checkPermission("android.permission.SET_WALLPAPER", 1, -11);
         assertEquals(PackageManager.PERMISSION_DENIED, returnValue);
     }
 
diff --git a/tests/tests/content/src/android/content/cts/ImageCaptureActivity.java b/tests/tests/content/src/android/content/cts/ImageCaptureActivity.java
new file mode 100644
index 0000000..71bf250
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/ImageCaptureActivity.java
@@ -0,0 +1,103 @@
+/*
+ * 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.content;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.ClipData.Item;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+public class ImageCaptureActivity extends Activity {
+    public static final String ACTION_FILE_READY = "com.android.cts.content.action.file_ready";
+    private static final String TAG = ImageCaptureUriExtraToClipDataTest.TAG;
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = getIntent();
+
+        // Check action.
+        String action = intent.getAction();
+        if ((MediaStore.ACTION_IMAGE_CAPTURE.equals(action)
+                        || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(action)
+                        || MediaStore.ACTION_VIDEO_CAPTURE.equals(action))) {
+            writeToClipDataUri(intent);
+        }
+
+        finish();
+    }
+
+    // Sends ACTION_FILE_READY intent when write to clipdata uri is succesful.
+    private void writeToClipDataUri(Intent intent) {
+        if ((intent.getFlags() & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
+
+            // Note: since this activity is in the same package as the test we can write to the file
+            // regardless of this permission, but in general this permission is required.
+            Log.e(TAG, "Intent.FLAG_GRANT_WRITE_URI_PERMISSION was not granted.");
+            return;
+        }
+
+        File file = getFileFromIntent(intent);
+        if (file == null) {
+            Log.e(TAG, "Could not get file from clipdata.");
+            return;
+        }
+        try {
+            FileWriter writer = new FileWriter(file);
+            writer.write(ImageCaptureUriExtraToClipDataTest.TEST_INPUT);
+            writer.flush();
+            writer.close();
+        } catch (IOException e) {
+            Log.e(TAG, "File IO failure while writing.");
+            return;
+        }
+        Intent fileReady = new Intent(ACTION_FILE_READY);
+        sendBroadcast(fileReady);
+    }
+
+    private File getFileFromIntent(Intent intent) {
+        ClipData clipData = intent.getClipData();
+        if (clipData == null) {
+            Log.e(TAG, "ClipData missing.");
+            return null;
+        }
+        if (clipData.getItemCount() == 0) {
+            Log.e(TAG, "Uri missing in ClipData.");
+            return null;
+        }
+
+        Uri filePath = clipData.getItemAt(0).getUri();
+        if (filePath == null) {
+            Log.e(TAG, "Uri missing in ClipData.");
+            return null;
+        }
+
+        try {
+            return new File(filePath.getPath());
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Cannot get file at Uri.");
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java b/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java
new file mode 100644
index 0000000..bb2a43d
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.content;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.test.AndroidTestCase;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+public class ImageCaptureUriExtraToClipDataTest extends AndroidTestCase {
+    private static final String FILE_NAME = "testFile.txt";
+    private File mTestFile;
+    private final Semaphore mFileReadySemaphore = new Semaphore(0);
+
+    public static final String TEST_INPUT = "testString";
+    public static final String TAG = "ImageCaptureUriExtraToClipDataTest";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertEquals(0, mFileReadySemaphore.availablePermits());
+
+        BroadcastReceiver mReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    mFileReadySemaphore.release();
+                }
+            };
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ImageCaptureActivity.ACTION_FILE_READY);
+        getContext().registerReceiver(mReceiver, filter);
+
+        mTestFile = new File(getContext().getFilesDir() + File.separator + FILE_NAME);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mTestFile.exists()) {
+            assertTrue(mTestFile.delete());
+        }
+        super.tearDown();
+    }
+
+
+    public void testUriExtraOutputMigratedToClipData_imageCaptureIntent() {
+        startActivityWithAction(MediaStore.ACTION_IMAGE_CAPTURE);
+        waitForFileReady();
+        testFileContents();
+    }
+
+    public void testUriExtraOutputMigratedToClipData_imageCaptureSecureIntent() {
+        startActivityWithAction(MediaStore.ACTION_IMAGE_CAPTURE_SECURE);
+        waitForFileReady();
+        testFileContents();
+    }
+
+    public void testUriExtraOutputMigratedToClipData_videoCaptureIntent() {
+        startActivityWithAction(MediaStore.ACTION_VIDEO_CAPTURE);
+        waitForFileReady();
+        testFileContents();
+    }
+
+    private void startActivityWithAction(String action) {
+        Intent intent = new Intent(action);
+        intent.setComponent(new ComponentName("com.android.cts.content",
+                        "com.android.cts.content.ImageCaptureActivity"));
+        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTestFile));
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getContext().startActivity(intent);
+    }
+
+    private void waitForFileReady() {
+        try {
+            assertTrue(mFileReadySemaphore.tryAcquire(5, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            fail(e.toString());
+        }
+    }
+
+    private void testFileContents() {
+        char[] buffer = new char[TEST_INPUT.length()];
+        try {
+            FileReader reader = new FileReader(mTestFile);
+            reader.read(buffer);
+            reader.close();
+        } catch (IOException e) {
+            // Problem
+            fail(e.toString());
+        }
+        String fileContents = new String(buffer);
+        assertEquals(TEST_INPUT, fileContents);
+    }
+}
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 41b03b8..eef99a2 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -76,19 +76,19 @@
     // Only test the preview size that is no larger than 1080p.
     public static final Size PREVIEW_SIZE_BOUND = SIZE_BOUND_1080P;
     // Default timeouts for reaching various states
-    public static final int CAMERA_OPEN_TIMEOUT_MS = 2000;
-    public static final int CAMERA_CLOSE_TIMEOUT_MS = 2000;
-    public static final int CAMERA_IDLE_TIMEOUT_MS = 2000;
+    public static final int CAMERA_OPEN_TIMEOUT_MS = 3000;
+    public static final int CAMERA_CLOSE_TIMEOUT_MS = 3000;
+    public static final int CAMERA_IDLE_TIMEOUT_MS = 3000;
     public static final int CAMERA_ACTIVE_TIMEOUT_MS = 1000;
     public static final int CAMERA_BUSY_TIMEOUT_MS = 1000;
     public static final int CAMERA_UNCONFIGURED_TIMEOUT_MS = 1000;
-    public static final int CAMERA_CONFIGURE_TIMEOUT_MS = 2000;
+    public static final int CAMERA_CONFIGURE_TIMEOUT_MS = 3000;
     public static final int CAPTURE_RESULT_TIMEOUT_MS = 3000;
     public static final int CAPTURE_IMAGE_TIMEOUT_MS = 3000;
 
-    public static final int SESSION_CONFIGURE_TIMEOUT_MS = 2000;
-    public static final int SESSION_CLOSE_TIMEOUT_MS = 2000;
-    public static final int SESSION_READY_TIMEOUT_MS = 2000;
+    public static final int SESSION_CONFIGURE_TIMEOUT_MS = 3000;
+    public static final int SESSION_CLOSE_TIMEOUT_MS = 3000;
+    public static final int SESSION_READY_TIMEOUT_MS = 3000;
     public static final int SESSION_ACTIVE_TIMEOUT_MS = 1000;
 
     public static final int MAX_READER_IMAGES = 5;
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 006b32c..00dd24d 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -282,6 +282,11 @@
             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.
@@ -340,6 +345,11 @@
             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/PerformanceTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java
index d4a0e73..8b8f2f6 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -195,6 +195,11 @@
             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/StillCaptureTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
index 8dd35f6..2f5409d 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -140,6 +140,11 @@
                 Log.i(TAG, "Testing JPEG exif for Camera " + mCameraIds[i]);
                 openDevice(mCameraIds[i]);
 
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    Log.i(TAG, "Skipping test on legacy devices");
+                    continue;
+                }
+
                 jpegExifTestByCamera();
             } finally {
                 closeDevice();
@@ -263,6 +268,11 @@
                 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();
@@ -303,6 +313,11 @@
                 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;
@@ -353,6 +368,11 @@
                 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;
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 01da4c8..b3d4cf9 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -74,6 +74,11 @@
                 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/testcases/Camera2MultiViewTestCase.java b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
index 4d16e7d..03e9647 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
@@ -63,8 +63,6 @@
 
 
     private static final long SHORT_SLEEP_WAIT_TIME_MS = 100;
-    // Default timeouts for reaching various camera states
-    private static final int CAMERA_CLOSE_TIMEOUT_MS = 2000;
 
     protected TextureView[] mTextureView = new TextureView[2];
     protected String[] mCameraIds;
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java b/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java
index 6075add..e620955 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java
@@ -16,19 +16,18 @@
 
 package android.hardware.cts.helpers;
 
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
 import android.hardware.cts.helpers.sensoroperations.SensorOperationTest;
+import android.hardware.cts.helpers.sensorverification.EventGapVerificationTest;
 import android.hardware.cts.helpers.sensorverification.EventOrderingVerificationTest;
 import android.hardware.cts.helpers.sensorverification.FrequencyVerificationTest;
 import android.hardware.cts.helpers.sensorverification.JitterVerificationTest;
 import android.hardware.cts.helpers.sensorverification.MagnitudeVerificationTest;
 import android.hardware.cts.helpers.sensorverification.MeanVerificationTest;
-import android.hardware.cts.helpers.sensorverification.EventGapVerificationTest;
-import android.hardware.cts.helpers.sensorverification.SigNumVerificationTest;
 import android.hardware.cts.helpers.sensorverification.StandardDeviationVerificationTest;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
 /**
  * Unit test suite for the CTS sensor framework.
  */
@@ -48,7 +47,6 @@
         addTestSuite(MagnitudeVerificationTest.class);
         addTestSuite(MeanVerificationTest.class);
         addTestSuite(EventGapVerificationTest.class);
-        addTestSuite(SigNumVerificationTest.class);
         addTestSuite(StandardDeviationVerificationTest.class);
 
         // sensorOperations
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 c45d640..8f33f92 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
@@ -197,6 +197,19 @@
     }
 
     /**
+     * @return The number of axes in the coordinate system of the sensor under test.
+     */
+    public int getSensorAxesCount() {
+        switch (mSensor.getType()) {
+            case Sensor.TYPE_GYROSCOPE:
+                return 3;
+            default:
+                throw new IllegalStateException("Axes count needs to be defined for sensor type: "
+                        + mSensor.getStringType());
+        }
+    }
+
+    /**
      * Get the default sensor for a given type.
      *
      * @deprecated Used for historical reasons, sensor tests must be written around Sensor objects,
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 a62107b..d72a2ce 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
@@ -58,7 +58,7 @@
     private TestSensorEventListener mTestSensorEventListener;
 
     /**
-     * @Deprecated Use {@link #TestSensorManager(TestSensorEnvironment)} instead.
+     * @deprecated Use {@link #TestSensorManager(TestSensorEnvironment)} instead.
      */
     @Deprecated
     public TestSensorManager(
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SensorOperationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SensorOperationTest.java
index 7148454..38ad498 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SensorOperationTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SensorOperationTest.java
@@ -16,10 +16,10 @@
 
 package android.hardware.cts.helpers.sensoroperations;
 
-import android.hardware.cts.helpers.SensorStats;
-
 import junit.framework.TestCase;
 
+import android.hardware.cts.helpers.SensorStats;
+
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
@@ -29,7 +29,7 @@
  * {@link SequentialSensorOperation}.
  */
 public class SensorOperationTest extends TestCase {
-    private static final int THRESHOLD_MS = 50;
+    private static final long TEST_DURATION_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(5);
 
     /**
      * Test that the {@link FakeSensorOperation} functions correctly. Other tests in this class
@@ -44,7 +44,7 @@
         long start = System.currentTimeMillis();
         op.execute();
         long duration = System.currentTimeMillis() - start;
-        assertTrue(Math.abs(opDurationMs - duration) < THRESHOLD_MS);
+        assertTrue(Math.abs(opDurationMs - duration) < TEST_DURATION_THRESHOLD_MS);
         assertTrue(op.getStats().flatten().containsKey("executed"));
 
         op = new FakeSensorOperation(true, 0, TimeUnit.MILLISECONDS);
@@ -67,10 +67,11 @@
         FakeSensorOperation subOp = new FakeSensorOperation(subOpDurationMs, TimeUnit.MILLISECONDS);
         ISensorOperation op = new DelaySensorOperation(subOp, opDurationMs, TimeUnit.MILLISECONDS);
 
-        long start = System.currentTimeMillis();
+        long startMs = System.currentTimeMillis();
         op.execute();
-        long duration = System.currentTimeMillis() - start;
-        assertTrue(Math.abs(opDurationMs + subOpDurationMs - duration) < THRESHOLD_MS);
+        long dirationMs = System.currentTimeMillis() - startMs;
+        long durationDeltaMs = Math.abs(opDurationMs + subOpDurationMs - dirationMs);
+        assertTrue(durationDeltaMs < TEST_DURATION_THRESHOLD_MS);
     }
 
     /**
@@ -92,8 +93,18 @@
 
         long start = System.currentTimeMillis();
         op.execute();
-        long duration = System.currentTimeMillis() - start;
-        assertTrue(Math.abs(subOpDurationMs - duration) < THRESHOLD_MS);
+        long durationMs = System.currentTimeMillis() - start;
+        long durationDeltaMs = Math.abs(subOpDurationMs - durationMs);
+        String message = String.format(
+                "Expected duration=%sms, observed=%sms, delta=%sms, thresold=%sms",
+                subOpDurationMs,
+                durationMs,
+                durationDeltaMs,
+                TEST_DURATION_THRESHOLD_MS);
+        // starting threads might have an impact in the order of 100s ms, depending on the load of
+        // the system, so we relax the benchmark part of the test, and we just expect all operations
+        // to complete
+        assertTrue(message, durationDeltaMs < TEST_DURATION_THRESHOLD_MS);
 
         statsKeys = op.getStats().flatten().keySet();
         assertEquals(subOpCount, statsKeys.size());
@@ -151,9 +162,9 @@
     public void testParallelSensorOperation_timeout() {
         final int subOpCount = 100;
 
-        ParallelSensorOperation op = new ParallelSensorOperation(100, TimeUnit.MILLISECONDS);
+        ParallelSensorOperation op = new ParallelSensorOperation(1, TimeUnit.SECONDS);
         for (int i = 0; i < subOpCount; i++) {
-            // Trigger timeouts in the 5th, 55th operations (5 seconds vs 0 seconds)
+            // Trigger timeouts in the 5th, 55th operations (5 seconds vs 1 seconds)
             ISensorOperation subOp = new FakeSensorOperation(i % 50 == 5 ? 5 : 0, TimeUnit.SECONDS);
             op.add(subOp);
         }
@@ -196,7 +207,7 @@
         long start = System.currentTimeMillis();
         op.execute();
         long duration = System.currentTimeMillis() - start;
-        assertTrue(Math.abs(subOpDurationMs * iterations - duration) < THRESHOLD_MS);
+        assertTrue(Math.abs(subOpDurationMs * iterations - duration) < TEST_DURATION_THRESHOLD_MS);
 
         statsKeys = op.getStats().flatten().keySet();
         assertEquals(iterations, statsKeys.size());
@@ -285,7 +296,7 @@
         long start = System.currentTimeMillis();
         op.execute();
         long duration = System.currentTimeMillis() - start;
-        assertTrue(Math.abs(subOpDurationMs * subOpCount - duration) < THRESHOLD_MS);
+        assertTrue(Math.abs(subOpDurationMs * subOpCount - duration) < TEST_DURATION_THRESHOLD_MS);
 
         statsKeys = op.getStats().flatten().keySet();
         assertEquals(subOpCount, statsKeys.size());
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/GyroscopeIntegrationVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/GyroscopeIntegrationVerification.java
new file mode 100644
index 0000000..b46c2dc
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/GyroscopeIntegrationVerification.java
@@ -0,0 +1,115 @@
+/*
+ * 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.Sensor;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorVerification} that verifies the measurements of the sensors:
+ * - {@link Sensor#TYPE_GYROSCOPE}
+ * - {@link Sensor#TYPE_GYROSCOPE_UNCALIBRATED}
+ *
+ * It uses a routine to integrate gyroscope's data, and that they correspond to expected angular
+ * positions.
+ */
+public class GyroscopeIntegrationVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "gyroscope_integration_passed";
+
+    private static final long ONE_SECOND_AS_NANOS = TimeUnit.SECONDS.toNanos(1);
+
+    private final double[] mIntermediatesDeg;
+    private final int[] mExpectationsDeg;
+    private final float[] mThresholdsDeg;
+
+    private volatile Long mLastTimestampNs;
+
+    public GyroscopeIntegrationVerification(int[] expectationsDeg, float[] thresholdsDeg) {
+        mIntermediatesDeg = new double[expectationsDeg.length];
+        mExpectationsDeg = expectationsDeg;
+        mThresholdsDeg = thresholdsDeg;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void verify(TestSensorEnvironment environment, SensorStats stats) {
+        int sensorType = environment.getSensor().getType();
+        if (sensorType != Sensor.TYPE_GYROSCOPE
+                && sensorType != Sensor.TYPE_GYROSCOPE_UNCALIBRATED) {
+            // the verification does not apply, so no-op
+            stats.addValue(PASSED_KEY, true);
+        }
+
+        boolean success = true;
+        int gyroscopeAxes = environment.getSensorAxesCount();
+        StringBuilder builder = new StringBuilder("Gyroscope Integration | failures:");
+        for (int i = 0; i < gyroscopeAxes; ++i) {
+            double integrationDeg = Math.toDegrees(mIntermediatesDeg[i]);
+            double integrationDelta = Math.abs(integrationDeg - mExpectationsDeg[i]);
+            if (integrationDelta > mThresholdsDeg[i]) {
+                success = false;
+                String message = String.format(
+                        "\naxis=%s, expected=%sdeg, observed=%sdeg, delta=%sdeg, threshold=%sdeg",
+                        i,
+                        mExpectationsDeg[i],
+                        integrationDeg,
+                        integrationDelta,
+                        mThresholdsDeg[i]);
+                builder.append(message);
+            }
+        }
+
+        stats.addValue(PASSED_KEY, success);
+        Assert.assertTrue(builder.toString(), success);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GyroscopeIntegrationVerification clone() {
+        return new GyroscopeIntegrationVerification(mExpectationsDeg, mThresholdsDeg);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        float[] eventValues = event.values.clone();
+        long eventTimestampNs = event.timestamp;
+        if (mLastTimestampNs == null) {
+            mLastTimestampNs = eventTimestampNs;
+            return;
+        }
+
+        int intermediatesLength = mIntermediatesDeg.length;
+        long timestampDeltaNs = eventTimestampNs - mLastTimestampNs;
+        for (int i = 0; i < intermediatesLength; ++i) {
+            mIntermediatesDeg[i] += eventValues[i] * timestampDeltaNs / ONE_SECOND_AS_NANOS;
+        }
+        mLastTimestampNs = eventTimestampNs;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerification.java
deleted file mode 100644
index 94a4c96..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerification.java
+++ /dev/null
@@ -1,132 +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.sensorverification;
-
-import junit.framework.Assert;
-
-import android.hardware.cts.helpers.SensorStats;
-import android.hardware.cts.helpers.TestSensorEnvironment;
-
-/**
- * A {@link ISensorVerification} which verifies that the sign of each of the sensor values is
- * correct.
- * <p>
- * If the value of the measurement is in [-threshold, threshold], the sign is considered 0. If
- * it is less than -threshold, it is considered -1. If it is greater than threshold, it is
- * considered 1.
- * </p>
- */
-public class SigNumVerification extends AbstractMeanVerification {
-    public static final String PASSED_KEY = "sig_num_passed";
-
-    private final int[] mExpected;
-    private final float[] mThreshold;
-
-    /**
-     * Construct a {@link SigNumVerification}
-     *
-     * @param expected the expected values
-     * @param threshold the threshold that needs to be crossed to consider a measurement nonzero
-     * @throws IllegalStateException if the expected values are not 0, -1, or 1.
-     */
-    public SigNumVerification(int[] expected, float[] threshold) {
-        for (int i = 0; i < expected.length; i++) {
-            if (!(expected[i] == -1 || expected[i] == 0 || expected[i] == 1)) {
-                throw new IllegalArgumentException("Expected value must be -1, 0, or 1");
-            }
-        }
-
-        mExpected = expected;
-        mThreshold = threshold;
-    }
-
-    /**
-     * Verify that the sign of each of the sensor values is correct. Add {@value #PASSED_KEY} and
-     * {@value SensorStats#MEAN_KEY} keys to {@link SensorStats}.
-     *
-     * @throws AssertionError if the verification failed.
-     */
-    @Override
-    public void verify(TestSensorEnvironment environment, SensorStats stats) {
-        verify(stats);
-    }
-
-    /**
-     * Visible for unit tests only.
-     */
-    void verify(SensorStats stats) {
-        if (getCount() < 1) {
-            stats.addValue(PASSED_KEY, true);
-            return;
-        }
-
-        float[] means = getMeans();
-
-        boolean failed = false;
-        StringBuilder meanSb = new StringBuilder();
-        StringBuilder expectedSb = new StringBuilder();
-
-        if (means.length > 1) {
-            meanSb.append("(");
-            expectedSb.append("(");
-        }
-        for (int i = 0; i < means.length; i++) {
-            meanSb.append(String.format("%.2f", means[i]));
-            if (i != means.length - 1) meanSb.append(", ");
-
-            if (mExpected[i] == 0) {
-                if (Math.abs(means[i]) > mThreshold[i]) {
-                    failed = true;
-                }
-                expectedSb.append(String.format("[%.2f, %.2f]", -mThreshold[i], mThreshold[i]));
-            } else {
-                if (mExpected[i] > 0) {
-                    if (means[i] <= mThreshold[i]) {
-                        failed = true;
-                    }
-                    expectedSb.append(String.format("(%.2f, inf)", mThreshold[i]));
-                } else {
-                    if (means[i] >= -1 * mThreshold[i]) {
-                        failed = true;
-                    }
-                    expectedSb.append(String.format("(-inf, %.2f)", -1 * mThreshold[i]));
-                }
-            }
-            if (i != means.length - 1) expectedSb.append(", ");
-        }
-        if (means.length > 1) {
-            meanSb.append(")");
-            expectedSb.append(")");
-        }
-
-        stats.addValue(PASSED_KEY, !failed);
-        stats.addValue(SensorStats.MEAN_KEY, means);
-
-        if (failed) {
-            Assert.fail(String.format("Signum out of range: mean=%s (expected %s)",
-                    meanSb.toString(), expectedSb.toString()));
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public SigNumVerification clone() {
-        return new SigNumVerification(mExpected, mThreshold);
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerificationTest.java
deleted file mode 100644
index c8ce87e..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerificationTest.java
+++ /dev/null
@@ -1,83 +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.sensorverification;
-
-import junit.framework.TestCase;
-
-import android.hardware.cts.helpers.SensorStats;
-import android.hardware.cts.helpers.TestSensorEnvironment;
-import android.hardware.cts.helpers.TestSensorEvent;
-
-/**
- * Tests for {@link SigNumVerification}.
- */
-public class SigNumVerificationTest extends TestCase {
-
-    /**
-     * Test {@link SigNumVerification#verify(TestSensorEnvironment, SensorStats)}.
-     */
-    public void testVerify() {
-        float[][] values = {{1.0f, 0.2f, 0.0f, -0.2f, -1.0f}};
-
-        int[] expected = {1, 1, 0, -1, -1};
-        float[] threshold = {0.1f, 0.1f, 0.1f, 0.1f, 0.1f};
-        runVerification(true, expected, threshold, values);
-
-        expected = new int[]{1, 0, 0, 0, -1};
-        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
-        runVerification(true, expected, threshold, values);
-
-        expected = new int[]{0, 1, 0, -1, 0};
-        threshold = new float[]{1.5f, 0.1f, 0.1f, 0.1f, 1.5f};
-        runVerification(true, expected, threshold, values);
-
-        expected = new int[]{1, 0, 0, 0, 1};
-        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
-        runVerification(false, expected, threshold, values);
-
-        expected = new int[]{-1, 0, 0, 0, -1};
-        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
-        runVerification(false, expected, threshold, values);
-    }
-
-    private SigNumVerification getVerification(int[] expected, float[] threshold,
-            float[] ... values) {
-        SigNumVerification verification = new SigNumVerification(expected, threshold);
-        for (float[] value : values) {
-            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
-        }
-        return verification;
-    }
-
-    private void runVerification(boolean passed, int[] expected, float[] threshold,
-            float[][] values) {
-        SensorStats stats = new SensorStats();
-        SigNumVerification verification = getVerification(expected, threshold, values);
-        if (passed) {
-            verification.verify(stats);
-        } else {
-            try {
-                verification.verify(stats);
-                fail("Expected an AssertionError");
-            } catch (AssertionError e) {
-                // Expected;
-            }
-        }
-        assertEquals(passed, stats.getValue(SigNumVerification.PASSED_KEY));
-        assertNotNull(stats.getValue(SensorStats.MEAN_KEY));
-    }
-}
diff --git a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
index 6bf5c62..f330e8a 100644
--- a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
+++ b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
@@ -36,6 +36,7 @@
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.test.InstrumentationTestCase;
+import android.test.UiThreadTest;
 
 import java.util.List;
 import java.lang.Thread;
@@ -223,6 +224,7 @@
         return false;
     }
 
+    @UiThreadTest
     public void testGpsStatusListener() {
         try {
             mManager.addGpsStatusListener(new MockGpsStatusListener());
diff --git a/tests/tests/os/src/android/os/cts/ReadElf.java b/tests/tests/os/src/android/os/cts/ReadElf.java
index 2f64e03..4a20031 100644
--- a/tests/tests/os/src/android/os/cts/ReadElf.java
+++ b/tests/tests/os/src/android/os/cts/ReadElf.java
@@ -19,458 +19,476 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.RandomAccessFile;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
 /**
- * A poor man's implementation of the readelf command. This program is
- * designed to parse ELF (Executable and Linkable Format) files.
+ * A poor man's implementation of the readelf command. This program is designed
+ * to parse ELF (Executable and Linkable Format) files.
  */
 public class ReadElf implements AutoCloseable {
-  /** The magic values for the ELF identification. */
-  private static final byte[] ELFMAG = { (byte) 0x7F, (byte) 'E', (byte) 'L', (byte) 'F', };
+    /** The magic values for the ELF identification. */
+    private static final byte[] ELFMAG = {
+            (byte) 0x7F, (byte) 'E', (byte) 'L', (byte) 'F', };
 
-  private static final int EI_NIDENT = 16;
+    private static final int EI_NIDENT = 16;
 
-  private static final int EI_CLASS = 4;
-  private static final int EI_DATA = 5;
+    private static final int EI_CLASS = 4;
+    private static final int EI_DATA = 5;
 
-  private static final int EM_386 = 3;
-  private static final int EM_MIPS = 8;
-  private static final int EM_ARM = 40;
-  private static final int EM_X86_64 = 62;
-  // http://en.wikipedia.org/wiki/Qualcomm_Hexagon
-  private static final int EM_QDSP6 = 164;
-  private static final int EM_AARCH64 = 183;
+    private static final int EM_386 = 3;
+    private static final int EM_MIPS = 8;
+    private static final int EM_ARM = 40;
+    private static final int EM_X86_64 = 62;
+    // http://en.wikipedia.org/wiki/Qualcomm_Hexagon
+    private static final int EM_QDSP6 = 164;
+    private static final int EM_AARCH64 = 183;
 
-  private static final int ELFCLASS32 = 1;
-  private static final int ELFCLASS64 = 2;
+    private static final int ELFCLASS32 = 1;
+    private static final int ELFCLASS64 = 2;
 
-  private static final int ELFDATA2LSB = 1;
-  private static final int ELFDATA2MSB = 2;
+    private static final int ELFDATA2LSB = 1;
+    private static final int ELFDATA2MSB = 2;
 
-  private static final int EV_CURRENT = 1;
+    private static final int EV_CURRENT = 1;
 
-  private static final long PT_LOAD = 1;
+    private static final long PT_LOAD = 1;
 
-  private static final int SHT_SYMTAB = 2;
-  private static final int SHT_STRTAB = 3;
-  private static final int SHT_DYNAMIC = 6;
-  private static final int SHT_DYNSYM = 11;
+    private static final int SHT_SYMTAB = 2;
+    private static final int SHT_STRTAB = 3;
+    private static final int SHT_DYNAMIC = 6;
+    private static final int SHT_DYNSYM = 11;
 
-  public static class Symbol {
-    public static final int STB_LOCAL = 0;
-    public static final int STB_GLOBAL = 1;
-    public static final int STB_WEAK = 2;
-    public static final int STB_LOPROC = 13;
-    public static final int STB_HIPROC = 15;
+    public static class Symbol {
+        public static final int STB_LOCAL = 0;
+        public static final int STB_GLOBAL = 1;
+        public static final int STB_WEAK = 2;
+        public static final int STB_LOPROC = 13;
+        public static final int STB_HIPROC = 15;
 
-    public static final int STT_NOTYPE = 0;
-    public static final int STT_OBJECT = 1;
-    public static final int STT_FUNC = 2;
-    public static final int STT_SECTION = 3;
-    public static final int STT_FILE = 4;
-    public static final int STT_COMMON = 5;
-    public static final int STT_TLS = 6;
+        public static final int STT_NOTYPE = 0;
+        public static final int STT_OBJECT = 1;
+        public static final int STT_FUNC = 2;
+        public static final int STT_SECTION = 3;
+        public static final int STT_FILE = 4;
+        public static final int STT_COMMON = 5;
+        public static final int STT_TLS = 6;
 
-    public final String name;
-    public final int bind;
-    public final int type;
+        public final String name;
+        public final int bind;
+        public final int type;
 
-    Symbol(String name, int st_info) {
-      this.name = name;
-      this.bind = (st_info >> 4) & 0x0F;
-      this.type = st_info & 0x0F;
-    }
-
-    public String toString() {
-      return "Symbol[" + name + "," + toBind() + "," + toType() + "]";
-    }
-
-    private String toBind() {
-      switch (bind) {
-        case STB_LOCAL: return "LOCAL";
-        case STB_GLOBAL: return "GLOBAL";
-        case STB_WEAK: return "WEAK";
-      }
-      return "STB_??? (" + bind + ")";
-    }
-
-    private String toType() {
-      switch (type) {
-        case STT_NOTYPE: return "NOTYPE";
-        case STT_OBJECT: return "OBJECT";
-        case STT_FUNC: return "FUNC";
-        case STT_SECTION: return "SECTION";
-        case STT_FILE: return "FILE";
-        case STT_COMMON: return "COMMON";
-        case STT_TLS: return "TLS";
-      }
-      return "STT_??? (" + type + ")";
-    }
-  }
-
-  private final String mPath;
-  private final RandomAccessFile mFile;
-  private final byte[] mBuffer = new byte[512];
-  private int mEndian;
-  private boolean mIsDynamic;
-  private boolean mIsPIE;
-  private int mType;
-  private int mAddrSize;
-
-  /** Symbol Table offset */
-  private long mSymTabOffset;
-
-  /** Symbol Table size */
-  private long mSymTabSize;
-
-  /** Dynamic Symbol Table offset */
-  private long mDynSymOffset;
-
-  /** Dynamic Symbol Table size */
-  private long mDynSymSize;
-
-  /** Section Header String Table offset */
-  private long mShStrTabOffset;
-
-  /** Section Header String Table size */
-  private long mShStrTabSize;
-
-  /** String Table offset */
-  private long mStrTabOffset;
-
-  /** String Table size */
-  private long mStrTabSize;
-
-  /** Dynamic String Table offset */
-  private long mDynStrOffset;
-
-  /** Dynamic String Table size */
-  private long mDynStrSize;
-
-  /** Symbol Table symbol names */
-  private Map<String, Symbol> mSymbols;
-
-  /** Dynamic Symbol Table symbol names */
-  private Map<String, Symbol> mDynamicSymbols;
-
-  public static ReadElf read(File file) throws IOException {
-    return new ReadElf(file);
-  }
-
-  public static void main(String[] args) throws IOException {
-    for (String arg : args) {
-      ReadElf re = new ReadElf(new File(arg));
-      re.getSymbol("x");
-      re.getDynamicSymbol("x");
-    }
-  }
-
-  public boolean isDynamic() {
-    return mIsDynamic;
-  }
-
-  public int getType() {
-    return mType;
-  }
-
-  public boolean isPIE() {
-    return mIsPIE;
-  }
-
-  private ReadElf(File file) throws IOException {
-    mPath = file.getPath();
-    mFile = new RandomAccessFile(file, "r");
-
-    if (mFile.length() < EI_NIDENT) {
-      throw new IllegalArgumentException("Too small to be an ELF file: " + file);
-    }
-
-    readHeader();
-  }
-
-  public void close() {
-    try {
-      mFile.close();
-    } catch (IOException ignored) {
-    }
-  }
-
-  protected void finalize() throws Throwable {
-    try {
-      close();
-    } finally {
-      super.finalize();
-    }
-  }
-
-  private void readHeader() throws IOException {
-    mFile.seek(0);
-    mFile.readFully(mBuffer, 0, EI_NIDENT);
-
-    if (mBuffer[0] != ELFMAG[0] || mBuffer[1] != ELFMAG[1] ||
-        mBuffer[2] != ELFMAG[2] || mBuffer[3] != ELFMAG[3]) {
-      throw new IllegalArgumentException("Invalid ELF file: " + mPath);
-    }
-
-    int elfClass = mBuffer[EI_CLASS];
-    if (elfClass == ELFCLASS32) {
-      mAddrSize = 4;
-    } else if (elfClass == ELFCLASS64) {
-      mAddrSize = 8;
-    } else {
-      throw new IOException("Invalid ELF EI_CLASS: " + elfClass + ": " + mPath);
-    }
-
-    mEndian = mBuffer[EI_DATA];
-    if (mEndian == ELFDATA2LSB) {
-    } else if (mEndian == ELFDATA2MSB) {
-      throw new IOException("Unsupported ELFDATA2MSB file: " + mPath);
-    } else {
-      throw new IOException("Invalid ELF EI_DATA: " + mEndian + ": " + mPath);
-    }
-
-    mType = readHalf();
-
-    int e_machine = readHalf();
-    if (e_machine != EM_386 && e_machine != EM_X86_64 &&
-        e_machine != EM_AARCH64 && e_machine != EM_ARM &&
-        e_machine != EM_MIPS &&
-        e_machine != EM_QDSP6) {
-      throw new IOException("Invalid ELF e_machine: " + e_machine + ": " + mPath);
-    }
-
-    // AbiTest relies on us rejecting any unsupported combinations.
-    if ((e_machine == EM_386 && elfClass != ELFCLASS32) ||
-        (e_machine == EM_X86_64 && elfClass != ELFCLASS64) ||
-        (e_machine == EM_AARCH64 && elfClass != ELFCLASS64) ||
-        (e_machine == EM_ARM && elfClass != ELFCLASS32) ||
-        (e_machine == EM_QDSP6 && elfClass != ELFCLASS32)) {
-      throw new IOException("Invalid e_machine/EI_CLASS ELF combination: " +
-                            e_machine + "/" + elfClass + ": " + mPath);
-    }
-
-    long e_version = readWord();
-    if (e_version != EV_CURRENT) {
-      throw new IOException("Invalid e_version: " + e_version + ": " + mPath);
-    }
-
-    long e_entry = readAddr();
-
-    long ph_off = readOff();
-    long sh_off = readOff();
-
-    long e_flags = readWord();
-    int e_ehsize = readHalf();
-    int e_phentsize = readHalf();
-    int e_phnum = readHalf();
-    int e_shentsize = readHalf();
-    int e_shnum = readHalf();
-    int e_shstrndx = readHalf();
-
-    readSectionHeaders(sh_off, e_shnum, e_shentsize, e_shstrndx);
-    readProgramHeaders(ph_off, e_phnum, e_phentsize);
-  }
-
-  private void readSectionHeaders(long sh_off, int e_shnum, int e_shentsize, int e_shstrndx) throws IOException {
-    // Read the Section Header String Table offset first.
-    {
-      mFile.seek(sh_off + e_shstrndx * e_shentsize);
-
-      long sh_name = readWord();
-      long sh_type = readWord();
-      long sh_flags = readX(mAddrSize);
-      long sh_addr = readAddr();
-      long sh_offset = readOff();
-      long sh_size = readX(mAddrSize);
-      // ...
-
-      if (sh_type == SHT_STRTAB) {
-        mShStrTabOffset = sh_offset;
-        mShStrTabSize = sh_size;
-      }
-    }
-
-    for (int i = 0; i < e_shnum; ++i) {
-      // Don't bother to re-read the Section Header StrTab.
-      if (i == e_shstrndx) {
-        continue;
-      }
-
-      mFile.seek(sh_off + i * e_shentsize);
-
-      long sh_name = readWord();
-      long sh_type = readWord();
-      long sh_flags = readX(mAddrSize);
-      long sh_addr = readAddr();
-      long sh_offset = readOff();
-      long sh_size = readX(mAddrSize);
-
-      if (sh_type == SHT_SYMTAB || sh_type == SHT_DYNSYM) {
-        final String symTabName = readShStrTabEntry(sh_name);
-        if (".symtab".equals(symTabName)) {
-          mSymTabOffset = sh_offset;
-          mSymTabSize = sh_size;
-        } else if (".dynsym".equals(symTabName)) {
-          mDynSymOffset = sh_offset;
-          mDynSymSize = sh_size;
+        Symbol(String name, int st_info) {
+            this.name = name;
+            this.bind = (st_info >> 4) & 0x0F;
+            this.type = st_info & 0x0F;
         }
-      } else if (sh_type == SHT_STRTAB) {
-        final String strTabName = readShStrTabEntry(sh_name);
-        if (".strtab".equals(strTabName)) {
-          mStrTabOffset = sh_offset;
-          mStrTabSize = sh_size;
-        } else if (".dynstr".equals(strTabName)) {
-          mDynStrOffset = sh_offset;
-          mDynStrSize = sh_size;
+
+        @Override
+        public String toString() {
+            return "Symbol[" + name + "," + toBind() + "," + toType() + "]";
         }
-      } else if (sh_type == SHT_DYNAMIC) {
-        mIsDynamic = true;
-      }
-    }
-  }
 
-  private void readProgramHeaders(long ph_off, int e_phnum, int e_phentsize) throws IOException {
-    for (int i = 0; i < e_phnum; ++i) {
-      mFile.seek(ph_off + i * e_phentsize);
-
-      long p_type = readWord();
-      if (p_type == PT_LOAD) {
-        if (mAddrSize == 8) {
-          long p_flags = readWord(); // Only in Elf64_phdr; in Elf32_phdr p_flags is at the end.
+        private String toBind() {
+            switch (bind) {
+                case STB_LOCAL:
+                    return "LOCAL";
+                case STB_GLOBAL:
+                    return "GLOBAL";
+                case STB_WEAK:
+                    return "WEAK";
+            }
+            return "STB_??? (" + bind + ")";
         }
-        long p_offset = readOff();
-        long p_vaddr = readAddr();
-        // ...
 
-        if (p_vaddr == 0) {
-          mIsPIE = true;
+        private String toType() {
+            switch (type) {
+                case STT_NOTYPE:
+                    return "NOTYPE";
+                case STT_OBJECT:
+                    return "OBJECT";
+                case STT_FUNC:
+                    return "FUNC";
+                case STT_SECTION:
+                    return "SECTION";
+                case STT_FILE:
+                    return "FILE";
+                case STT_COMMON:
+                    return "COMMON";
+                case STT_TLS:
+                    return "TLS";
+            }
+            return "STT_??? (" + type + ")";
         }
-      }
-    }
-  }
-
-  private HashMap<String, Symbol> readSymbolTable(long symStrOffset, long symStrSize,
-                                                  long tableOffset, long tableSize) throws IOException {
-    HashMap<String, Symbol> result = new HashMap<String, Symbol>();
-    mFile.seek(tableOffset);
-    while (mFile.getFilePointer() < tableOffset + tableSize) {
-      long st_name = readWord();
-      int st_info;
-      if (mAddrSize == 8) {
-        st_info = readByte();
-        int st_other = readByte();
-        int st_shndx = readHalf();
-        long st_value = readAddr();
-        long st_size = readX(mAddrSize);
-      } else {
-        long st_value = readAddr();
-        long st_size = readWord();
-        st_info = readByte();
-        int st_other = readByte();
-        int st_shndx = readHalf();
-      }
-      if (st_name == 0) {
-        continue;
-      }
-
-      final String symName = readStrTabEntry(symStrOffset, symStrSize, st_name);
-      if (symName != null) {
-        Symbol s = new Symbol(symName, st_info);
-        result.put(symName, s);
-      }
-    }
-    return result;
-  }
-
-  private String readShStrTabEntry(long strOffset) throws IOException {
-    if (mShStrTabOffset == 0 || strOffset < 0 || strOffset >= mShStrTabSize) {
-      return null;
-    }
-    return readString(mShStrTabOffset + strOffset);
-  }
-
-  private String readStrTabEntry(long tableOffset, long tableSize, long strOffset) throws IOException {
-    if (tableOffset == 0 || strOffset < 0 || strOffset >= tableSize) {
-      return null;
-    }
-    return readString(tableOffset + strOffset);
-  }
-
-  private int readHalf() throws IOException {
-    return (int) readX(2);
-  }
-
-  private long readWord() throws IOException {
-    return readX(4);
-  }
-
-  private long readOff() throws IOException {
-    return readX(mAddrSize);
-  }
-
-  private long readAddr() throws IOException {
-    return readX(mAddrSize);
-  }
-
-  private long readX(int byteCount) throws IOException {
-    mFile.readFully(mBuffer, 0, byteCount);
-
-    int answer = 0;
-    if (mEndian == ELFDATA2LSB) {
-      for (int i = byteCount - 1; i >= 0; i--) {
-        answer = (answer << 8) | (mBuffer[i] & 0xff);
-      }
-    } else {
-      final int N = byteCount - 1;
-      for (int i = 0; i <= N; ++i) {
-        answer = (answer << 8) | (mBuffer[i] & 0xff);
-      }
     }
 
-    return answer;
-  }
+    private final String mPath;
+    private final RandomAccessFile mFile;
+    private final byte[] mBuffer = new byte[512];
+    private int mEndian;
+    private boolean mIsDynamic;
+    private boolean mIsPIE;
+    private int mType;
+    private int mAddrSize;
 
-  private String readString(long offset) throws IOException {
-    long originalOffset = mFile.getFilePointer();
-    mFile.seek(offset);
-    mFile.readFully(mBuffer, 0, (int) Math.min(mBuffer.length, mFile.length() - offset));
-    mFile.seek(originalOffset);
+    /** Symbol Table offset */
+    private long mSymTabOffset;
 
-    for (int i = 0; i < mBuffer.length; ++i) {
-      if (mBuffer[i] == 0) {
-        return new String(mBuffer, 0, i);
-      }
+    /** Symbol Table size */
+    private long mSymTabSize;
+
+    /** Dynamic Symbol Table offset */
+    private long mDynSymOffset;
+
+    /** Dynamic Symbol Table size */
+    private long mDynSymSize;
+
+    /** Section Header String Table offset */
+    private long mShStrTabOffset;
+
+    /** Section Header String Table size */
+    private long mShStrTabSize;
+
+    /** String Table offset */
+    private long mStrTabOffset;
+
+    /** String Table size */
+    private long mStrTabSize;
+
+    /** Dynamic String Table offset */
+    private long mDynStrOffset;
+
+    /** Dynamic String Table size */
+    private long mDynStrSize;
+
+    /** Symbol Table symbol names */
+    private Map<String, Symbol> mSymbols;
+
+    /** Dynamic Symbol Table symbol names */
+    private Map<String, Symbol> mDynamicSymbols;
+
+    public static ReadElf read(File file) throws IOException {
+        return new ReadElf(file);
     }
 
-    return null;
-  }
+    public static void main(String[] args) throws IOException {
+        for (String arg : args) {
+            ReadElf re = new ReadElf(new File(arg));
+            re.getSymbol("x");
+            re.getDynamicSymbol("x");
+            re.close();
+        }
+    }
 
-  private int readByte() throws IOException {
-    return mFile.read() & 0xff;
-  }
+    public boolean isDynamic() {
+        return mIsDynamic;
+    }
 
-  public Symbol getSymbol(String name) {
-    if (mSymbols == null) {
-      try {
-        mSymbols = readSymbolTable(mStrTabOffset, mStrTabSize, mSymTabOffset, mSymTabSize);
-      } catch (IOException e) {
+    public int getType() {
+        return mType;
+    }
+
+    public boolean isPIE() {
+        return mIsPIE;
+    }
+
+    private ReadElf(File file) throws IOException {
+        mPath = file.getPath();
+        mFile = new RandomAccessFile(file, "r");
+
+        if (mFile.length() < EI_NIDENT) {
+            throw new IllegalArgumentException("Too small to be an ELF file: " + file);
+        }
+
+        readHeader();
+    }
+
+    @Override
+    public void close() {
+        try {
+            mFile.close();
+        } catch (IOException ignored) {
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private void readHeader() throws IOException {
+        mFile.seek(0);
+        mFile.readFully(mBuffer, 0, EI_NIDENT);
+
+        if (mBuffer[0] != ELFMAG[0] || mBuffer[1] != ELFMAG[1] ||
+                mBuffer[2] != ELFMAG[2] || mBuffer[3] != ELFMAG[3]) {
+            throw new IllegalArgumentException("Invalid ELF file: " + mPath);
+        }
+
+        int elfClass = mBuffer[EI_CLASS];
+        if (elfClass == ELFCLASS32) {
+            mAddrSize = 4;
+        } else if (elfClass == ELFCLASS64) {
+            mAddrSize = 8;
+        } else {
+            throw new IOException("Invalid ELF EI_CLASS: " + elfClass + ": " + mPath);
+        }
+
+        mEndian = mBuffer[EI_DATA];
+        if (mEndian == ELFDATA2LSB) {
+        } else if (mEndian == ELFDATA2MSB) {
+            throw new IOException("Unsupported ELFDATA2MSB file: " + mPath);
+        } else {
+            throw new IOException("Invalid ELF EI_DATA: " + mEndian + ": " + mPath);
+        }
+
+        mType = readHalf();
+
+        int e_machine = readHalf();
+        if (e_machine != EM_386 && e_machine != EM_X86_64 &&
+                e_machine != EM_AARCH64 && e_machine != EM_ARM &&
+                e_machine != EM_MIPS &&
+                e_machine != EM_QDSP6) {
+            throw new IOException("Invalid ELF e_machine: " + e_machine + ": " + mPath);
+        }
+
+        // AbiTest relies on us rejecting any unsupported combinations.
+        if ((e_machine == EM_386 && elfClass != ELFCLASS32) ||
+                (e_machine == EM_X86_64 && elfClass != ELFCLASS64) ||
+                (e_machine == EM_AARCH64 && elfClass != ELFCLASS64) ||
+                (e_machine == EM_ARM && elfClass != ELFCLASS32) ||
+                (e_machine == EM_QDSP6 && elfClass != ELFCLASS32)) {
+            throw new IOException("Invalid e_machine/EI_CLASS ELF combination: " +
+                    e_machine + "/" + elfClass + ": " + mPath);
+        }
+
+        long e_version = readWord();
+        if (e_version != EV_CURRENT) {
+            throw new IOException("Invalid e_version: " + e_version + ": " + mPath);
+        }
+
+        long e_entry = readAddr();
+
+        long ph_off = readOff();
+        long sh_off = readOff();
+
+        long e_flags = readWord();
+        int e_ehsize = readHalf();
+        int e_phentsize = readHalf();
+        int e_phnum = readHalf();
+        int e_shentsize = readHalf();
+        int e_shnum = readHalf();
+        int e_shstrndx = readHalf();
+
+        readSectionHeaders(sh_off, e_shnum, e_shentsize, e_shstrndx);
+        readProgramHeaders(ph_off, e_phnum, e_phentsize);
+    }
+
+    private void readSectionHeaders(long sh_off, int e_shnum, int e_shentsize, int e_shstrndx)
+            throws IOException {
+        // Read the Section Header String Table offset first.
+        {
+            mFile.seek(sh_off + e_shstrndx * e_shentsize);
+
+            long sh_name = readWord();
+            long sh_type = readWord();
+            long sh_flags = readX(mAddrSize);
+            long sh_addr = readAddr();
+            long sh_offset = readOff();
+            long sh_size = readX(mAddrSize);
+            // ...
+
+            if (sh_type == SHT_STRTAB) {
+                mShStrTabOffset = sh_offset;
+                mShStrTabSize = sh_size;
+            }
+        }
+
+        for (int i = 0; i < e_shnum; ++i) {
+            // Don't bother to re-read the Section Header StrTab.
+            if (i == e_shstrndx) {
+                continue;
+            }
+
+            mFile.seek(sh_off + i * e_shentsize);
+
+            long sh_name = readWord();
+            long sh_type = readWord();
+            long sh_flags = readX(mAddrSize);
+            long sh_addr = readAddr();
+            long sh_offset = readOff();
+            long sh_size = readX(mAddrSize);
+
+            if (sh_type == SHT_SYMTAB || sh_type == SHT_DYNSYM) {
+                final String symTabName = readShStrTabEntry(sh_name);
+                if (".symtab".equals(symTabName)) {
+                    mSymTabOffset = sh_offset;
+                    mSymTabSize = sh_size;
+                } else if (".dynsym".equals(symTabName)) {
+                    mDynSymOffset = sh_offset;
+                    mDynSymSize = sh_size;
+                }
+            } else if (sh_type == SHT_STRTAB) {
+                final String strTabName = readShStrTabEntry(sh_name);
+                if (".strtab".equals(strTabName)) {
+                    mStrTabOffset = sh_offset;
+                    mStrTabSize = sh_size;
+                } else if (".dynstr".equals(strTabName)) {
+                    mDynStrOffset = sh_offset;
+                    mDynStrSize = sh_size;
+                }
+            } else if (sh_type == SHT_DYNAMIC) {
+                mIsDynamic = true;
+            }
+        }
+    }
+
+    private void readProgramHeaders(long ph_off, int e_phnum, int e_phentsize) throws IOException {
+        for (int i = 0; i < e_phnum; ++i) {
+            mFile.seek(ph_off + i * e_phentsize);
+
+            long p_type = readWord();
+            if (p_type == PT_LOAD) {
+                if (mAddrSize == 8) {
+                    // Only in Elf64_phdr; in Elf32_phdr p_flags is at the end.
+                    long p_flags = readWord();
+                }
+                long p_offset = readOff();
+                long p_vaddr = readAddr();
+                // ...
+
+                if (p_vaddr == 0) {
+                    mIsPIE = true;
+                }
+            }
+        }
+    }
+
+    private HashMap<String, Symbol> readSymbolTable(long symStrOffset, long symStrSize,
+            long tableOffset, long tableSize) throws IOException {
+        HashMap<String, Symbol> result = new HashMap<String, Symbol>();
+        mFile.seek(tableOffset);
+        while (mFile.getFilePointer() < tableOffset + tableSize) {
+            long st_name = readWord();
+            int st_info;
+            if (mAddrSize == 8) {
+                st_info = readByte();
+                int st_other = readByte();
+                int st_shndx = readHalf();
+                long st_value = readAddr();
+                long st_size = readX(mAddrSize);
+            } else {
+                long st_value = readAddr();
+                long st_size = readWord();
+                st_info = readByte();
+                int st_other = readByte();
+                int st_shndx = readHalf();
+            }
+            if (st_name == 0) {
+                continue;
+            }
+
+            final String symName = readStrTabEntry(symStrOffset, symStrSize, st_name);
+            if (symName != null) {
+                Symbol s = new Symbol(symName, st_info);
+                result.put(symName, s);
+            }
+        }
+        return result;
+    }
+
+    private String readShStrTabEntry(long strOffset) throws IOException {
+        if (mShStrTabOffset == 0 || strOffset < 0 || strOffset >= mShStrTabSize) {
+            return null;
+        }
+        return readString(mShStrTabOffset + strOffset);
+    }
+
+    private String readStrTabEntry(long tableOffset, long tableSize, long strOffset)
+            throws IOException {
+        if (tableOffset == 0 || strOffset < 0 || strOffset >= tableSize) {
+            return null;
+        }
+        return readString(tableOffset + strOffset);
+    }
+
+    private int readHalf() throws IOException {
+        return (int) readX(2);
+    }
+
+    private long readWord() throws IOException {
+        return readX(4);
+    }
+
+    private long readOff() throws IOException {
+        return readX(mAddrSize);
+    }
+
+    private long readAddr() throws IOException {
+        return readX(mAddrSize);
+    }
+
+    private long readX(int byteCount) throws IOException {
+        mFile.readFully(mBuffer, 0, byteCount);
+
+        int answer = 0;
+        if (mEndian == ELFDATA2LSB) {
+            for (int i = byteCount - 1; i >= 0; i--) {
+                answer = (answer << 8) | (mBuffer[i] & 0xff);
+            }
+        } else {
+            final int N = byteCount - 1;
+            for (int i = 0; i <= N; ++i) {
+                answer = (answer << 8) | (mBuffer[i] & 0xff);
+            }
+        }
+
+        return answer;
+    }
+
+    private String readString(long offset) throws IOException {
+        long originalOffset = mFile.getFilePointer();
+        mFile.seek(offset);
+        mFile.readFully(mBuffer, 0, (int) Math.min(mBuffer.length, mFile.length() - offset));
+        mFile.seek(originalOffset);
+
+        for (int i = 0; i < mBuffer.length; ++i) {
+            if (mBuffer[i] == 0) {
+                return new String(mBuffer, 0, i);
+            }
+        }
+
         return null;
-      }
     }
-    return mSymbols.get(name);
-  }
 
-  public Symbol getDynamicSymbol(String name) {
-    if (mDynamicSymbols == null) {
-      try {
-        mDynamicSymbols = readSymbolTable(mDynStrOffset, mDynStrSize, mDynSymOffset, mDynSymSize);
-      } catch (IOException e) {
-        return null;
-      }
+    private int readByte() throws IOException {
+        return mFile.read() & 0xff;
     }
-    return mDynamicSymbols.get(name);
-  }
+
+    public Symbol getSymbol(String name) {
+        if (mSymbols == null) {
+            try {
+                mSymbols = readSymbolTable(mStrTabOffset, mStrTabSize, mSymTabOffset, mSymTabSize);
+            } catch (IOException e) {
+                return null;
+            }
+        }
+        return mSymbols.get(name);
+    }
+
+    public Symbol getDynamicSymbol(String name) {
+        if (mDynamicSymbols == null) {
+            try {
+                mDynamicSymbols = readSymbolTable(
+                        mDynStrOffset, mDynStrSize, mDynSymOffset, mDynSymSize);
+            } catch (IOException e) {
+                return null;
+            }
+        }
+        return mDynamicSymbols.get(name);
+    }
 }
diff --git a/tests/tests/rscpp/librscpptest/rs_jni.cpp b/tests/tests/rscpp/librscpptest/rs_jni.cpp
index d582e05..f5946f5 100644
--- a/tests/tests/rscpp/librscpptest/rs_jni.cpp
+++ b/tests/tests/rscpp/librscpptest/rs_jni.cpp
@@ -371,79 +371,4 @@
 
 }
 
-extern "C" JNIEXPORT jboolean JNICALL
-Java_android_cts_rscpp_RSLoopFilterTest_loopfilterTest(JNIEnv * env, jclass obj, jstring pathObj,
-                                                       jint start, jint stop, jint num_planes,
-                                                       jint mi_rows, jint mi_cols,
-                                                       jint y_offset, jint u_offset, jint v_offset,
-                                                       jint y_stride, jint uv_stride,
-                                                       jbyteArray lf_infoArray,
-                                                       jbyteArray lfmsArray,
-                                                       jbyteArray frameArray)
-{
-    const int mi_block_size = 8;
-
-    const char * path = env->GetStringUTFChars(pathObj, NULL);
-    sp<RS> rs = new RS();
-    rs->init(path);
-
-    jbyte * plf_info = (jbyte *) env->GetPrimitiveArrayCritical(lf_infoArray, 0);
-    jbyte * plfms = (jbyte *) env->GetPrimitiveArrayCritical(lfmsArray, 0);
-    jbyte * pframe = (jbyte *) env->GetPrimitiveArrayCritical(frameArray, 0);
-
-    ScriptIntrinsicVP9LoopFilter::BufferInfo buf_info = {y_offset, u_offset, v_offset,
-                                                         y_stride, uv_stride};
-    ScriptIntrinsicVP9LoopFilter::LoopFilterInfoN * lf_info =
-            (ScriptIntrinsicVP9LoopFilter::LoopFilterInfoN *) plf_info;
-    ScriptIntrinsicVP9LoopFilter::LoopFilterMask * lfms =
-            (ScriptIntrinsicVP9LoopFilter::LoopFilterMask *) plfms;
-
-    ScriptIntrinsicVP9LoopFilter::LoopFilterInfoN lf_info_obj;
-    memcpy(&lf_info_obj, lf_info, sizeof(lf_info_obj));
-
-    size_t frame_size = env->GetArrayLength(frameArray);
-    uint8_t * frame_buffer_ptr = (uint8_t *) aligned_alloc(128, frame_size);
-    memcpy(frame_buffer_ptr, pframe, frame_size);
-
-    sp<const Element> e = Element::U8(rs);
-
-    int size_lfm = sizeof(ScriptIntrinsicVP9LoopFilter::LoopFilterInfoN);
-    sp<const Type> t_lf_info = Type::create(rs, e, size_lfm, 0, 0);
-    int size_lfms = (stop + mi_block_size - start) / mi_block_size *
-                    (mi_cols + mi_block_size) / mi_block_size *
-                    sizeof(ScriptIntrinsicVP9LoopFilter::LoopFilterMask);
-    sp<const Type> t_mask = Type::create(rs, e, size_lfms, 0, 0);
-
-    sp<Allocation> lf_info_buffer = Allocation::createTyped(
-            rs, t_lf_info, RS_ALLOCATION_MIPMAP_NONE,
-            RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_SCRIPT,
-            &lf_info_obj);
-    sp<Allocation> mask_buffer = Allocation::createTyped(
-            rs, t_mask, RS_ALLOCATION_MIPMAP_NONE,
-            RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_SCRIPT,
-            lfms);
-
-    sp<const Type> frameType = Type::create(rs, e, frame_size, 0, 0);
-    sp<Allocation> frame_buffers = Allocation::createTyped(
-            rs, frameType, RS_ALLOCATION_MIPMAP_NONE,
-            RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_SCRIPT,
-            frame_buffer_ptr);
-
-    sp<ScriptIntrinsicVP9LoopFilter> loopFilter = ScriptIntrinsicVP9LoopFilter::create(rs, e);
-
-    loopFilter->setLoopFilterDomain(start, stop, num_planes, mi_rows, mi_cols);
-    loopFilter->setBufferInfo(&buf_info);
-    loopFilter->setLoopFilterInfo(lf_info_buffer);
-    loopFilter->setLoopFilterMasks(mask_buffer);
-    loopFilter->forEach(frame_buffers);
-    rs->finish();
-
-    memcpy(pframe, frame_buffer_ptr, frame_size);
-    aligned_free(frame_buffer_ptr);
-    env->ReleasePrimitiveArrayCritical(frameArray, pframe, 0);
-    env->ReleasePrimitiveArrayCritical(lfmsArray, plfms, 0);
-    env->ReleasePrimitiveArrayCritical(lf_infoArray, plf_info, 0);
-    env->ReleaseStringUTFChars(pathObj, path);
-    return (rs->getError() == RS_SUCCESS);
-}
 
diff --git a/tests/tests/rscpp/res/raw/rs_loopfilter_param.bin b/tests/tests/rscpp/res/raw/rs_loopfilter_param.bin
deleted file mode 100644
index cf52c44..0000000
--- a/tests/tests/rscpp/res/raw/rs_loopfilter_param.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSLoopFilterTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSLoopFilterTest.java
deleted file mode 100644
index 189a7e9..0000000
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSLoopFilterTest.java
+++ /dev/null
@@ -1,1200 +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.cts.rscpp;
-
-import com.android.cts.rscpp.R;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.test.AndroidTestCase;
-import android.renderscript.*;
-import android.util.Log;
-import java.io.InputStream;
-import java.util.Random;
-
-public class RSLoopFilterTest extends RSCppTest {
-
-    static {
-        System.loadLibrary("rscpptest_jni");
-    }
-
-    native boolean loopfilterTest(String cacheDir,
-            int start, int stop, int num_planes, int mi_rows, int mi_cols,
-            int y_offset, int u_offset, int v_offset, int y_stride, int uv_stride,
-            byte[] lf_infoArray, byte[] lfmsArray, byte[] frameArray);
-
-    private static final int MI_SIZE_LOG2 = 3;
-    private static final int MI_BLOCK_SIZE_LOG2 = 6 - MI_SIZE_LOG2;
-
-    private static final int MI_SIZE = (1 << MI_SIZE_LOG2);
-    private static final int MI_BLOCK_SIZE = (1 << MI_BLOCK_SIZE_LOG2);
-
-    private static final int MI_MASK = MI_BLOCK_SIZE - 1;
-
-    private static final int SIMD_WIDTH = 16;
-    private static final int MAX_LOOP_FILTER = 63;
-    private static final int MAX_SEGMENTS = 8;
-    private static final int MAX_REF_FRAMES = 4;
-    private static final int MAX_MODE_LF_DELTAS = 2;
-    private static final int MB_MODE_COUNT = 14;
-    private static final int BLOCK_SIZES = 13;
-
-    private static final int MAX_CPU_CORES = 32;
-    private static final int MAX_MB_PLANE = 3;
-    private static final int MAX_SB_COL = 32;
-
-    class LoopFilterMask {
-        long[] left_y;
-        long[] above_y;
-        long int_4x4_y;
-        short[] left_uv;
-        short[] above_uv;
-        short int_4x4_uv;
-        byte[] lfl_y;
-        byte[] lfl_uv;
-
-        LoopFilterMask() {
-            left_y = new long[4];
-            above_y = new long[4];
-            int_4x4_y = 0;
-            left_uv = new short[4];
-            above_uv = new short[4];
-            int_4x4_uv = 0;
-            lfl_y = new byte[64];
-            lfl_uv = new byte[16];
-        }
-    }
-
-    class LoopFilterThresh {
-        byte[] mblim;
-        byte[] lim;
-        byte[] hev_thr;
-
-        LoopFilterThresh() {
-            mblim = new byte[SIMD_WIDTH];
-            lim = new byte[SIMD_WIDTH];
-            hev_thr = new byte[SIMD_WIDTH];
-        }
-    }
-
-    class LoopFilterInfoN {
-        LoopFilterThresh[] lfthr;
-        byte[][][] lvl;
-        byte[] mode_lf_lut;
-
-        LoopFilterInfoN() {
-            lfthr = new LoopFilterThresh[MAX_LOOP_FILTER + 1];
-            for (int i = 0; i < MAX_LOOP_FILTER + 1; ++i) {
-                lfthr[i] = new LoopFilterThresh();
-            }
-            lvl = new byte[MAX_SEGMENTS][MAX_REF_FRAMES][MAX_MODE_LF_DELTAS];
-            mode_lf_lut = new byte[MB_MODE_COUNT];
-        }
-    }
-
-    class BufferInfo {
-        int y_offset;
-        int u_offset;
-        int v_offset;
-        int y_stride;
-        int uv_stride;
-
-        BufferInfo() {
-            y_offset = 0;
-            u_offset = 0;
-            v_offset = 0;
-            y_stride = 0;
-            uv_stride = 0;
-        }
-    }
-
-    private static final int sizeofShort = 2;
-    private static final int sizeofInt = 4;
-    private static final int sizeofUInt64 = 8;
-    private byte[] dataArray;
-
-    private int start = 0;
-    private int stop = 0;
-    private int num_planes = 0;
-    private int mi_rows = 0;
-    private int mi_cols = 0;
-
-    private int y_offset = 0;
-    private int u_offset = 0;
-    private int v_offset = 0;
-    private int y_stride = 0;
-    private int uv_stride = 0;
-
-    private int size_lf_info = 0;
-    private int size_lfm = 0;
-    private int size_lfms = 0;
-    private int frame_buffer_size = 0;
-
-    public BufferInfo buf_info;
-    public LoopFilterInfoN lf_info;
-    public LoopFilterMask[] lfms;
-
-    private byte[] buffer_alloc;
-    private byte[] frameArray;
-
-    private long getLongData(byte[] inArray, int index, int elementsize) {
-        long result = 0;
-        for (int i = 0; i < elementsize; i++) {
-            result += (0xffL & inArray[index + i]) << (8 * i);
-        }
-        return result;
-    }
-
-    private int getIntData(byte[] inArray, int index, int elementsize) {
-        int result = 0;
-        for (int i = 0; i < elementsize; i++) {
-            result += (0xff & inArray[index + i]) << (8 * i);
-        }
-        return result;
-    }
-
-    private short getShortData(byte[] inArray, int index, int elementsize) {
-        short result = 0;
-        for (int i = 0; i < elementsize; i++) {
-            result += (0xff & inArray[index + i]) << (8 * i);
-        }
-        return (short) result;
-    }
-
-    private void initDataArray() {
-        Random rand = new Random();
-        for (int i = 0; i < buffer_alloc.length; i++) {
-            buffer_alloc[i] = (byte)(rand.nextInt(30));
-            frameArray[i] = buffer_alloc[i];
-        }
-    }
-
-    public void testRSLoopFilter() {
-
-        try {
-            InputStream in = getContext().getResources().openRawResource(R.raw.rs_loopfilter_param);
-            int length = in.available();
-            dataArray = new byte[length];
-            in.read(dataArray);
-            in.close();
-        } catch(Exception e) {
-            e.printStackTrace();
-        }
-
-        int getNum = 0;
-        start = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        stop = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        num_planes = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        mi_rows = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        mi_cols = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-
-        y_offset = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        u_offset = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        v_offset = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        y_stride = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        uv_stride = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-
-        size_lf_info = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        size_lfm = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        size_lfms = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-        frame_buffer_size = getIntData(dataArray, getNum, sizeofInt);
-        getNum += sizeofInt;
-
-        lf_info = new LoopFilterInfoN();
-        for (int i = 0; i < lf_info.lfthr.length; i++) {
-            for (int j = 0; j < lf_info.lfthr[i].mblim.length; j++) {
-                lf_info.lfthr[i].mblim[j] = dataArray[getNum];
-                getNum++;
-            }
-            for (int j = 0; j < lf_info.lfthr[i].lim.length; j++) {
-                lf_info.lfthr[i].lim[j] = dataArray[getNum];
-                getNum++;
-            }
-            for (int j = 0; j < lf_info.lfthr[i].hev_thr.length; j++) {
-                lf_info.lfthr[i].hev_thr[j] = dataArray[getNum];
-                getNum++;
-            }
-        }
-        for (int i = 0; i < lf_info.lvl.length; i++) {
-            for (int j = 0; j < lf_info.lvl[i].length; j++) {
-                for (int k = 0; k < lf_info.lvl[i][j].length; k++) {
-                    lf_info.lvl[i][j][k] = dataArray[getNum];
-                    getNum++;
-                }
-            }
-        }
-        for (int i = 0; i < lf_info.mode_lf_lut.length; i++) {
-            lf_info.mode_lf_lut[i] = dataArray[getNum];
-            getNum++;
-        }
-        getNum += size_lf_info - 3150;
-
-        lfms = new LoopFilterMask[size_lfms / size_lfm];
-        for (int i = 0; i < size_lfms / size_lfm; i++) {
-            lfms[i] = new LoopFilterMask();
-            for (int j = 0; j < lfms[i].left_y.length; j++) {
-                lfms[i].left_y[j] = getLongData(dataArray, getNum, sizeofUInt64);
-                getNum += sizeofUInt64;
-            }
-            for (int j = 0; j < lfms[i].above_y.length; j++) {
-                lfms[i].above_y[j] = getLongData(dataArray, getNum, sizeofUInt64);
-                getNum += sizeofUInt64;
-            }
-            lfms[i].int_4x4_y = getLongData(dataArray, getNum, sizeofUInt64);
-            getNum += sizeofUInt64;
-            for (int j = 0; j < lfms[i].left_uv.length; j++) {
-                lfms[i].left_uv[j] = getShortData(dataArray, getNum, sizeofShort);
-                getNum += sizeofShort;
-            }
-            for (int j = 0; j < lfms[i].above_uv.length; j++) {
-                lfms[i].above_uv[j] = getShortData(dataArray, getNum, sizeofShort);
-                getNum += sizeofShort;
-            }
-            lfms[i].int_4x4_uv = getShortData(dataArray, getNum, sizeofShort);
-            getNum += sizeofShort;
-            for (int j = 0; j < lfms[i].lfl_y.length; j++) {
-                lfms[i].lfl_y[j] = dataArray[getNum];
-                getNum ++;
-            }
-            for (int j = 0; j < lfms[i].lfl_uv.length; j++) {
-                lfms[i].lfl_uv[j] = dataArray[getNum];
-                getNum ++;
-            }
-            getNum += size_lfm - 170;
-        }
-
-        buf_info = new BufferInfo();
-        buf_info.y_offset = y_offset;
-        buf_info.u_offset = u_offset;
-        buf_info.v_offset = v_offset;
-        buf_info.y_stride = y_stride;
-        buf_info.uv_stride = uv_stride;
-
-        getNum = 14 * sizeofInt;
-        byte[] lf_infoArray = new byte[size_lf_info];
-        for (int i = 0; i < lf_infoArray.length; i++) {
-            lf_infoArray[i] = dataArray[getNum + i];
-        }
-        getNum += size_lf_info;
-        byte[] lfmsArray = new byte[size_lfms];
-        for (int i = 0; i < lfmsArray.length; i++) {
-            lfmsArray[i] = dataArray[getNum + i];
-        }
-
-        buffer_alloc = new byte[frame_buffer_size];
-        frameArray = new byte[frame_buffer_size];
-        initDataArray();
-
-        loopfilterTest(this.getContext().getCacheDir().toString(),
-                start, stop, num_planes, mi_rows, mi_cols,
-                y_offset, u_offset, v_offset, y_stride, uv_stride,
-                lf_infoArray, lfmsArray, frameArray);
-
-        vp9_loop_filter_rows_work_proc(start, stop, num_planes, mi_rows, mi_cols,
-                buf_info, buffer_alloc, lf_info, lfms);
-
-        for (int i = 0; i < frame_buffer_size; ++i) {
-            assertTrue(frameArray[i] == buffer_alloc[i]);
-        }
-
-    }
-
-    private static int round_power_of_two(int value, int n) {
-
-        int res = ((value) + (1 << ((n) - 1)) >>> (n));
-        return res;
-    }
-
-    private static int round_power_of_two_signed(int value, int n) {
-
-        int res = (((value) + (1 << ((n) - 1))) >> (n));
-        return res;
-    }
-
-    private static int clamp(int data, int low, int high) {
-
-        int res = (data < low ? low : (data > high ? high : data));
-        return res;
-    }
-
-    private static byte signed_char_clamp(int t) {
-
-        return (byte)clamp(t, -128, 127);
-    }
-
-    private static byte filter_mask(byte limit, byte blimit,
-                                    byte p3, byte p2,
-                                    byte p1, byte p0,
-                                    byte q0, byte q1,
-                                    byte q2, byte q3) {
-
-        byte mask = 0;
-        mask |= (Math.abs((p3 & 0xff) - (p2 & 0xff)) > (limit & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((p2 & 0xff) - (p1 & 0xff)) > (limit & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((p1 & 0xff) - (p0 & 0xff)) > (limit & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((q1 & 0xff) - (q0 & 0xff)) > (limit & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((q2 & 0xff) - (q1 & 0xff)) > (limit & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((q3 & 0xff) - (q2 & 0xff)) > (limit & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((p0 & 0xff) - (q0 & 0xff)) * 2 + Math.abs((p1 & 0xff) - (q1 & 0xff)) / 2
-                > (blimit & 0xff)) ? -1 : 0;
-        return (byte)(~mask);
-    }
-
-    private static byte flat_mask4(byte thresh,
-                                   byte p3, byte p2,
-                                   byte p1, byte p0,
-                                   byte q0, byte q1,
-                                   byte q2, byte q3) {
-
-        byte mask = 0;
-        mask |= (Math.abs((p1 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((q1 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((p2 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((q2 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((p3 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((q3 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        return (byte)(~mask);
-    }
-
-    private static byte flat_mask5(byte thresh,
-                                   byte p4, byte p3,
-                                   byte p2, byte p1,
-                                   byte p0, byte q0,
-                                   byte q1, byte q2,
-                                   byte q3, byte q4) {
-
-        byte mask = (byte)(~flat_mask4(thresh, p3, p2, p1, p0, q0, q1, q2, q3));
-        mask |= (Math.abs((p4 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        mask |= (Math.abs((q4 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        return (byte)(~mask);
-    }
-
-    // There is high edge variance internal edge: 11111111 yes, 00000000 no
-    private static byte hev_mask(byte thresh,
-                                 byte p1, byte p0,
-                                 byte q0, byte q1) {
-
-        byte hev = 0;
-        hev |= (Math.abs((p1 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        hev |= (Math.abs((q1 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
-        return hev;
-    }
-
-    private static void filter4(byte mask, byte thresh,
-                                byte[] op1, int index_op1,
-                                byte[] op0, int index_op0,
-                                byte[] oq0, int index_oq0,
-                                byte[] oq1, int index_oq1) {
-
-        byte filter1, filter2;
-
-        final byte ps1 = (byte)(op1[index_op1] ^ 0x80);
-        final byte ps0 = (byte)(op0[index_op0] ^ 0x80);
-        final byte qs0 = (byte)(oq0[index_oq0] ^ 0x80);
-        final byte qs1 = (byte)(oq1[index_oq1] ^ 0x80);
-
-        final byte hev = hev_mask(thresh, op1[index_op1], op0[index_op0], oq0[index_oq0],
-                oq1[index_oq1]);
-
-        // add outer taps if we have high edge variance
-        byte filter = (byte)(signed_char_clamp(ps1 - qs1) & hev);
-
-        // inner taps
-        filter = (byte)(signed_char_clamp(filter + 3 * (qs0 - ps0)) & mask);
-
-        // save bottom 3 bits so that we round one side +4 and the other +3
-        // if it equals 4 we'll set to adjust by -1 to account for the fact
-        // we'd round 3 the other way
-        filter1 = (byte)(signed_char_clamp(filter + 4) >> 3);
-        filter2 = (byte)(signed_char_clamp(filter + 3) >> 3);
-
-        oq0[index_oq0] = (byte)(signed_char_clamp(qs0 - filter1) ^ 0x80);
-        op0[index_op0] = (byte)(signed_char_clamp(ps0 + filter2) ^ 0x80);
-
-        // outer tap adjustments
-        filter = (byte)(round_power_of_two_signed(filter1, 1) & (~hev));
-
-        oq1[index_oq1] = (byte)(signed_char_clamp(qs1 - filter) ^ 0x80);
-        op1[index_op1] = (byte)(signed_char_clamp(ps1 + filter) ^ 0x80);
-    }
-
-    private static void vp9_lpf_horizontal_4_c(byte[] s, int index, int p,
-                                               final byte[] blimit, final byte[] limit,
-                                               final byte[] thresh, int count) {
-
-        int i;
-        // loop filter designed to work using chars so that we can make maximum use
-        // of 8 bit simd instructions.
-        for (i = 0; i < 8 * count; ++i) {
-             byte p3 = s[index - 4 * p], p2 = s[index - 3 * p], p1 = s[index - 2 * p],
-                     p0 = s[index - p];
-             byte q0 = s[index + 0 * p], q1 = s[index + 1 * p], q2 = s[index + 2 * p],
-                     q3 = s[index + 3 * p];
-             byte mask = (byte)filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
-
-            filter4(mask, thresh[0], s, index - 2 * p, s, index - 1 * p, s, index, s,
-                    index + 1 * p);
-            ++index;
-        }
-    }
-
-    private static void vp9_lpf_horizontal_4_dual_c(byte[] s, int index, int p,
-                                                    final byte[] blimit0, final byte[] limit0,
-                                                    final byte[] thresh0, final byte[] blimit1,
-                                                    final byte[] limit1, final byte[] thresh1) {
-
-        vp9_lpf_horizontal_4_c(s, index, p, blimit0, limit0, thresh0, 1);
-        vp9_lpf_horizontal_4_c(s, index + 8, p, blimit1, limit1, thresh1, 1);
-    }
-
-    private static void vp9_lpf_vertical_4_c(byte[] s, int index, int pitch,
-                                             final byte[] blimit, final byte[] limit,
-                                             final byte[] thresh, int count) {
-
-        int i;
-        // loop filter designed to work using chars so that we can make maximum use
-        // of 8 bit simd instructions.
-        for (i = 0; i < 8 * count; ++i) {
-            final byte p3 = s[index - 4], p2 = s[index - 3], p1 = s[index - 2], p0 = s[index - 1];
-            final byte q0 = s[index], q1 = s[index + 1], q2 = s[index + 2], q3 = s[index + 3];
-            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
-
-            filter4(mask, thresh[0], s, index - 2, s, index - 1, s, index, s, index + 1);
-            index += pitch;
-        }
-    }
-
-    private static void vp9_lpf_vertical_4_dual_c(byte[] s, int index, int pitch,
-                                                  final byte[] blimit0, final byte[] limit0,
-                                                  final byte[] thresh0, final byte[] blimit1,
-                                                  final byte[] limit1, final byte[] thresh1) {
-
-        vp9_lpf_vertical_4_c(s, index, pitch, blimit0, limit0, thresh0, 1);
-        vp9_lpf_vertical_4_c(s, index + 8 * pitch, pitch, blimit1, limit1, thresh1, 1);
-    }
-
-    private static void filter8(byte mask, byte thresh, byte flat,
-                                byte[] op3, int index_op3,
-                                byte[] op2, int index_op2,
-                                byte[] op1, int index_op1,
-                                byte[] op0, int index_op0,
-                                byte[] oq0, int index_oq0,
-                                byte[] oq1, int index_oq1,
-                                byte[] oq2, int index_oq2,
-                                byte[] oq3, int index_oq3) {
-
-        if (((flat & 0xff) != 0) && (mask != 0)) {
-            final byte p3 = op3[index_op3], p2 = op2[index_op2], p1 = op1[index_op1],
-                    p0 = op0[index_op0];
-            final byte q0 = oq0[index_oq0], q1 = oq1[index_oq1], q2 = oq2[index_oq2],
-                    q3 = oq3[index_oq3];
-
-            // 7-tap filter [1, 1, 1, 2, 1, 1, 1]
-            op2[index_op2] = (byte)round_power_of_two((p3 & 0xff) + (p3 & 0xff) + (p3 & 0xff) +
-                    2 * (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff), 3);
-            op1[index_op1] = (byte)round_power_of_two((p3 & 0xff) + (p3 & 0xff) + (p2 & 0xff) +
-                    2 * (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff), 3);
-            op0[index_op0] = (byte)round_power_of_two((p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) +
-                    2 * (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff), 3);
-            oq0[index_oq0] = (byte)round_power_of_two((p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) +
-                    2 * (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff), 3);
-            oq1[index_oq1] = (byte)round_power_of_two((p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) +
-                    2 * (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q3 & 0xff), 3);
-            oq2[index_oq2] = (byte)round_power_of_two((p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) +
-                    2 * (q2 & 0xff) + (q3 & 0xff) + (q3 & 0xff) + (q3 & 0xff), 3);
-        } else {
-            filter4(mask, thresh, op1, index_op1, op0, index_op0, oq0, index_oq0, oq1, index_oq1);
-        }
-    }
-
-    private static void vp9_lpf_horizontal_8_c(byte[] s, int index,  int p,
-                                               final byte[] blimit, final byte[] limit,
-                                               final byte[] thresh, int count) {
-
-        int i;
-        // loop filter designed to work using chars so that we can make maximum use
-        // of 8 bit simd instructions.
-        for (i = 0; i < 8 * count; ++i) {
-            final byte p3 = s[index - 4 * p], p2 = s[index - 3 * p], p1 = s[index - 2 * p],
-                    p0 = s[index - p];
-            final byte q0 = s[index + 0 * p], q1 = s[index + 1 * p], q2 = s[index + 2 * p],
-                    q3 = s[index + 3 * p];
-
-            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
-            final byte flat = flat_mask4((byte)1, p3, p2, p1, p0, q0, q1, q2, q3);
-
-            filter8(mask, thresh[0], flat, s, index - 4 * p, s, index - 3 * p, s, index - 2 * p, s,
-                    index - 1 * p, s, index, s, index + 1 * p, s, index + 2 * p, s, index + 3 * p);
-            ++index;
-        }
-    }
-
-    private static void vp9_lpf_horizontal_8_dual_c(byte[] s, int index, int p,
-                                                    final byte[] blimit0, final byte[] limit0,
-                                                    final byte[] thresh0, final byte[] blimit1,
-                                                    final byte[] limit1,  final byte[] thresh1) {
-
-        vp9_lpf_horizontal_8_c(s, index, p, blimit0, limit0, thresh0, 1);
-        vp9_lpf_horizontal_8_c(s, index + 8, p, blimit1, limit1, thresh1, 1);
-    }
-
-    private static void vp9_lpf_vertical_8_c(byte[] s, int index, int pitch,
-                                             final byte[] blimit, final byte[] limit,
-                                             final byte[] thresh, int count) {
-
-        int i;
-        for (i = 0; i < 8 * count; ++i) {
-            final byte p3 = s[index - 4], p2 = s[index - 3], p1 = s[index - 2], p0 = s[index - 1];
-            final byte q0 = s[index + 0], q1 = s[index + 1], q2 = s[index + 2], q3 = s[index + 3];
-            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
-            final byte flat = flat_mask4((byte)1, p3, p2, p1, p0, q0, q1, q2, q3);
-
-            filter8(mask, thresh[0], flat, s, index - 4, s, index - 3, s, index - 2, s, index - 1,
-                    s, index, s, index + 1, s, index + 2, s, index + 3);
-            index += pitch;
-        }
-    }
-
-    private static void vp9_lpf_vertical_8_dual_c(byte[] s, int index, int pitch,
-                                                  final byte[] blimit0, final byte[] limit0,
-                                                  final byte[] thresh0, final byte[] blimit1,
-                                                  final byte[] limit1, final byte[] thresh1) {
-
-        vp9_lpf_vertical_8_c(s, index, pitch, blimit0, limit0, thresh0, 1);
-        vp9_lpf_vertical_8_c(s, index + 8 * pitch, pitch, blimit1, limit1, thresh1, 1);
-    }
-
-    private static void filter16(byte mask, byte thresh,
-                                 byte flat, byte flat2,
-                                 byte[] op7, int index_op7,
-                                 byte[] op6, int index_op6,
-                                 byte[] op5, int index_op5,
-                                 byte[] op4, int index_op4,
-                                 byte[] op3, int index_op3,
-                                 byte[] op2, int index_op2,
-                                 byte[] op1, int index_op1,
-                                 byte[] op0, int index_op0,
-                                 byte[] oq0, int index_oq0,
-                                 byte[] oq1, int index_oq1,
-                                 byte[] oq2, int index_oq2,
-                                 byte[] oq3, int index_oq3,
-                                 byte[] oq4, int index_oq4,
-                                 byte[] oq5, int index_oq5,
-                                 byte[] oq6, int index_oq6,
-                                 byte[] oq7, int index_oq7) {
-
-        if (((flat2 & 0xff) != 0) && ((flat & 0xff) != 0) && (mask != 0)) {
-            final byte p7 = op7[index_op7], p6 = op6[index_op6], p5 = op5[index_op5],
-                    p4 = op4[index_op4], p3 = op3[index_op3], p2 = op2[index_op2],
-                    p1 = op1[index_op1], p0 = op0[index_op0];
-
-            final byte q0 = oq0[index_oq0], q1 = oq1[index_oq1], q2 = oq2[index_oq2],
-                    q3 = oq3[index_oq3], q4 = oq4[index_oq4], q5 = oq5[index_oq5],
-                    q6 = oq6[index_oq6], q7 = oq7[index_oq7];
-
-            // 15-tap filter [1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1]
-            op6[index_op6] = (byte)round_power_of_two((p7 & 0xff) * 7 + (p6 & 0xff) * 2 +
-                    (p5 & 0xff) + (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) +
-                    (p0 & 0xff) + (q0 & 0xff), 4);
-            op5[index_op5] = (byte)round_power_of_two((p7 & 0xff) * 6 + (p6 & 0xff) +
-                    (p5 & 0xff) * 2 + (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) +
-                    (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff), 4);
-            op4[index_op4] = (byte)round_power_of_two((p7 & 0xff) * 5 + (p6 & 0xff) + (p5 & 0xff) +
-                    (p4 & 0xff) * 2 + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) +
-                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff), 4);
-            op3[index_op3] = (byte)round_power_of_two((p7 & 0xff) * 4 + (p6 & 0xff) + (p5 & 0xff) +
-                    (p4 & 0xff) + (p3 & 0xff) * 2 + (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) +
-                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff), 4);
-            op2[index_op2] = (byte)round_power_of_two((p7 & 0xff) * 3 + (p6 & 0xff) + (p5 & 0xff) +
-                    (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) * 2 + (p1 & 0xff) + (p0 & 0xff) +
-                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff), 4);
-            op1[index_op1] = (byte)round_power_of_two((p7 & 0xff) * 2 + (p6 & 0xff) + (p5 & 0xff) +
-                    (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) * 2 + (p0 & 0xff) +
-                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) +
-                    (q5 & 0xff), 4);
-            op0[index_op0] = (byte)round_power_of_two((p7 & 0xff) + (p6 & 0xff) + (p5 & 0xff) +
-                    (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) * 2 +
-                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) +
-                    (q5 & 0xff) + (q6 & 0xff), 4);
-            oq0[index_oq0] = (byte)round_power_of_two((p6 & 0xff) + (p5 & 0xff) + (p4 & 0xff) +
-                    (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) * 2 +
-                    (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) +
-                    (q6 & 0xff) + (q7 & 0xff), 4);
-            oq1[index_oq1] = (byte)round_power_of_two((p5 & 0xff) + (p4 & 0xff) + (p3 & 0xff) +
-                    (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) * 2 +
-                    (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) + (q6 & 0xff) +
-                    (q7 & 0xff) * 2, 4);
-            oq2[index_oq2] = (byte)round_power_of_two((p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) +
-                    (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) * 2 +
-                    (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) + (q6 & 0xff) + (q7 & 0xff) * 3, 4);
-            oq3[index_oq3] = (byte)round_power_of_two((p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) +
-                    (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) * 2 +
-                    (q4 & 0xff) + (q5 & 0xff) + (q6 & 0xff) + (q7 & 0xff) * 4, 4);
-            oq4[index_oq4] = (byte)round_power_of_two((p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) +
-                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) * 2 +
-                    (q5 & 0xff) + (q6 & 0xff) + (q7 & 0xff) * 5, 4);
-            oq5[index_oq5] = (byte)round_power_of_two((p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) +
-                    (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) * 2 +
-                    (q6 & 0xff) + (q7 & 0xff) * 6, 4);
-            oq6[index_oq6] = (byte)round_power_of_two((p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) +
-                    (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) + (q6 & 0xff) * 2 +
-                    (q7 & 0xff) * 7, 4);
-        } else {
-            filter8(mask, thresh, flat, op3, index_op3, op2, index_op2, op1, index_op1, op0,
-                    index_op0, oq0, index_oq0, oq1, index_oq1, oq2, index_oq2, oq3, index_oq3);
-        }
-    }
-
-    private static void vp9_lpf_horizontal_16_c(byte[] s, int index, int p,
-                                                final byte[] blimit, final byte[] limit,
-                                                final byte[] thresh, int count) {
-
-        int i;
-        // loop filter designed to work using chars so that we can make maximum use
-        // of 8 bit simd instructions.
-        for (i = 0; i < 8 * count; ++i) {
-            final byte p3 = s[index - 4 * p], p2 = s[index - 3 * p], p1 = s[index - 2 * p],
-                    p0 = s[index - p];
-            final byte q0 = s[index + 0 * p], q1 = s[index + 1 * p], q2 = s[index + 2 * p],
-                    q3 = s[index + 3 * p];
-
-            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
-            final byte flat = flat_mask4((byte)1, p3, p2, p1, p0, q0, q1, q2, q3);
-            final byte flat2 = flat_mask5((byte)1, s[index - 8 * p], s[index - 7 * p],
-                    s[index - 6 * p], s[index - 5 * p], p0, q0, s[index + 4 * p], s[index + 5 * p],
-                    s[index + 6 * p], s[index + 7 * p]);
-
-            filter16(mask, thresh[0], flat, flat2, s, index - 8 * p, s, index - 7 * p, s,
-                    index - 6 * p, s, index - 5 * p, s, index - 4 * p, s, index - 3 * p, s,
-                    index - 2 * p, s, index - 1 * p, s, index, s, index + 1 * p, s, index + 2 * p,
-                    s, index + 3 * p, s, index + 4 * p, s, index + 5 * p, s, index + 6 * p,
-                    s, index + 7 * p);
-            ++index;
-        }
-    }
-
-    private static void mb_lpf_vertical_edge_w(byte[] s, int index, int p,
-                                               final byte[] blimit, final byte[] limit,
-                                               final byte[] thresh, int count) {
-
-        int i;
-        for (i = 0; i < count; ++i) {
-            final byte p3 = s[index - 4], p2 = s[index - 3], p1 = s[index - 2], p0 = s[index - 1];
-            final byte q0 = s[index + 0], q1 = s[index + 1], q2 = s[index + 2], q3 = s[index + 3];
-
-            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
-            final byte flat = flat_mask4((byte)1, p3, p2, p1, p0, q0, q1, q2, q3);
-            final byte flat2 = flat_mask5((byte)1, s[index - 8], s[index - 7], s[index - 6],
-                    s[index - 5], p0, q0, s[index + 4], s[index + 5], s[index + 6], s[index + 7]);
-
-            filter16(mask, thresh[0], flat, flat2, s, index - 8, s, index - 7, s, index - 6,
-                    s, index - 5, s, index - 4, s, index - 3, s, index - 2, s, index - 1,
-                    s, index, s, index + 1, s, index + 2, s, index + 3, s, index + 4, s, index + 5,
-                    s, index + 6, s, index + 7);
-            index += p;
-        }
-    }
-
-    private static void vp9_lpf_vertical_16_c(byte[] s, int index, int p, final byte[] blimit,
-                                              final byte[] limit, final byte[] thresh) {
-
-          mb_lpf_vertical_edge_w(s, index, p, blimit, limit, thresh, 8);
-    }
-
-    private static void vp9_lpf_vertical_16_dual_c(byte[] s, int index, int p, final byte[] blimit,
-                                                  final byte[] limit, final byte[] thresh) {
-
-        mb_lpf_vertical_edge_w(s, index, p, blimit, limit, thresh, 16);
-    }
-
-    private static void filter_selectively_vert_row2(boolean flags,
-                                                     byte[] s, int index, int pitch,
-                                                     int mask_16x16_l,
-                                                     int mask_8x8_l,
-                                                     int mask_4x4_l,
-                                                     int mask_4x4_int_l,
-                                                     final LoopFilterInfoN lfi_n,
-                                                     final byte[] lfl,
-                                                     int index_lfl) {
-
-        final int mask_shift = (flags) ? 4 : 8;
-        final int mask_cutoff = (flags) ? 0xf : 0xff;
-        final int lfl_forward = (flags) ? 4 : 8;
-
-        int mask_16x16_0 = mask_16x16_l & mask_cutoff;
-        int mask_8x8_0 = mask_8x8_l & mask_cutoff;
-        int mask_4x4_0 = mask_4x4_l & mask_cutoff;
-        int mask_4x4_int_0 = mask_4x4_int_l & mask_cutoff;
-        int mask_16x16_1 = (mask_16x16_l >>> mask_shift) & mask_cutoff;
-        int mask_8x8_1 = (mask_8x8_l >>> mask_shift) & mask_cutoff;
-        int mask_4x4_1 = (mask_4x4_l >>> mask_shift) & mask_cutoff;
-        int mask_4x4_int_1 = (mask_4x4_int_l >>> mask_shift) & mask_cutoff;
-        int mask;
-
-        for (mask = (mask_16x16_0 | mask_8x8_0 | mask_4x4_0 | mask_4x4_int_0 |
-             mask_16x16_1 | mask_8x8_1 | mask_4x4_1 | mask_4x4_int_1);
-             mask > 0; mask >>>= 1) {
-
-            if ((mask & 1) != 0) {
-                if (((mask_16x16_0 | mask_16x16_1) & 1) != 0) {
-                    if (((mask_16x16_0 & mask_16x16_1) & 1) != 0) {
-                        vp9_lpf_vertical_16_dual_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr);
-                    } else if ((mask_16x16_0 & 1) != 0) {
-                        vp9_lpf_vertical_16_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr);
-                    } else {
-                        vp9_lpf_vertical_16_c(s, index + 8 *pitch, pitch,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr);
-                    }
-                }
-
-                if (((mask_8x8_0 | mask_8x8_1) & 1) != 0) {
-                    if (((mask_8x8_0 & mask_8x8_1) & 1) != 0) {
-                        vp9_lpf_vertical_8_dual_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr);
-                    } else if ((mask_8x8_0 & 1) != 0) {
-                        vp9_lpf_vertical_8_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-                    } else {
-                        vp9_lpf_vertical_8_c(s, index + 8 * pitch, pitch,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr, 1);
-                    }
-                }
-
-                if (((mask_4x4_0 | mask_4x4_1) & 1) != 0) {
-                    if (((mask_4x4_0 & mask_4x4_1) & 1) != 0) {
-                        vp9_lpf_vertical_4_dual_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr);
-                    } else if ((mask_4x4_0 & 1) != 0) {
-                        vp9_lpf_vertical_4_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-                    } else {
-                        vp9_lpf_vertical_4_c(s, index + 8 * pitch, pitch,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr, 1);
-                    }
-                }
-
-                if (((mask_4x4_int_0 | mask_4x4_int_1) & 1) != 0) {
-                    if (((mask_4x4_int_0 & mask_4x4_int_1) & 1) != 0) {
-                        vp9_lpf_vertical_4_dual_c(s, index + 4, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr);
-                    } else if ((mask_4x4_int_0 & 1) != 0) {
-                        vp9_lpf_vertical_4_c(s, index + 4, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-                    } else {
-                        vp9_lpf_vertical_4_c(s, index + 8 * pitch + 4, pitch,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
-                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr, 1);
-                    }
-                }
-            }
-
-            index += 8;
-            index_lfl += 1;
-            mask_16x16_0 >>>= 1;
-            mask_8x8_0 >>>= 1;
-            mask_4x4_0 >>>= 1;
-            mask_4x4_int_0 >>>= 1;
-            mask_16x16_1 >>>= 1;
-            mask_8x8_1 >>>= 1;
-            mask_4x4_1 >>>= 1;
-            mask_4x4_int_1 >>>= 1;
-        }
-    }
-
-    private static void filter_selectively_horiz(byte[] s, int index, int pitch,
-                                                 int mask_16x16,
-                                                 int mask_8x8,
-                                                 int mask_4x4,
-                                                 int mask_4x4_int,
-                                                 final LoopFilterInfoN lfi_n,
-                                                 final byte[] lfl,
-                                                 int index_lfl) {
-
-        int mask;
-        int count;
-
-        for (mask = (mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int); mask != 0;
-                mask >>>= count) {
-
-            count = 1;
-            if ((mask & 1) != 0) {
-                if ((mask_16x16 & 1) != 0) {
-                    if ((mask_16x16 & 3) == 3) {
-                        vp9_lpf_horizontal_16_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 2);
-                        count = 2;
-                    } else {
-                        vp9_lpf_horizontal_16_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-                    }
-                } else if ((mask_8x8 & 1) != 0) {
-                    if ((mask_8x8 & 3) == 3) {
-                        vp9_lpf_horizontal_8_dual_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
-                                lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl + 1]].lim,
-                                lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr);
-
-                        if ((mask_4x4_int & 3) == 3) {
-                            vp9_lpf_horizontal_4_dual_c(s, index + 4 * pitch, pitch,
-                                    lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                    lfi_n.lfthr[lfl[index_lfl]].lim,
-                                    lfi_n.lfthr[lfl[index_lfl]].hev_thr,
-                                    lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
-                                    lfi_n.lfthr[lfl[index_lfl + 1]].lim,
-                                    lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr);
-                        } else {
-                            if ((mask_4x4_int & 1) != 0)
-                                vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
-                                        lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                        lfi_n.lfthr[lfl[index_lfl]].lim,
-                                        lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-                            else if ((mask_4x4_int & 2) != 0)
-                                vp9_lpf_horizontal_4_c(s, index + 8 + 4 * pitch, pitch,
-                                        lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
-                                        lfi_n.lfthr[lfl[index_lfl + 1]].lim,
-                                        lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr, 1);
-                        }
-                        count = 2;
-                    } else {
-                        vp9_lpf_horizontal_8_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-
-                        if ((mask_4x4_int & 1) != 0)
-                            vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
-                                    lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                    lfi_n.lfthr[lfl[index_lfl]].lim,
-                                    lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-                    }
-                } else if ((mask_4x4 & 1) != 0) {
-                    if ((mask_4x4 & 3) == 3) {
-
-                        vp9_lpf_horizontal_4_dual_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
-                                lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl + 1]].lim,
-                                lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr);
-                        if ((mask_4x4_int & 3) == 3) {
-                            vp9_lpf_horizontal_4_dual_c(s, index + 4 * pitch, pitch,
-                                    lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                    lfi_n.lfthr[lfl[index_lfl]].lim,
-                                    lfi_n.lfthr[lfl[index_lfl]].hev_thr,
-                                    lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
-                                    lfi_n.lfthr[lfl[index_lfl + 1]].lim,
-                                    lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr);
-                        } else {
-                            if ((mask_4x4_int & 1) != 0)
-                                vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
-                                        lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                        lfi_n.lfthr[lfl[index_lfl]].lim,
-                                        lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-                            else if ((mask_4x4_int & 2) != 0)
-                                vp9_lpf_horizontal_4_c(s, index + 8 + 4 * pitch, pitch,
-                                        lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
-                                        lfi_n.lfthr[lfl[index_lfl + 1]].lim,
-                                        lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr, 1);
-                        }
-                        count = 2;
-                    } else {
-                        vp9_lpf_horizontal_4_c(s, index, pitch,
-                                lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                lfi_n.lfthr[lfl[index_lfl]].lim,
-                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-
-                        if ((mask_4x4_int & 1) != 0)
-                            vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
-                                    lfi_n.lfthr[lfl[index_lfl]].mblim,
-                                    lfi_n.lfthr[lfl[index_lfl]].lim,
-                                    lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-                    }
-                } else if ((mask_4x4_int & 1) != 0) {
-                    vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
-                            lfi_n.lfthr[lfl[index_lfl]].mblim,
-                            lfi_n.lfthr[lfl[index_lfl]].lim,
-                            lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
-                }
-            }
-
-            index += 8 * count;
-            index_lfl += count;
-            mask_16x16 >>>= count;
-            mask_8x8 >>>= count;
-            mask_4x4 >>>= count;
-            mask_4x4_int >>>= count;
-        }
-    }
-
-    private static void filter_block_plane_y(LoopFilterInfoN lf_info,
-                                             LoopFilterMask lfm,
-                                             int stride,
-                                             byte[] buf,
-                                             int index,
-                                             int mi_rows,
-                                             int mi_row) {
-
-        int r;
-
-        int tmp_index = index;
-        long mask_16x16 = lfm.left_y[2];
-        long mask_8x8 = lfm.left_y[1];
-        long mask_4x4 = lfm.left_y[0];
-        long mask_4x4_int = lfm.int_4x4_y;
-
-        // Vertical pass: do 2 rows at one time
-        for (r = 0; (r < MI_BLOCK_SIZE) && (mi_row + r < mi_rows); r += 2) {
-            int mask_16x16_l = (int)(mask_16x16 & 0xffff);
-            int mask_8x8_l = (int)(mask_8x8 & 0xffff);
-            int mask_4x4_l = (int)(mask_4x4 & 0xffff);
-            int mask_4x4_int_l = (int)(mask_4x4_int & 0xffff);
-
-            // Disable filtering on the leftmost column
-            filter_selectively_vert_row2(false, buf, index, stride,
-                    mask_16x16_l, mask_8x8_l, mask_4x4_l, mask_4x4_int_l, lf_info,
-                    lfm.lfl_y, r << 3);
-
-            index += 16 * stride;
-            mask_16x16 >>>= 16;
-            mask_8x8 >>>= 16;
-            mask_4x4 >>>= 16;
-            mask_4x4_int >>>= 16;
-        }
-
-
-        // Horizontal pass
-        index = tmp_index;
-        mask_16x16 = lfm.above_y[2];
-        mask_8x8 = lfm.above_y[1];
-        mask_4x4 = lfm.above_y[0];
-        mask_4x4_int = lfm.int_4x4_y;
-
-        for (r = 0; (r < MI_BLOCK_SIZE) && (mi_row + r < mi_rows); r++) {
-            int mask_16x16_r;
-            int mask_8x8_r;
-            int mask_4x4_r;
-
-            if (mi_row + r == 0) {
-                mask_16x16_r = 0;
-                mask_8x8_r = 0;
-                mask_4x4_r = 0;
-            } else {
-                mask_16x16_r = (int)(mask_16x16 & 0xff);
-                mask_8x8_r = (int)(mask_8x8 & 0xff);
-                mask_4x4_r = (int)(mask_4x4 & 0xff);
-            }
-
-            filter_selectively_horiz(buf, index, stride, mask_16x16_r, mask_8x8_r,
-                    mask_4x4_r, (int)(mask_4x4_int & 0xff), lf_info, lfm.lfl_y, r << 3);
-
-            index += 8 * stride;
-            mask_16x16 >>>= 8;
-            mask_8x8 >>>= 8;
-            mask_4x4 >>>= 8;
-            mask_4x4_int >>>= 8;
-        }
-    }
-
-    private static void filter_block_plane_uv(LoopFilterInfoN lf_info,
-                                              LoopFilterMask lfm,
-                                              int stride,
-                                              byte[] buf,
-                                              int index,
-                                              int mi_rows,
-                                              int mi_row) {
-
-        int r, c;
-
-        int tmp_index = index;
-        short mask_16x16 = lfm.left_uv[2];
-        short mask_8x8 = lfm.left_uv[1];
-        short mask_4x4 = lfm.left_uv[0];
-        short mask_4x4_int = lfm.int_4x4_uv;
-
-        // Vertical pass: do 2 rows at one time
-        for (r = 0; (r < MI_BLOCK_SIZE) && (mi_row + r < mi_rows); r += 4) {
-
-            for (c = 0; c < (MI_BLOCK_SIZE >> 1); c++) {
-                lfm.lfl_uv[(r << 1) + c] = lfm.lfl_y[(r << 3) + (c << 1)];
-                lfm.lfl_uv[((r + 2) << 1) + c] = lfm.lfl_y[((r + 2) << 3) + (c << 1)];
-            }
-
-            {
-                int mask_16x16_l = mask_16x16 & 0xff;
-                int mask_8x8_l = mask_8x8 & 0xff;
-                int mask_4x4_l = mask_4x4 & 0xff;
-                int mask_4x4_int_l = mask_4x4_int & 0xff;
-
-                // Disable filtering on the leftmost column
-                filter_selectively_vert_row2(true, buf, index, stride,
-                        mask_16x16_l, mask_8x8_l, mask_4x4_l, mask_4x4_int_l, lf_info,
-                        lfm.lfl_uv, r << 1);
-
-                index += 16 * stride;
-                mask_16x16 >>>= 8;
-                mask_8x8 >>>= 8;
-                mask_4x4 >>>= 8;
-                mask_4x4_int >>>= 8;
-            }
-        }
-
-        // Horizontal pass
-        index = tmp_index;
-        mask_16x16 = lfm.above_uv[2];
-        mask_8x8 = lfm.above_uv[1];
-        mask_4x4 = lfm.above_uv[0];
-        mask_4x4_int = lfm.int_4x4_uv;
-
-        for (r = 0; (r < MI_BLOCK_SIZE) && (mi_row + r < mi_rows); r += 2) {
-            int skip_border_4x4_r;
-            if (mi_row + r == mi_rows - 1) {
-                skip_border_4x4_r = 1;
-            } else {
-                skip_border_4x4_r = 0;
-            }
-
-            int mask_4x4_int_r;
-            if (skip_border_4x4_r != 0) {
-                mask_4x4_int_r = 0;
-            } else {
-                mask_4x4_int_r = mask_4x4_int & 0xf;
-            }
-
-            int mask_16x16_r;
-            int mask_8x8_r;
-            int mask_4x4_r;
-
-            if (mi_row + r == 0) {
-                mask_16x16_r = 0;
-                mask_8x8_r = 0;
-                mask_4x4_r = 0;
-            } else {
-                mask_16x16_r = mask_16x16 & 0xf;
-                mask_8x8_r = mask_8x8 & 0xf;
-                mask_4x4_r = mask_4x4 & 0xf;
-            }
-
-            filter_selectively_horiz(buf, index, stride, mask_16x16_r, mask_8x8_r, mask_4x4_r,
-                    mask_4x4_int_r, lf_info, lfm.lfl_uv, r << 1);
-
-            index += 8 * stride;
-            mask_16x16 >>>= 4;
-            mask_8x8 >>>= 4;
-            mask_4x4 >>>= 4;
-            mask_4x4_int >>>= 4;
-        }
-    }
-
-    private void vp9_loop_filter_rows_work_proc(int start, int stop, int num_planes,
-                                                int mi_rows, int mi_cols,
-                                                BufferInfo buf_info,
-                                                byte[] buffer_alloc,
-                                                LoopFilterInfoN lf_info,
-                                                LoopFilterMask[] lfms) {
-
-        int mi_row, mi_col;
-        int lfm_idx;
-        int index_start0;
-        int index_start1;
-        int index_start2;
-        int index_buf0;
-        int index_buf1;
-        int index_buf2;
-
-        index_start0 = buf_info.y_offset;
-        index_start1 = buf_info.u_offset;
-        index_start2 = buf_info.v_offset;
-
-        for (mi_row = start; mi_row < stop; mi_row += MI_BLOCK_SIZE) {
-            index_buf0 = index_start0 + (mi_row * buf_info.y_stride << 3);
-            index_buf1 = index_start1 + (mi_row * buf_info.uv_stride << 2);
-            index_buf2 = index_start2 + (mi_row * buf_info.uv_stride << 2);
-
-            for (mi_col = 0; mi_col < mi_cols; mi_col += MI_BLOCK_SIZE) {
-                lfm_idx = ((mi_row + 7) >> 3) * ((mi_cols + 7) >> 3) + ((mi_col + 7) >> 3);
-                filter_block_plane_y(lf_info, lfms[lfm_idx], buf_info.y_stride, buffer_alloc,
-                        index_buf0, mi_rows, mi_row);
-                index_buf0 += MI_BLOCK_SIZE * MI_BLOCK_SIZE;
-
-                if (num_planes > 1) {
-                    filter_block_plane_uv(lf_info, lfms[lfm_idx], buf_info.uv_stride, buffer_alloc,
-                            index_buf1, mi_rows, mi_row);
-                    filter_block_plane_uv(lf_info, lfms[lfm_idx], buf_info.uv_stride, buffer_alloc,
-                            index_buf2, mi_rows, mi_row);
-                    index_buf1 += MI_BLOCK_SIZE * MI_BLOCK_SIZE >> 1;
-                    index_buf2 += MI_BLOCK_SIZE * MI_BLOCK_SIZE >> 1;
-                }
-            }
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index 6a7833d..10ad5f8 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -40,7 +40,7 @@
 include $(BUILD_CTS_PACKAGE)
 
 selinux_policy.xml := $(sepolicy_asset_dir)/selinux_policy.xml
-selinux_policy_parser := packages/experimental/SELinux/CTS/src/gen_SELinux_CTS.py
+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)
diff --git a/tools/selinux/src/SELinux_CTS.py b/tools/selinux/src/SELinux_CTS.py
new file mode 100644
index 0000000..ec12be0
--- /dev/null
+++ b/tools/selinux/src/SELinux_CTS.py
@@ -0,0 +1,542 @@
+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
new file mode 100644
index 0000000..aeef5f8
--- /dev/null
+++ b/tools/selinux/src/example_input_policy.conf
@@ -0,0 +1,9850 @@
+#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
new file mode 100755
index 0000000..85d49a8
--- /dev/null
+++ b/tools/selinux/src/gen_SELinux_CTS.py
@@ -0,0 +1,58 @@
+#!/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
new file mode 100644
index 0000000..074a63b
--- /dev/null
+++ b/tools/selinux/test/policy_clean_test.conf
@@ -0,0 +1,2230 @@
+#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
new file mode 100644
index 0000000..d0962cd
--- /dev/null
+++ b/tools/selinux/test/policy_test.conf
@@ -0,0 +1,2244 @@
+#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
new file mode 100755
index 0000000..bc424e9
--- /dev/null
+++ b/tools/selinux/test/testrunner.py
@@ -0,0 +1,442 @@
+#!/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()
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index a91fdca..6d617ea 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -663,20 +663,7 @@
             }
         } else if (mClassName != null) {
             Log.i(LOG_TAG, String.format("Executing CTS test class %s", mClassName));
-            // try to find packages to run from class name
-            List<String> packageIds = testRepo.findPackageIdsForTest(mClassName);
-            if (!packageIds.isEmpty()) {
-                for (String packageId: packageIds) {
-                    ITestPackageDef testPackageDef = testRepo.getTestPackage(packageId);
-                    if (testPackageDef != null) {
-                        testPackageDef.setClassName(mClassName, mMethodName);
-                        testPkgDefs.add(testPackageDef);
-                    }
-                }
-            } else {
-                Log.logAndDisplay(LogLevel.WARN, LOG_TAG, String.format(
-                        "Could not find package for test class %s", mClassName));
-            }
+            testPkgDefs.addAll(buildTestPackageDefSet(testRepo, mClassName, mMethodName));
         } else if (mTestName != null) {
             Log.i(LOG_TAG, String.format("Executing CTS test %s", mTestName));
             String [] split = mTestName.split("#");
@@ -686,20 +673,7 @@
             } else {
                 String className = split[0];
                 String methodName = split[1];
-                // try to find packages to run from class name
-                List<String> packageIds = testRepo.findPackageIdsForTest(className);
-                if (!packageIds.isEmpty()) {
-                    for (String packageId: packageIds) {
-                        ITestPackageDef testPackageDef = testRepo.getTestPackage(packageId);
-                        if (testPackageDef != null) {
-                            testPackageDef.setClassName(className, methodName);
-                            testPkgDefs.add(testPackageDef);
-                        }
-                    }
-                } else {
-                    Log.logAndDisplay(LogLevel.WARN, LOG_TAG, String.format(
-                            "Could not find package for test class %s", mTestName));
-                }
+                testPkgDefs.addAll(buildTestPackageDefSet(testRepo, className, methodName));
             }
         } else if (mContinueSessionId != null) {
             // create an in-memory derived plan that contains the notExecuted tests from previous
@@ -740,6 +714,29 @@
     }
 
     /**
+     * @return a {@link Set} containing {@ITestPackageDef}s pertaining to the given
+     *     {@code className} and {@code methodName}.
+     */
+    private static Set<ITestPackageDef> buildTestPackageDefSet(
+            ITestPackageRepo testRepo, String className, String methodName) {
+        Set<ITestPackageDef> testPkgDefs = new LinkedHashSet<ITestPackageDef>();
+        // try to find packages to run from class name
+        List<String> packageIds = testRepo.findPackageIdsForTest(className);
+        if (packageIds.isEmpty()) {
+            Log.logAndDisplay(LogLevel.WARN, LOG_TAG, String.format(
+                    "Could not find package for test class %s", className));
+        }
+        for (String packageId: packageIds) {
+            ITestPackageDef testPackageDef = testRepo.getTestPackage(packageId);
+            if (testPackageDef != null) {
+                testPackageDef.setClassName(className, methodName);
+                testPkgDefs.add(testPackageDef);
+            }
+        }
+        return testPkgDefs;
+    }
+
+    /**
      * Return the list of unique prerequisite apks to install
      * @param testPackages
      */
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
index a981d96..db1b2dd 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
@@ -389,11 +389,13 @@
 
         String instrumentationName =
                 "com.drawelements.deqp/com.drawelements.deqp.testercore.DeqpInstrumentation";
-        // TODO run the test with the given ABI
-        String command = "am instrument -w -e deqpLogFileName \"" + logFileName
-                + "\" -e deqpCmdLine \"--deqp-caselist-file=" + caseListFileName + " "
-                + "--deqp-gl-config-name=rgba8888d24s8\" "
-                + (mLogData ? "-e deqpLogData \"true\" " : "") + instrumentationName;
+
+        String command = String.format(
+                "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
+                    + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\""
+                    + " -e deqpLogData \"%s\" %s",
+                AbiUtils.createAbiFlag(mAbi.getName()), logFileName, caseListFileName, mLogData,
+                instrumentationName);
 
         mDevice.executeShellCommand(command, parser);
         parser.flush();
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
index 1a92a39..cd9c738 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
@@ -127,10 +127,12 @@
             EasyMock.expect(mockDevice.pushString(testTrie + "\n", CASE_LIST_FILE_NAME))
                     .andReturn(true).once();
 
-            String command = "am instrument -w -e deqpLogFileName \"" + LOG_FILE_NAME
-                    + "\" -e deqpCmdLine \"--deqp-caselist-file=" + CASE_LIST_FILE_NAME + " "
-                    + "--deqp-gl-config-name=rgba8888d24s8\" "
-                    + INSTRUMENTATION_NAME;
+            String command = String.format(
+                    "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
+                        + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\""
+                        + "-e deqpLogData \"%s\" %s",
+                    AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
+                    CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
 
             mockDevice.executeShellCommand(EasyMock.eq(command),
                     EasyMock.<IShellOutputReceiver>notNull());
@@ -230,10 +232,12 @@
         EasyMock.expect(mockDevice.pushString(testTrie + "\n", CASE_LIST_FILE_NAME)).andReturn(true)
                 .once();
 
-        String command = "am instrument -w -e deqpLogFileName \"" + LOG_FILE_NAME
-                + "\" -e deqpCmdLine \"--deqp-caselist-file=" + CASE_LIST_FILE_NAME + " "
-                + "--deqp-gl-config-name=rgba8888d24s8\" "
-                + INSTRUMENTATION_NAME;
+        String command = String.format(
+                "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
+                    + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\""
+                    + "-e deqpLogData \"%s\" %s",
+                AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
+                CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
 
         mockDevice.executeShellCommand(EasyMock.eq(command),
                 EasyMock.<IShellOutputReceiver>notNull());
@@ -403,10 +407,12 @@
         EasyMock.expect(mockDevice.pushString(testTrie + "\n", CASE_LIST_FILE_NAME))
                 .andReturn(true).once();
 
-        String command = "am instrument -w -e deqpLogFileName \"" + LOG_FILE_NAME
-                + "\" -e deqpCmdLine \"--deqp-caselist-file=" + CASE_LIST_FILE_NAME + " "
-                + "--deqp-gl-config-name=rgba8888d24s8\" "
-                + INSTRUMENTATION_NAME;
+        String command = String.format(
+                "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
+                    + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\""
+                    + "-e deqpLogData \"%s\" %s",
+                AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
+                CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
 
         mockDevice.executeShellCommand(EasyMock.eq(command),
                 EasyMock.<IShellOutputReceiver>notNull());