split boot animation out of SurfaceFlinger

Conflicts:

	data/etc/platform.xml
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index 2212436..9272983 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -6,7 +6,6 @@
     DisplayHardware/DisplayHardware.cpp \
     DisplayHardware/DisplayHardwareBase.cpp \
     GPUHardware/GPUHardware.cpp \
-    BootAnimation.cpp \
     BlurFilter.cpp.arm \
     CPUGauge.cpp \
     Layer.cpp \
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
deleted file mode 100644
index db40385..0000000
--- a/libs/surfaceflinger/BootAnimation.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BootAnimation"
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <math.h>
-#include <fcntl.h>
-#include <utils/misc.h>
-
-#include <utils/threads.h>
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/AssetManager.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-#include <ui/DisplayInfo.h>
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-#include <ui/EGLNativeWindowSurface.h>
-
-#include <core/SkBitmap.h>
-#include <images/SkImageDecoder.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <EGL/eglext.h>
-
-#include "BootAnimation.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-BootAnimation::BootAnimation(const sp<ISurfaceComposer>& composer) :
-    Thread(false) {
-    mSession = SurfaceComposerClient::clientForConnection(
-            composer->createConnection()->asBinder());
-}
-
-BootAnimation::~BootAnimation() {
-}
-
-void BootAnimation::onFirstRef() {
-    run("BootAnimation", PRIORITY_DISPLAY);
-}
-
-const sp<SurfaceComposerClient>& BootAnimation::session() const {
-    return mSession;
-}
-
-status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
-        const char* name) {
-    Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
-    if (!asset)
-        return NO_INIT;
-    SkBitmap bitmap;
-    SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
-            &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
-    asset->close();
-    delete asset;
-
-    // ensure we can call getPixels(). No need to call unlock, since the
-    // bitmap will go out of scope when we return from this method.
-    bitmap.lockPixels();
-
-    const int w = bitmap.width();
-    const int h = bitmap.height();
-    const void* p = bitmap.getPixels();
-
-    GLint crop[4] = { 0, h, w, -h };
-    texture->w = w;
-    texture->h = h;
-
-    glGenTextures(1, &texture->name);
-    glBindTexture(GL_TEXTURE_2D, texture->name);
-
-    switch (bitmap.getConfig()) {
-        case SkBitmap::kA8_Config:
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
-                    GL_UNSIGNED_BYTE, p);
-            break;
-        case SkBitmap::kARGB_4444_Config:
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
-                    GL_UNSIGNED_SHORT_4_4_4_4, p);
-            break;
-        case SkBitmap::kARGB_8888_Config:
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
-                    GL_UNSIGNED_BYTE, p);
-            break;
-        case SkBitmap::kRGB_565_Config:
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
-                    GL_UNSIGNED_SHORT_5_6_5, p);
-            break;
-        default:
-            break;
-    }
-
-    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-    return NO_ERROR;
-}
-
-status_t BootAnimation::readyToRun() {
-    mAssets.addDefaultAssets();
-
-    DisplayInfo dinfo;
-    status_t status = session()->getDisplayInfo(0, &dinfo);
-    if (status)
-        return -1;
-
-    // create the native surface
-    sp<Surface> s = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h,
-            PIXEL_FORMAT_RGB_565);
-    session()->openTransaction();
-    s->setLayer(0x40000000);
-    session()->closeTransaction();
-
-    // initialize opengl and egl
-    const EGLint attribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6,
-            EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 0, EGL_NONE };
-    EGLint w, h, dummy;
-    EGLint numConfigs;
-    EGLConfig config;
-    EGLSurface surface;
-    EGLContext context;
-    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    eglChooseConfig(display, attribs, &config, 1, &numConfigs);
-
-    mNativeWindowSurface = new EGLNativeWindowSurface(s);
-    surface = eglCreateWindowSurface(display, config, 
-            mNativeWindowSurface.get(), NULL);
-
-    context = eglCreateContext(display, config, NULL, NULL);
-    eglQuerySurface(display, surface, EGL_WIDTH, &w);
-    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
-    eglMakeCurrent(display, surface, surface, context);
-    mDisplay = display;
-    mContext = context;
-    mSurface = surface;
-    mWidth = w;
-    mHeight = h;
-    mFlingerSurface = s;
-
-    // initialize GL
-    glShadeModel(GL_FLAT);
-    glEnable(GL_TEXTURE_2D);
-    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-    return NO_ERROR;
-}
-
-void BootAnimation::requestExit() {
-    mBarrier.open();
-    Thread::requestExit();
-}
-
-bool BootAnimation::threadLoop() {
-    bool r = android();
-    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    eglDestroyContext(mDisplay, mContext);
-    eglDestroySurface(mDisplay, mSurface);
-    mNativeWindowSurface.clear();
-    return r;
-}
-
-bool BootAnimation::android() {
-    initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
-    initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
-
-    // clear screen
-    glDisable(GL_DITHER);
-    glDisable(GL_SCISSOR_TEST);
-    glClear(GL_COLOR_BUFFER_BIT);
-    eglSwapBuffers(mDisplay, mSurface);
-
-    const GLint xc = (mWidth  - mAndroid[0].w) / 2;
-    const GLint yc = (mHeight - mAndroid[0].h) / 2;
-    const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h);
-
-    // draw and update only what we need
-    mNativeWindowSurface->setSwapRectangle(updateRect.left,
-            updateRect.top, updateRect.width(), updateRect.height());
-
-    glEnable(GL_SCISSOR_TEST);
-    glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(),
-            updateRect.height());
-
-    // Blend state
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-    const nsecs_t startTime = systemTime();
-    do {
-        nsecs_t now = systemTime();
-        double time = now - startTime;
-        float t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w;
-        GLint offset = (1 - (t - floorf(t))) * mAndroid[1].w;
-        GLint x = xc - offset;
-
-        glDisable(GL_BLEND);
-        glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
-        glDrawTexiOES(x,                 yc, 0, mAndroid[1].w, mAndroid[1].h);
-        glDrawTexiOES(x + mAndroid[1].w, yc, 0, mAndroid[1].w, mAndroid[1].h);
-
-        glEnable(GL_BLEND);
-        glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
-        glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h);
-
-        eglSwapBuffers(mDisplay, mSurface);
-        
-        // 12fps: don't animate too fast to preserve CPU
-        const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
-        if (sleepTime > 0)
-            usleep(sleepTime); 
-    } while (!exitPending());
-
-    glDeleteTextures(1, &mAndroid[0].name);
-    glDeleteTextures(1, &mAndroid[1].name);
-    return false;
-}
-
-// ---------------------------------------------------------------------------
-
-}
-; // namespace android
diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h
deleted file mode 100644
index 3fb6670..0000000
--- a/libs/surfaceflinger/BootAnimation.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-#ifndef ANDROID_BOOTANIMATION_H
-#define ANDROID_BOOTANIMATION_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-#include <utils/AssetManager.h>
-
-#include <ui/ISurfaceComposer.h>
-#include <ui/SurfaceComposerClient.h>
-
-#include <EGL/egl.h>
-#include <GLES/gl.h>
-
-#include "Barrier.h"
-
-class SkBitmap;
-
-namespace android {
-
-class AssetManager;
-class EGLNativeWindowSurface;
-
-// ---------------------------------------------------------------------------
-
-class BootAnimation : public Thread
-{
-public:
-                BootAnimation(const sp<ISurfaceComposer>& composer);
-    virtual     ~BootAnimation();
-
-    const sp<SurfaceComposerClient>& session() const;
-    virtual void        requestExit();
-
-private:
-    virtual bool        threadLoop();
-    virtual status_t    readyToRun();
-    virtual void        onFirstRef();
-
-    struct Texture {
-        GLint   w;
-        GLint   h;
-        GLuint  name;
-    };
-
-    status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
-    bool android();
-
-    sp<SurfaceComposerClient>       mSession;
-    AssetManager mAssets;
-    Texture     mAndroid[2];
-    int         mWidth;
-    int         mHeight;
-    EGLDisplay  mDisplay;
-    EGLDisplay  mContext;
-    EGLDisplay  mSurface;
-    sp<Surface> mFlingerSurface;
-    sp<EGLNativeWindowSurface> mNativeWindowSurface;
-    Barrier mBarrier;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_BOOTANIMATION_H
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 167a59b..0e998bf 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -61,6 +61,13 @@
 #include "GPUHardware/GPUHardware.h"
 
 
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
 #define DISPLAY_COUNT       1
 
 namespace android {
@@ -184,7 +191,6 @@
         mDebugCpu(0),
         mDebugFps(0),
         mDebugBackground(0),
-        mDebugNoBootAnimation(0),
         mSyncObject(),
         mDeplayedTransactionPending(0),
         mConsoleSignals(0),
@@ -207,14 +213,11 @@
     mDebugBackground = atoi(value);
     property_get("debug.sf.showfps", value, "0");
     mDebugFps = atoi(value);
-    property_get("debug.sf.nobootanimation", value, "0");
-    mDebugNoBootAnimation = atoi(value);
 
     LOGI_IF(mDebugRegion,           "showupdates enabled");
     LOGI_IF(mDebugCpu,              "showcpu enabled");
     LOGI_IF(mDebugBackground,       "showbackground enabled");
     LOGI_IF(mDebugFps,              "showfps enabled");
-    LOGI_IF(mDebugNoBootAnimation,  "boot animation disabled");
 }
 
 SurfaceFlinger::~SurfaceFlinger()
@@ -324,11 +327,8 @@
 {
     const nsecs_t now = systemTime();
     const nsecs_t duration = now - mBootTime;
-    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
-    if (mBootAnimation != 0) {
-        mBootAnimation->requestExit();
-        mBootAnimation.clear();
-    }
+    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );  
+    property_set("ctl.stop", "bootanim");
 }
 
 void SurfaceFlinger::onFirstRef()
@@ -456,10 +456,10 @@
     if (mDebugCpu)
         mCpuGauge = new CPUGauge(this, ms2ns(500));
 
-    // the boot animation!
-    if (mDebugNoBootAnimation == false)
-        mBootAnimation = new BootAnimation(this);
-
+    
+    // start boot animation
+    property_set("ctl.start", "bootanim");
+    
     return NO_ERROR;
 }
 
