Merge "Revert "Camera: Fix preCorrectionActiveArraySize check""
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
index f666d92..7732437 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
@@ -47,9 +47,14 @@
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     androidx.legacy_legacy-support-v4
 
-LOCAL_MIN_SDK_VERSION := 20
+LOCAL_MIN_SDK_VERSION := 21
 
 # tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := arcts cts vts general-tests
 
+# Code coverage puts us over the dex limit, so enable multi-dex for coverage-enabled builds
+ifeq (true,$(EMMA_INSTRUMENT))
+LOCAL_DX_FLAGS := --multi-dex
+endif # EMMA_INSTRUMENT
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/accessibilityservice/AndroidManifest.xml b/tests/accessibilityservice/AndroidManifest.xml
index 5214410..029dc51 100644
--- a/tests/accessibilityservice/AndroidManifest.xml
+++ b/tests/accessibilityservice/AndroidManifest.xml
@@ -30,38 +30,38 @@
         <activity
             android:label="@string/accessibility_end_to_end_test_activity"
             android:name=".activities.AccessibilityEndToEndActivity"
-            android:screenOrientation="portrait"/>
+            android:screenOrientation="locked"/>
 
         <activity
             android:label="@string/accessibility_query_window_test_activity"
             android:name=".activities.AccessibilityWindowQueryActivity"
             android:supportsPictureInPicture="true"
-            android:screenOrientation="portrait"/>
+            android:screenOrientation="locked"/>
 
         <activity
             android:label="@string/accessibility_view_tree_reporting_test_activity"
             android:name=".activities.AccessibilityViewTreeReportingActivity"
-            android:screenOrientation="portrait"/>
+            android:screenOrientation="locked"/>
 
         <activity
             android:label="@string/accessibility_focus_and_input_focus_sync_test_activity"
             android:name=".activities.AccessibilityFocusAndInputFocusSyncActivity"
-            android:screenOrientation="portrait"/>
+            android:screenOrientation="locked"/>
 
         <activity
             android:label="@string/accessibility_text_traversal_test_activity"
             android:name=".activities.AccessibilityTextTraversalActivity"
-            android:screenOrientation="portrait"/>
+            android:screenOrientation="locked"/>
 
         <activity android:label="Activity for testing window accessibility reporting"
              android:name=".activities.AccessibilityWindowReportingActivity"
              android:supportsPictureInPicture="true"
-             android:screenOrientation="portrait"/>
+             android:screenOrientation="locked"/>
 
         <activity
             android:label="Full screen activity for gesture dispatch testing"
             android:name=".AccessibilityGestureDispatchTest$GestureDispatchActivity"
-            android:screenOrientation="portrait" />
+            android:screenOrientation="locked" />
 
         <activity
             android:label="@string/accessibility_soft_keyboard_modes_activity"
diff --git a/tests/app/AndroidTest.xml b/tests/app/AndroidTest.xml
index 790a9ec..d90edad 100644
--- a/tests/app/AndroidTest.xml
+++ b/tests/app/AndroidTest.xml
@@ -20,8 +20,8 @@
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsSimpleApp.apk" />
-	<option name="test-file-name" value="CtsAppTestStubs.apk" />
-	<option name="test-file-name" value="CtsAppTestStubsApp1.apk" />
+        <option name="test-file-name" value="CtsAppTestStubs.apk" />
+        <option name="test-file-name" value="CtsAppTestStubsApp1.apk" />
         <option name="test-file-name" value="CtsAppTestStubsApp3.apk" />
         <option name="test-file-name" value="CtsAppTestStubsApp2.apk" />
         <option name="test-file-name" value="CtsAppTestCases.apk" />
@@ -29,6 +29,7 @@
         <option name="test-file-name" value="CtsCantSaveState2.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
         <option name="package" value="android.app.cts" />
         <option name="runtime-hint" value="6m38s" />
         <option name="hidden-api-checks" value="false"/>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
index b4d87b9..f38ccbc 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
@@ -1075,6 +1075,7 @@
 
         // Trigger autofill.
         mActivity.syncRunOnUiThread(() -> mActivity.mInput.requestFocus());
