(Android5.1.1) 如何在开机动画时显示机器序列号

之前做过的一个功能,在开机动画时显示当前主机的序列号。有其他会动态更新或者要显示当前机器特有信息在开机动画需求时,也可以借鉴此补丁进行实现。

external/skia/include/core/SkBitmap.h              |    2 +-
 frameworks/base/cmds/bootanimation/Android.mk      |    3 +-
 .../base/cmds/bootanimation/BootAnimation.cpp      |  164 +++++++++++++++++++-
 frameworks/base/cmds/bootanimation/BootAnimation.h |    7 +
 4 files changed, 171 insertions(+), 5 deletions(-)

diff --git a/external/skia/include/core/SkBitmap.h b/external/skia/include/core/SkBitmap.h
index d3c33a8..a4a60c6 100644
--- a/external/skia/include/core/SkBitmap.h
+++ b/external/skia/include/core/SkBitmap.h
@@ -13,7 +13,7 @@
 #include "SkImageInfo.h"
 #include "SkPoint.h"
 #include "SkRefCnt.h"
-
+#define SK_SUPPORT_LEGACY_SETCONFIG
 struct SkMask;
 struct SkIRect;
 struct SkRect;
diff --git a/frameworks/base/cmds/bootanimation/Android.mk b/frameworks/base/cmds/bootanimation/Android.mk
index 4a1a713..590a293 100644
--- a/frameworks/base/cmds/bootanimation/Android.mk
+++ b/frameworks/base/cmds/bootanimation/Android.mk
@@ -8,7 +8,8 @@ LOCAL_SRC_FILES:= \

 LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES

-LOCAL_C_INCLUDES += external/tinyalsa/include
+LOCAL_C_INCLUDES += external/tinyalsa/include \
+			external/skia/include

 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/frameworks/base/cmds/bootanimation/BootAnimation.cpp b/frameworks/base/cmds/bootanimation/BootAnimation.cpp
index 0d6c78d..bb6a9c7 100644
--- a/frameworks/base/cmds/bootanimation/BootAnimation.cpp
+++ b/frameworks/base/cmds/bootanimation/BootAnimation.cpp
@@ -79,6 +79,19 @@ namespace android {

 static const int ANIM_ENTRY_NAME_MAX = 256;

+static const int SN_TEXT_SIZE = 30;
+static const SkColor SN_TEXT_COLOR= 0xFFFFFFFF;
+
+#define EXPECT_NO_GL_ERROR(stmt)  \
+  do {  \
+    stmt;  \
+    const EGLint error_code = eglGetError();  \
+    if (EGL_SUCCESS != error_code){  \
+        LOGD("GLTest: GL error code %d at %s:%d", error_code, __FILE__, __LINE__); \
+        __android_log_assert("GLTest", "GLtest", "GlTest"); \
+    }\
+  } while(0)
+
 // ---------------------------------------------------------------------------

 BootAnimation::BootAnimation(bool shutdown) : Thread(false), mZip(NULL)
@@ -214,12 +227,12 @@ status_t BootAnimation::initTexture(const Animation::Frame& frame)
 {
     //StopWatch watch("blah");

-    SkBitmap bitmap;
+    SkBitmap bm;
     SkMemoryStream  stream(frame.map->getDataPtr(), frame.map->getDataLength());
     SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
     if (codec) {
         codec->setDitherImage(false);
-        codec->decode(&stream, &bitmap,
+        codec->decode(&stream, &bm,
                 #ifdef USE_565
                 kRGB_565_SkColorType,
                 #else
@@ -236,6 +249,24 @@ status_t BootAnimation::initTexture(const Animation::Frame& frame)

     // ensure we can call getPixels(). No need to call unlock, since the
     // bitmap will go out of scope when we return from this method.
+    SkBitmap bitmap;
+    bitmap.setConfig(SkBitmap::kARGB_8888_Config, bm.width(), bm.height());
+    bitmap.allocPixels();
+    SkGraphics::Init();
+    SkCanvas canvas(bitmap);
+    SkPaint textAttribs;
+
+    canvas.drawBitmap(bm, 0, 0,
+               &textAttribs);
+
+    textAttribs.setColor(SN_TEXT_COLOR);
+    textAttribs.setTextSize(SkIntToScalar(SN_TEXT_SIZE));
+    char serialno[PROPERTY_VALUE_MAX];
+    property_get("ro.serialno", serialno, "") ;
+    canvas.drawText(serialno, strlen(serialno), SN_TEXT_SIZE/2, bm.height()-SN_TEXT_SIZE/2,
+                textAttribs);
+
+
     bitmap.lockPixels();

     const int w = bitmap.width();
@@ -497,6 +528,8 @@ bool BootAnimation::android()
 {
     initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png"); // texture_object_mask
     initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
+    initSerialnoTexture(&serialnoTexture);
+
     mBMPWidth = mTexWidth = mBMPHeight = mTexHeight = 1;
     getTexCoordinate();

@@ -636,6 +669,11 @@ bool BootAnimation::android()
                        GL_UNSIGNED_SHORT,   // type
                        indices);            // indices

+        glDisable(GL_SCISSOR_TEST);
+        glEnable (GL_BLEND);
+        EXPECT_NO_GL_ERROR(glBindTexture(GL_TEXTURE_2D, serialnoTexture.name));
+        EXPECT_NO_GL_ERROR(glDrawTexiOES(0, 0, 0, serialnoTexture.w, serialnoTexture.h));
+
         /*-----------------------------------*/

         EGLBoolean res = eglSwapBuffers(mDisplay, mSurface);
@@ -652,6 +690,7 @@ bool BootAnimation::android()

     glDeleteTextures(1, &mAndroid[0].name);
     glDeleteTextures(1, &mAndroid[1].name);
+    glDeleteTextures(1, &serialnoTexture.name);
     return false;
 }

@@ -962,7 +1001,7 @@ bool BootAnimation::movie()
                     } while (err<0 && errno == EINTR);
                 }

-                checkExit();
+               checkExit();
             }

             usleep(part.pause * ns2us(frameDuration));
@@ -983,7 +1022,126 @@ bool BootAnimation::movie()

     return false;
 }