@@ -1543,13 +1543,13 @@
             // codes that require permission check
             IPCThreadState* ipc = IPCThreadState::self();
             const int pid = ipc->getCallingPid();
+            const int uid = ipc->getCallingUid();
             const int self_pid = getpid();
-            if (UNLIKELY(pid != self_pid)) {
+            if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
                 // we're called from a different process, do the real check
                 if (!checkCallingPermission(
                         String16("android.permission.ACCESS_SURFACE_FLINGER")))
                 {
-                    const int uid = ipc->getCallingUid();
                     LOGE("Permission Denial: "
                             "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
                     return PERMISSION_DENIED;
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index e023182..15913f2 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -36,7 +36,6 @@
 #include <private/ui/SurfaceFlingerSynchro.h>
 
 #include "Barrier.h"
-#include "BootAnimation.h"
 #include "CPUGauge.h"
 #include "Layer.h"
 #include "Tokenizer.h"
@@ -347,7 +346,6 @@
                 sp<SurfaceHeapManager>      mSurfaceHeapManager;
                 sp<GPUHardwareInterface>    mGPU;
                 GLuint                      mWormholeTexName;
-                sp<BootAnimation>           mBootAnimation;
                 nsecs_t                     mBootTime;
                 
                 // Can only accessed from the main thread, these members
@@ -374,7 +372,6 @@
                 int                         mDebugCpu;
                 int                         mDebugFps;
                 int                         mDebugBackground;
-                int                         mDebugNoBootAnimation;
 
                 // these are thread safe
     mutable     Barrier                     mReadyToRunBarrier;
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp
index 238c602..5f633bd 100644
--- a/libs/surfaceflinger/VRamHeap.cpp
+++ b/libs/surfaceflinger/VRamHeap.cpp
@@ -35,6 +35,8 @@
 #include <utils/MemoryHeapPmem.h>
 #include <utils/MemoryHeapBase.h>
 
+#include <EGL/eglnatives.h>
+
 #include "GPUHardware/GPUHardware.h"
 #include "SurfaceFlinger.h"
 #include "VRamHeap.h"
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp
index dd6a798..dab5f71 100644
--- a/libs/ui/ISurfaceFlingerClient.cpp
+++ b/libs/ui/ISurfaceFlingerClient.cpp
@@ -35,6 +35,13 @@
 
 // ---------------------------------------------------------------------------
 
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
 
@@ -136,13 +143,13 @@
      
      IPCThreadState* ipc = IPCThreadState::self();
      const int pid = ipc->getCallingPid();
-     const int self_pid    = getpid();
-     if (UNLIKELY(pid != self_pid)) {
+     const int uid = ipc->getCallingUid();
+     const int self_pid = getpid();
+     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
          // we're called from a different process, do the real check
          if (!checkCallingPermission(
                  String16("android.permission.ACCESS_SURFACE_FLINGER")))
          {
-             const int uid = ipc->getCallingUid();
              LOGE("Permission Denial: "
                      "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
              return PERMISSION_DENIED;