+        sReplier.getNextFillRequest();
 
         mActivity.syncRunOnUiThread(() -> {
             mActivity.mInput.setText("id");
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
index e2c0ede..00dcc2b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
@@ -713,15 +713,15 @@
         InstrumentationRegistry.getTargetContext().startActivity(intent);
 
         // Wait for the activity to resume again
-        final List<LifecycleLog.ActivityCallback> expectedSequence =
-                Arrays.asList(ON_NEW_INTENT, ON_RESUME);
-        waitForActivityTransitions(SingleTopActivity.class, expectedSequence);
-
-        // Verify that the new intent was delivered and resumed again
         // TODO(b/77974794): New intent handling sequence should always be the same.
         // It is possible to get an extra pause and resume now.
         final List<LifecycleLog.ActivityCallback> extraPauseSequence =
                 Arrays.asList(ON_NEW_INTENT, ON_RESUME, ON_PAUSE, ON_RESUME);
+        waitForActivityTransitions(SingleTopActivity.class, extraPauseSequence);
+
+        // Verify that the new intent was delivered and resumed again
+        final List<LifecycleLog.ActivityCallback> expectedSequence =
+                Arrays.asList(ON_NEW_INTENT, ON_RESUME);
         LifecycleVerifier.assertSequenceMatchesOneOf(SingleTopActivity.class, getLifecycleLog(),
                 Arrays.asList(expectedSequence, extraPauseSequence), "newIntent");
     }
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index fa1af95..8ab05e0 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -768,7 +768,15 @@
 
             // Dismiss active keyguard after credential is cleared, so keyguard doesn't ask for
             // the stale credential.
+            // TODO (b/112015010) If keyguard is occluded, credential cannot be removed as expected.
+            // LockScreenSession#close is always calls before stop all test activities,
+            // which could cause keyguard stay at occluded after wakeup.
+            // If Keyguard is occluded, press back key can close ShowWhenLocked activity.
             pressBackButton();
+
+            // If device is unlocked, there might have ShowWhenLocked activity runs on,
+            // use home key to clear all activity at foreground.
+            pressHomeButton();
             sleepDevice();
             wakeUpDevice();
             unlockDevice();
diff --git a/tests/tests/graphics/src/android/graphics/fonts/FontFamilyTest.java b/tests/tests/graphics/src/android/graphics/fonts/FontFamilyTest.java
new file mode 100644
index 0000000..8f8b70f
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/fonts/FontFamilyTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2018 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.graphics.fonts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import android.content.res.AssetManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class FontFamilyTest {
+    private static final String TAG = "FontFamilyTest";
+    private static final String FONT_DIR = "fonts_for_family_selection/fonts/";
+
+    @Test
+    public void testBuilder_SingleFont() throws IOException {
+        AssetManager am = InstrumentationRegistry.getTargetContext().getAssets();
+        Font font = new Font.Builder(am, FONT_DIR + "ascii_g3em_weight400_upright.ttf").build();
+        FontFamily family = new FontFamily.Builder(font).build();
+        assertNotNull(family);
+        assertEquals(1, family.getFontCount());
+        assertSame(font, family.getFont(0));
+    }
+
+    @Test
+    public void testBuilder_MultipleFont() throws IOException {
+        AssetManager am = InstrumentationRegistry.getTargetContext().getAssets();
+        Font regularFont = new Font.Builder(
+                am, FONT_DIR + "ascii_g3em_weight400_upright.ttf").build();
+        Font boldFont = new Font.Builder(
+                am, FONT_DIR + "ascii_m3em_weight700_upright.ttf").build();
+        FontFamily family = new FontFamily.Builder(regularFont).addFont(boldFont).build();
+        assertNotNull(family);
+        assertEquals(2, family.getFontCount());
+        assertNotSame(family.getFont(0), family.getFont(1));
+        assertTrue(family.getFont(0) == regularFont || family.getFont(0) == boldFont);
+        assertTrue(family.getFont(1) == regularFont || family.getFont(1) == boldFont);
+    }
+
+    @Test
+    public void testBuilder_MultipleFont_overrideWeight() throws IOException {
+        AssetManager am = InstrumentationRegistry.getTargetContext().getAssets();
+        Font regularFont = new Font.Builder(
+                am, FONT_DIR + "ascii_g3em_weight400_upright.ttf").build();
+        Font boldFont = new Font.Builder(am, FONT_DIR + "ascii_g3em_weight400_upright.ttf")
+                .setWeight(700).build();
+        FontFamily family = new FontFamily.Builder(regularFont).addFont(boldFont).build();
+        assertNotNull(family);
+        assertEquals(2, family.getFontCount());
+        assertNotSame(family.getFont(0), family.getFont(1));
+        assertTrue(family.getFont(0) == regularFont || family.getFont(0) == boldFont);
+        assertTrue(family.getFont(1) == regularFont || family.getFont(1) == boldFont);
+    }
+
+    @Test
+    public void testBuilder_MultipleFont_overrideItalic() throws IOException {
+        AssetManager am = InstrumentationRegistry.getTargetContext().getAssets();
+        Font regularFont = new Font.Builder(
+                am, FONT_DIR + "ascii_g3em_weight400_upright.ttf").build();
+        Font italicFont = new Font.Builder(am, FONT_DIR + "ascii_g3em_weight400_upright.ttf")
+                .setItalic(true).build();
+        FontFamily family = new FontFamily.Builder(regularFont).addFont(italicFont).build();
+        assertNotNull(family);
+        assertEquals(2, family.getFontCount());
+        assertNotSame(family.getFont(0), family.getFont(1));
+        assertTrue(family.getFont(0) == regularFont || family.getFont(0) == italicFont);
+        assertTrue(family.getFont(1) == regularFont || family.getFont(1) == italicFont);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuilder_MultipleFont_SameStyle() throws IOException {
+        AssetManager am = InstrumentationRegistry.getTargetContext().getAssets();
+        Font regularFont = new Font.Builder(
+                am, FONT_DIR + "ascii_g3em_weight400_upright.ttf").build();
+        Font regularFont2 = new Font.Builder(
+                am, FONT_DIR + "ascii_g3em_weight400_upright.ttf").build();
+        new FontFamily.Builder(regularFont).addFont(regularFont2).build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuilder_MultipleFont_SameStyle_overrideWeight() throws IOException {
+        AssetManager am = InstrumentationRegistry.getTargetContext().getAssets();
+        Font regularFont = new Font.Builder(
+                am, FONT_DIR + "ascii_g3em_weight400_upright.ttf").build();
+        Font regularFont2 = new Font.Builder(am, FONT_DIR + "ascii_m3em_weight700_upright.ttf")
+                .setWeight(400).build();
+        new FontFamily.Builder(regularFont).addFont(regularFont2).build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuilder_MultipleFont_SameStyle_overrideItalic() throws IOException {
+        AssetManager am = InstrumentationRegistry.getTargetContext().getAssets();
+        Font regularFont = new Font.Builder(
+                am, FONT_DIR + "ascii_g3em_weight400_upright.ttf").build();
+        Font regularFont2 = new Font.Builder(am, FONT_DIR + "ascii_h3em_weight400_italic.ttf")
+                .setItalic(false).build();
+        new FontFamily.Builder(regularFont).addFont(regularFont2).build();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index 3b28ad4..80e28d1 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -732,7 +732,7 @@
                 assertThat("TEE attestation can only come from TEE keymaster",
                         attestation.getKeymasterSecurityLevel(),
                         is(KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT));
-                assertThat(attestation.getKeymasterVersion(), either(is(2)).or(is(3)));
+                assertThat(attestation.getKeymasterVersion(), either(is(2)).or(is(3)).or(is(4)));
 
                 checkRootOfTrust(attestation);
                 assertThat(teeEnforced.getOsVersion(), is(systemOsVersion));
diff --git a/tests/tests/keystore/src/android/server/am/ActivityManagerTestBase.java b/tests/tests/keystore/src/android/server/am/ActivityManagerTestBase.java
index 8e419a4..6db2f09 100644
--- a/tests/tests/keystore/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/tests/keystore/src/android/server/am/ActivityManagerTestBase.java
@@ -33,6 +33,7 @@
 import static android.server.am.UiDeviceUtils.pressWakeupButton;
 import static android.server.am.UiDeviceUtils.waitForDeviceIdle;
 
+import android.accessibilityservice.AccessibilityService;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.content.ComponentName;
@@ -300,6 +301,11 @@
 
         public LockScreenSession sleepDevice() {
             pressSleepButton();
+            // Not all device variants lock when we go to sleep, so we need to explicitly lock the
+            // device. Note that pressSleepButton() above is redundant because the action also
+            // puts the device to sleep, but kept around for clarity.
+            InstrumentationRegistry.getInstrumentation().getUiAutomation().performGlobalAction(
+                    AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN);
             waitForDisplayStateWithRetry(false /* displayOn */ );
             return this;
         }
diff --git a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
index 8bd05fe..aa66b9a 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
@@ -273,6 +273,7 @@
 enum GoldenColor {
     kZero,  // all zero, i.e., transparent black
     kBlack,  // opaque black
+    kWhite,  // opaque white
     kRed,  // opaque red
     kGreen,  // opaque green
     kBlue,  // opaque blue
@@ -332,6 +333,7 @@
         case kGreen: golden_pixel[1] = 255; break;
         case kBlue: golden_pixel[2] = 255; break;
         case kZero: if (FormatHasAlpha(format)) golden_pixel[3] = 0; break;
+        case kWhite: golden_pixel[0] = 255; golden_pixel[1] = 255; golden_pixel[2] = 255; break;
         case kBlack: break;
         default: FAIL() << "Unrecognized golden pixel color";
     }
@@ -367,6 +369,7 @@
         case kGreen: golden_pixel[1] = 1.f; break;
         case kBlue: golden_pixel[2] = 1.f; break;
         case kZero: golden_pixel[3] = 0.f; break;
+        case kWhite: golden_pixel[0] = 1.f; golden_pixel[1] = 1.f; golden_pixel[2] = 1.f; break;
         case kBlack: break;
         default: FAIL() << "Unrecognized golden pixel color";
     }
@@ -692,6 +695,7 @@
     GLuint mTextures[2] = { 0, 0 };
     GLuint mBufferObjects[2] = { 0, 0 };
     GLuint mFramebuffers[2] = { 0, 0 };
+    GLint mMaxTextureUnits = 0;
 };
 
 void AHardwareBufferGLTest::SetUp() {
@@ -758,6 +762,7 @@
     ASSERT_TRUE(dot_pos > 0 && dot_pos < version.size() - 1);
     mGLVersion = (version[dot_pos - 1] - '0') * 10 + (version[dot_pos + 1] - '0');
     ASSERT_GE(mGLVersion, 20);
+    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxTextureUnits);
 }
 
 bool AHardwareBufferGLTest::SetUpBuffer(const AHardwareBuffer_Desc& desc) {
@@ -785,9 +790,17 @@
             mTexTarget = GL_TEXTURE_2D;
         }
     }
-    if (desc.format == GL_SRGB8_ALPHA8 && mGLVersion < 30) {
-        ALOGI("Test skipped: GL_SRGB8_ALPHA8 requires GL ES 3.0, found %d.%d",
-              mGLVersion / 10, mGLVersion % 10);
+    if ((desc.format == GL_RGB8 || desc.format == GL_RGBA8) &&
+        (desc.usage & AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT) &&
+        mGLVersion < 30 && !HasGLExtension("GL_OES_rgb8_rgba8")) {
+        ALOGI("Test skipped: GL_RGB8/GL_RGBA8 renderbuffers require GL ES 3.0 or "
+              "GL_OES_rgb8_rgba8, but neither were found.");
+        return false;
+    }
+    if (desc.format == GL_SRGB8_ALPHA8 && mGLVersion < 30 &&
+        !HasGLExtension("GL_EXT_sRGB")) {
+        ALOGI("Test skipped: GL_SRGB8_ALPHA8 requires GL ES 3.0 or GL_EXT_sRGB, "
+              "but neither were found.");
         return false;
     }
     if (desc.format == GL_RGB10_A2 && mGLVersion < 30) {
@@ -800,6 +813,20 @@
               mGLVersion / 10, mGLVersion % 10);
         return false;
     }
+    if (desc.format == GL_DEPTH_COMPONENT16 &&
+        (desc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) &&
+        mGLVersion < 30 && !HasGLExtension("GL_OES_depth_texture")) {
+        ALOGI("Test skipped: depth textures require GL ES 3.0 or "
+              "GL_OES_depth_texture, but neither were found.");
+        return false;
+    }
+    if (desc.format == GL_DEPTH24_STENCIL8 &&
+        (desc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) &&
+        mGLVersion < 30 && !HasGLExtension("GL_OES_packed_depth_stencil")) {
+        ALOGI("Test skipped: depth-stencil textures require GL ES 3.0 or "
+              "GL_OES_packed_depth_stencil, but neither were found.");
+        return false;
+    }
     // For control cases using GL formats, the test should be run in a single
     // context, without using AHardwareBuffer. This simplifies verifying that
     // the test behaves as expected even if the AHardwareBuffer format under
@@ -924,33 +951,50 @@
     glGenTextures(1, &texture);
     glActiveTexture(GL_TEXTURE0 + unit);
     glBindTexture(mTexTarget, texture);
+    // If the texture does not have mipmaps, set a filter that does not require them.
+    if (!(desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)) {
+        glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    }
     if (desc.stride & kGlFormat) {
         int levels = 1;
         if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE) {
             levels = MipLevelCount(desc.width, desc.height);
         }
-        // Stride is nonzero, so interpret desc.format as a GL format.
+        // kGlFormat is set in the stride field, so interpret desc.format as a GL format.
         if ((desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP) ? desc.layers > 6 : desc.layers > 1) {
             glTexStorage3D(mTexTarget, levels, desc.format, desc.width, desc.height, desc.layers);
         } else if (mGLVersion >= 30) {
             glTexStorage2D(mTexTarget, levels, desc.format, desc.width, desc.height);
         } else {
-            GLenum format = 0, type = 0;
+            // Compatibility code for ES 2.0 goes here.
+            GLenum internal_format = 0, format = 0, type = 0;
             switch (desc.format) {
                 case GL_RGB8:
+                    internal_format = GL_RGB;
                     format = GL_RGB;
                     type = GL_UNSIGNED_BYTE;
                     break;
                 case GL_RGBA8:
+                    internal_format = GL_RGBA;
+                    format = GL_RGBA;
+                    type = GL_UNSIGNED_BYTE;
+                    break;
                 case GL_SRGB8_ALPHA8:
+                    // Available through GL_EXT_sRGB.
+                    internal_format = GL_SRGB_ALPHA_EXT;
                     format = GL_RGBA;
                     type = GL_UNSIGNED_BYTE;
                     break;
                 case GL_DEPTH_COMPONENT16:
+                    // Available through GL_OES_depth_texture.
+                    // Note that these are treated as luminance textures, not as red textures.
+                    internal_format = GL_DEPTH_COMPONENT;
                     format = GL_DEPTH_COMPONENT;
                     type = GL_UNSIGNED_SHORT;
                     break;
                 case GL_DEPTH24_STENCIL8:
+                    // Available through GL_OES_packed_depth_stencil.
+                    internal_format = GL_DEPTH_STENCIL_OES;
                     format = GL_DEPTH_STENCIL;
                     type = GL_UNSIGNED_INT_24_8;
                 default:
@@ -958,15 +1002,23 @@
             }
             if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP) {
                 for (int face = 0; face < 6; ++face) {
+                    uint32_t width = desc.width;
+                    uint32_t height = desc.height;
                     for (int level = 0; level < levels; ++level) {
-                        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, desc.format,
-                                     desc.width, desc.height, 0, format, type, nullptr);
+                        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, internal_format,
+                                     width, height, 0, format, type, nullptr);
+                        width /= 2;
+                        height /= 2;
                     }
                 }
             } else {
+                uint32_t width = desc.width;
+                uint32_t height = desc.height;
                 for (int level = 0; level < levels; ++level) {
-                    glTexImage2D(mTexTarget, level, desc.format, desc.width, desc.height, 0,
-                                format, type, nullptr);
+                    glTexImage2D(mTexTarget, level, internal_format, width, height, 0, format,
+                                 type, nullptr);
+                    width /= 2;
+                    height /= 2;
                 }
             }
         }