+status_t BootAnimation::initSerialnoTexture(Texture* texture)
+{
+        glShadeModel (GL_FLAT);
+    glDisable (GL_DITHER);
+    glDisable (GL_SCISSOR_TEST);
+    glClearColor(0, 1, 0, 1);
+    glClear(GL_COLOR_BUFFER_BIT);
+     SkGraphics::Init();
+    SkBitmap bitmap;

+     LOGD("initSerialnoTexture mWidth:%d,mHeight:%d",mWidth,mHeight);
+    bitmap.setConfig(SkBitmap::kARGB_8888_Config, mWidth, mHeight);
+    bitmap.allocPixels();
+
+    if(!initTexture(&(*texture), bitmap))
+    {
+        LOGD("GLTest: Unable to create a texture that is backed by SkBitmap");
+        return false;
+    }
+
+    SkCanvas canvas(bitmap);
+    SkPaint textAttribs;
+
+    textAttribs.setColor(SN_TEXT_COLOR);
+    textAttribs.setTextSize(SkIntToScalar(SN_TEXT_SIZE));
+    char serialno[PROPERTY_VALUE_MAX];
+    property_get("ro.serialno", serialno, "") ;
+    canvas.drawText(serialno, strlen(serialno), SN_TEXT_SIZE/2, mHeight-SN_TEXT_SIZE/2,
+                textAttribs);
+
+    return initTexture(&(*texture), bitmap);// Upload bitmap into canvas
+
+}
+
+status_t BootAnimation::initTexture(Texture* texture, const SkBitmap &bitmap)
+{
+    bool result = true;
+    SkAutoLockPixels alp(bitmap);
+
+    const int w = bitmap.width();
+    const int h = bitmap.height();
+    const void* p = bitmap.getPixels();
+    int tw = 1 << (31 - __builtin_clz(w));
+    int th = 1 << (31 - __builtin_clz(h));
+    if (tw < w)
+        tw <<= 1;
+    if (th < h)
+        th <<= 1;
+
+    if (NULL == texture)
+      {LOGD("GNULL == texture");
+        return false;
+      }
+      LOGD("texture->name %d",texture->name);
+    if (texture->name != 0)
+    {
+        glBindTexture(GL_TEXTURE_2D, texture->name);
+        switch (bitmap.getConfig())
+        {
+        case SkBitmap::kA8_Config:
+            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_ALPHA, GL_UNSIGNED_BYTE, p);
+            break;
+        case SkBitmap::kARGB_4444_Config:
+            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, p);
+            break;
+        case SkBitmap::kARGB_8888_Config:
+            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
+            break;
+        case SkBitmap::kRGB_565_Config:
+            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
+            break;
+        default:
+            break;
+        }
+    }
+     LOGD("texture->w:%d,texture->h:%d",texture->w,texture->h);
+    GLint crop[4] = { 0, h, w, -h };
+    texture->w = w;
+    texture->h = h;
+
+    glEnable (GL_TEXTURE_2D);
+    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:
+        if (tw != w || th != h)
+        {
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
+                    GL_UNSIGNED_BYTE, 0);
+            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA,
+                    GL_UNSIGNED_BYTE, p);
+        }
+        else
+        {
+            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);
+    LOGD("result :%d",result);
+    return result;
+}
 /* ############################################################################################# */

 int64_t BootAnimation::getFileSize(int fd)
diff --git a/frameworks/base/cmds/bootanimation/BootAnimation.h b/frameworks/base/cmds/bootanimation/BootAnimation.h
index 5663dba..1a78d69 100644
--- a/frameworks/base/cmds/bootanimation/BootAnimation.h
+++ b/frameworks/base/cmds/bootanimation/BootAnimation.h
@@ -26,6 +26,10 @@
 #include <EGL/egl.h>
 #include <GLES/gl.h>

+#include "SkCanvas.h"
+#include "SkGraphics.h"
+ #include "SkBitmap.h"
+
 class SkBitmap;

 namespace android {
@@ -84,6 +88,8 @@ private:

     status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
     status_t initTexture(const Animation::Frame& frame);
+     status_t initTexture(Texture* texture, const SkBitmap &bitmap);
+     status_t initSerialnoTexture(Texture* texture);
     bool android();
     bool readFile(const char* name, String8& outString);
     bool movie();
@@ -114,6 +120,7 @@ private:
     int         mTexHeight;
     int         mBMPWidth;
     int         mBMPHeight;
+    Texture     serialnoTexture;

     template<class T>
     void exchangeParameters(T* x, T* y) {
--
1.7.9.5

标记一下,有空试下。全屏开机动画上显示会不会不好看?有没有拍个图看看效果。

有意思, 待会儿试试

有点意思! 我明天试试