Merge "Limit Carrier Privileges to relevant CTS test app" into emu-master-dev
diff --git a/android/android-emu/android/opengles.cpp b/android/android-emu/android/opengles.cpp
index fcc0070..8271400 100644
--- a/android/android-emu/android/opengles.cpp
+++ b/android/android-emu/android/opengles.cpp
@@ -119,7 +119,7 @@
 }
 
 int
-android_startOpenglesRenderer(int width, int height)
+android_startOpenglesRenderer(int width, int height, int guestApiLevel)
 {
     if (!sRenderLib) {
         D("Can't start OpenGLES renderer without support libraries");
@@ -132,6 +132,7 @@
 
     android_init_opengl_logger();
 
+    sRenderLib->setApiLevel(guestApiLevel);
     sRenderLib->setCrashReporter(&crashhandler_die_format);
     sRenderLib->setFeatureController(&android::featurecontrol::isEnabled);
     sRenderLib->setSyncDevice(goldfish_sync_create_timeline,
diff --git a/android/android-emu/android/opengles.h b/android/android-emu/android/opengles.h
index 82d1b24..1be404d 100644
--- a/android/android-emu/android/opengles.h
+++ b/android/android-emu/android/opengles.h
@@ -31,8 +31,12 @@
 /* Tries to start the renderer process. Returns 0 on success, -1 on error.
  * At the moment, this must be done before the VM starts. The onPost callback
  * may be NULL.
+ *
+ * width and height: the framebuffer dimensions that will be reported
+ *                   to the guest display driver.
+ * guestApiLevel: API level of guest image (23 for mnc, 24 for nyc, etc)
  */
-int android_startOpenglesRenderer(int width, int height);
+int android_startOpenglesRenderer(int width, int height, int guestApiLevel);
 
 /* See the description in render_api.h. */
 typedef void (*OnPostFunc)(void* context, int width, int height, int ydir,
diff --git a/android/android-emugl/host/include/OpenglRender/RenderLib.h b/android/android-emugl/host/include/OpenglRender/RenderLib.h
index 48094b2..9201931 100644
--- a/android/android-emugl/host/include/OpenglRender/RenderLib.h
+++ b/android/android-emugl/host/include/OpenglRender/RenderLib.h
@@ -27,6 +27,9 @@
 public:
     virtual ~RenderLib() = default;
 
+    // Tell emugl the API version of the system image
+    // Please extend it to setAvd, if more avd info is needed in future.
+    virtual void setApiLevel(int api) = 0;
     virtual void setLogger(emugl_logger_struct logger) = 0;
     virtual void setCrashReporter(emugl_crash_reporter_t reporter) = 0;
     virtual void setFeatureController(emugl_feature_is_enabled_t featureController) = 0;
diff --git a/android/android-emugl/host/libs/libOpenglRender/FbConfig.cpp b/android/android-emugl/host/libs/libOpenglRender/FbConfig.cpp
index 5035c53..c5c09b8 100644
--- a/android/android-emugl/host/libs/libOpenglRender/FbConfig.cpp
+++ b/android/android-emugl/host/libs/libOpenglRender/FbConfig.cpp
@@ -14,6 +14,7 @@
 
 #include "FbConfig.h"
 
+#include "emugl/common/misc.h"
 #include "OpenGLESDispatch/EGLDispatch.h"
 
 #include <stdio.h>
@@ -163,10 +164,16 @@
     // what it used by the current implementation, exclusively. This forces
     // the rewrite of |attribs| into a new array.
     bool hasSurfaceType = false;
+    bool wantSwapPreserved = false;
+    int surfaceTypeIdx = 0;
     int numAttribs = 0;
     while (attribs[numAttribs] != EGL_NONE) {
         if (attribs[numAttribs] == EGL_SURFACE_TYPE) {
             hasSurfaceType = true;
+            surfaceTypeIdx = numAttribs;
+            if (attribs[numAttribs+1] & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) {
+                wantSwapPreserved = true;
+            }
         }
         numAttribs += 2;
     }
@@ -180,6 +187,15 @@
         newAttribs[numAttribs] = EGL_SURFACE_TYPE;
         newAttribs[numAttribs + 1] = 0;
         newAttribs[numAttribs + 2] = EGL_NONE;
+    } else if (wantSwapPreserved && emugl::getApiLevel() <= 19) {
+        // For api <= 19, there is a bug in some public system images
+        // that causes UI issue if the host rejects
+        // EGL_SWAP_BEHAVIOR_PRESERVED_BIT, while they are not using
+        // this feature.
+        // So we wipe it out.
+        newAttribs = new GLint[numAttribs+1];
+        memcpy(newAttribs, attribs, (numAttribs+1) * sizeof(GLint));
+        newAttribs[surfaceTypeIdx+1] &= ~(EGLint)EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
     }
 
     if (s_egl.eglChooseConfig(mDisplay,
diff --git a/android/android-emugl/host/libs/libOpenglRender/RenderLibImpl.cpp b/android/android-emugl/host/libs/libOpenglRender/RenderLibImpl.cpp
index cd892b3..f2ab4aa 100644
--- a/android/android-emugl/host/libs/libOpenglRender/RenderLibImpl.cpp
+++ b/android/android-emugl/host/libs/libOpenglRender/RenderLibImpl.cpp
@@ -18,10 +18,15 @@
 #include "emugl/common/crash_reporter.h"
 #include "emugl/common/feature_control.h"
 #include "emugl/common/logging.h"
+#include "emugl/common/misc.h"
 #include "emugl/common/sync_device.h"
 
 namespace emugl {
 
+void RenderLibImpl::setApiLevel(int api) {
+    emugl::setApiLevel(api);
+}
+
 void RenderLibImpl::setLogger(emugl_logger_struct logger) {
     set_emugl_logger(logger.coarse);
     set_emugl_cxt_logger(logger.fine);
diff --git a/android/android-emugl/host/libs/libOpenglRender/RenderLibImpl.h b/android/android-emugl/host/libs/libOpenglRender/RenderLibImpl.h
index a83227a..0a17fed 100644
--- a/android/android-emugl/host/libs/libOpenglRender/RenderLibImpl.h
+++ b/android/android-emugl/host/libs/libOpenglRender/RenderLibImpl.h
@@ -25,6 +25,7 @@
 public:
     RenderLibImpl() = default;
 
+    virtual void setApiLevel(int api) override;
     virtual void setLogger(emugl_logger_struct logger) override;
     virtual void setCrashReporter(emugl_crash_reporter_t reporter) override;
     virtual void setFeatureController(emugl_feature_is_enabled_t featureController) override;
diff --git a/android/android-emugl/shared/emugl/common/Android.mk b/android/android-emugl/shared/emugl/common/Android.mk
index c458731..19d72bd 100644
--- a/android/android-emugl/shared/emugl/common/Android.mk
+++ b/android/android-emugl/shared/emugl/common/Android.mk
@@ -9,6 +9,7 @@
         crash_reporter.cpp \
         feature_control.cpp \
         logging.cpp \
+        misc.cpp \
         shared_library.cpp \
         stringparsing.cpp \
         sockets.cpp \
diff --git a/android/qemu1/vl-android.c b/android/qemu1/vl-android.c
index 0bc55c9..beab7bc 100644
--- a/android/qemu1/vl-android.c
+++ b/android/qemu1/vl-android.c
@@ -3033,7 +3033,9 @@
         // the error in |opengl_broken| instead.
         if (android_initOpenglesEmulation() != 0 ||
             android_startOpenglesRenderer(android_hw->hw_lcd_width,
-                                          android_hw->hw_lcd_height) != 0)
+                                          android_hw->hw_lcd_height,
+                                          avdInfo_getApiLevel(android_avdInfo))
+                != 0)
         {
             opengl_broken = true;
         }
diff --git a/distrib/android-emugl/shared/emugl/common/misc.cpp b/distrib/android-emugl/shared/emugl/common/misc.cpp
new file mode 100644
index 0000000..05e0bb3
--- /dev/null
+++ b/distrib/android-emugl/shared/emugl/common/misc.cpp
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "emugl/common/misc.h"
+
+static int s_api = -1;
+
+void emugl::setApiLevel(int api) {
+    s_api = api;
+}
+
+int emugl::getApiLevel() {
+    return s_api;
+}
diff --git a/distrib/android-emugl/shared/emugl/common/misc.h b/distrib/android-emugl/shared/emugl/common/misc.h
new file mode 100644
index 0000000..7e07a76
--- /dev/null
+++ b/distrib/android-emugl/shared/emugl/common/misc.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+namespace emugl {
+    // Set and get API version of system image.
+    // setApiVersion should only be called once when initializing RenderLib
+    void setApiLevel(int api);
+    int getApiLevel();
+}
\ No newline at end of file