@@ -978,11 +1030,6 @@
             glEGLImageTargetTexture2DOES(mTexTarget, static_cast<GLeglImageOES>(mEGLImage));
         }
     }
-    // If the texture does not have mipmaps, set a filter that does not require them.
-    if (!(desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)) {
-        glTexParameteri(mTexTarget, GL_TEXTURE_MAX_LEVEL, 0);
-        glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    }
     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
 }
 
@@ -1083,7 +1130,10 @@
 class BlobTest : public AHardwareBufferGLTest {
 public:
     bool SetUpBuffer(const AHardwareBuffer_Desc& desc) override {
-        if (!HasGLExtension("GL_EXT_external_buffer")) return false;
+        if (!HasGLExtension("GL_EXT_external_buffer")) {
+            ALOGI("Test skipped: GL_EXT_external_buffer not present");
+            return false;
+        }
         return AHardwareBufferGLTest::SetUpBuffer(desc);
     }
 };
@@ -1175,11 +1225,14 @@
 
 // Verifies that data written into a blob buffer from the GPU can be read on the CPU.
 TEST_P(BlobTest, GpuDataBufferCpuRead) {
+    if (mGLVersion < 31) {
+        ALOGI("Test skipped: shader storage buffer objects require ES 3.1+, found %d.%d",
+              mGLVersion / 10, mGLVersion % 10);
+        return;
+    }
     AHardwareBuffer_Desc desc = GetParam();
     desc.width = sizeof kQuadPositions;
     desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
-    // Shader storage buffer objects are only supported in OpenGL ES 3.1+
-    if (mGLVersion < 31) return;
     if (!SetUpBuffer(desc)) return;
 
     for (int i = 0; i < mContextCount; ++i) {
@@ -1370,7 +1423,7 @@
     if (!SetUpBuffer(desc)) return;
 
     // Bind the EGLImage to textures in both contexts.
-    const int kTextureUnit = 6;
+    const int kTextureUnit = 6 % mMaxTextureUnits;
     for (int i = 0; i < mContextCount; ++i) {
         MakeCurrent(i);
         SetUpTexture(desc, kTextureUnit);
@@ -1416,7 +1469,7 @@
     if (!SetUpBuffer(desc)) return;
 
     // Bind the EGLImage to textures in both contexts.
-    const int kTextureUnit = 1;
+    const int kTextureUnit = 1 % mMaxTextureUnits;
     for (int i = 0; i < mContextCount; ++i) {
         MakeCurrent(i);
         SetUpTexture(desc, kTextureUnit);
@@ -1456,6 +1509,11 @@
 }
 
 TEST_P(ColorTest, MipmapComplete) {
+    if (mGLVersion < 30) {
+        ALOGI("Test skipped: reading from nonzero level of a mipmap requires ES 3.0+, "
+              "found %d.%d", mGLVersion / 10, mGLVersion % 10);
+        return;
+    }
     const int kNumTiles = 8;
     AHardwareBuffer_Desc desc = GetParam();
     // Ensure that the checkerboard tiles have equal size at every level of the mipmap.
@@ -1467,7 +1525,7 @@
         AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
     if (!SetUpBuffer(desc)) return;
 
-    const int kTextureUnit = 7;
+    const int kTextureUnit = 7 % mMaxTextureUnits;
     for (int i = 0; i < mContextCount; ++i) {
         MakeCurrent(i);
         SetUpTexture(desc, kTextureUnit);
@@ -1508,7 +1566,7 @@
     desc.layers *= 6;
     if (!SetUpBuffer(desc)) return;
 
-    const int kTextureUnit = 4;
+    const int kTextureUnit = 4 % mMaxTextureUnits;
     for (int i = 0; i < mContextCount; ++i) {
         MakeCurrent(i);
         SetUpTexture(desc, kTextureUnit);
@@ -1548,6 +1606,11 @@
 }
 
 TEST_P(ColorTest, CubemapMipmaps) {
+    if (mGLVersion < 30) {
+        ALOGI("Test skipped: reading from nonzero level of a mipmap requires ES 3.0+, "
+              "found %d.%d", mGLVersion / 10, mGLVersion % 10);
+        return;
+    }
     const int kNumTiles = 8;
     AHardwareBuffer_Desc desc = GetParam();
     desc.usage =
@@ -1684,14 +1747,11 @@
 TEST_P(DepthTest, DepthCanBeSampled) {
     AHardwareBuffer_Desc desc = GetParam();
     desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
-    // ES 2.0 does not support depth textures. There is an extension OES_depth_texture, but it is
-    // incompatible with ES 3.x depth texture support.
-    if (mGLVersion < 30) return;
     if (!SetUpBuffer(desc)) return;
 
     // Bind the EGLImage to renderbuffers and framebuffers in both contexts.
     // The depth buffer is shared, but the color buffer is not.
-    const int kTextureUnit = 3;
+    const int kTextureUnit = 3 % mMaxTextureUnits;
     for (int i = 0; i < 2; ++i) {
         MakeCurrent(i);
         SetUpTexture(desc, kTextureUnit);
@@ -1720,12 +1780,13 @@
     EXPECT_EQ(GLenum{GL_NO_ERROR}, glGetError());
     glFinish();
 
-    // Check the rendered pixels. There should be a red square in the middle.
+    // Check the rendered pixels. There should be a square in the middle.
+    const GoldenColor kDepth = mGLVersion > 30 ? kRed : kWhite;
     std::vector<GoldenPixel> goldens{
-        {5, 35, kZero}, {15, 35, kZero}, {25, 35, kZero}, {35, 35, kZero},
-        {5, 25, kZero}, {15, 25, kRed},  {25, 25, kRed},  {35, 25, kZero},
-        {5, 15, kZero}, {15, 15, kRed},  {25, 15, kRed},  {35, 15, kZero},
-        {5,  5, kZero}, {15,  5, kZero}, {25, 5,  kZero}, {35, 5,  kZero},
+        {5, 35, kZero}, {15, 35, kZero},  {25, 35, kZero},  {35, 35, kZero},
+        {5, 25, kZero}, {15, 25, kDepth}, {25, 25, kDepth}, {35, 25, kZero},
+        {5, 15, kZero}, {15, 15, kDepth}, {25, 15, kDepth}, {35, 15, kZero},
+        {5,  5, kZero}, {15,  5, kZero},  {25, 5,  kZero},  {35, 5,  kZero},
     };
     CheckGoldenPixels(goldens, GL_RGBA8);
 }
@@ -1740,7 +1801,7 @@
     desc.layers *= 6;
     if (!SetUpBuffer(desc)) return;
 
-    const int kTextureUnit = 9;
+    const int kTextureUnit = 9 % mMaxTextureUnits;
     for (int i = 0; i < mContextCount; ++i) {
         MakeCurrent(i);
         SetUpTexture(desc, kTextureUnit);
@@ -1771,6 +1832,7 @@
         SetUpProgram(kVertexShader, kCubeMapFragmentShader, kQuadPositions, 0.5f, kTextureUnit);
     }
     SetUpFramebuffer(40, 40, 0, kRenderbuffer);
+    const GoldenColor kDepth = mGLVersion > 30 ? kRed : kWhite;
     for (int i = 0; i < 6; ++i) {
         float face_vector[3] = {0.f, 0.f, 0.f};
         face_vector[i / 2] = (i % 2) ? -1.f : 1.f;
@@ -1781,8 +1843,8 @@
 
         std::vector<GoldenPixel> goldens{
             {5, 35, kZero}, {15, 35, kZero},  {25, 35, kZero},  {35, 35, kZero},
-            {5, 25, kZero}, {15, 25, kBlack}, {25, 25, kRed},   {35, 25, kZero},
-            {5, 15, kZero}, {15, 15, kRed},   {25, 15, kBlack}, {35, 15, kZero},
+            {5, 25, kZero}, {15, 25, kBlack}, {25, 25, kDepth}, {35, 25, kZero},
+            {5, 15, kZero}, {15, 15, kDepth}, {25, 15, kBlack}, {35, 15, kZero},
             {5, 5,  kZero}, {15, 5,  kZero},  {25, 5,  kZero},  {35, 5,  kZero},
         };
         CheckGoldenPixels(goldens, GL_RGBA8);
@@ -1882,7 +1944,7 @@
     if (!kPureStencil && mGLVersion < 31) return;
     if (!SetUpBuffer(desc)) return;
 
-    const int kTextureUnit = 8;
+    const int kTextureUnit = 8 % mMaxTextureUnits;
     for (int i = 0; i < mContextCount; ++i) {
         MakeCurrent(i);
         SetUpTexture(desc, kTextureUnit);
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java b/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
index 3f2c47e..11fac90 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
@@ -233,7 +233,7 @@
         float eps = 0.005f;
 
         for (int c : pixels) {
-            if (c == background) {
+            if (isColorSame(c, background)) {
                 s.backgroundPixels++;
                 continue;
             }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CameraTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CameraTests.java
new file mode 100644
index 0000000..c46fbaf
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CameraTests.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 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.uirendering.cts.testclasses;
+
+import android.graphics.Camera;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.uirendering.cts.bitmapverifiers.RectVerifier;
+import android.uirendering.cts.testinfrastructure.ActivityTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class CameraTests extends ActivityTestBase {
+    @Test
+    public void testBasicTranslate() {
+        createTest()
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint paint = new Paint();
+                    paint.setAntiAlias(false);
+                    paint.setColor(Color.BLUE);
+                    Camera camera = new Camera();
+                    camera.translate(0, 50, 0);
+                    camera.applyToCanvas(canvas);
+                    canvas.drawRect(0, 50, 100, 100, paint);
+                })
+                .runWithVerifier(new RectVerifier(Color.WHITE, Color.BLUE,
+                        new Rect(0, 0, 100, 50)));
+    }
+}