Allow custom wallpaper and boot animation.

Add new "ro.config.wallpaper" and "ro.config.wallpaper_component"
properties which may be defined outside of the bundled framework
resources.  Falls back to bundled resources when properties are
undefined.

Also look for boot animation under OEM partition.

Bug: 13340779
Change-Id: Ibdc9935dbdaae3319bf63b40573de0503d82ae67
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 41afa39..1780e03 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -51,6 +51,7 @@
 
 #include "BootAnimation.h"
 
+#define OEM_BOOTANIMATION_FILE "/oem/media/bootanimation.zip"
 #define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
 #define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip"
 #define EXIT_PROP_NAME "service.bootanim.exit"
@@ -283,6 +284,9 @@
             (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) &&
             ((zipFile = ZipFileRO::open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)) != NULL)) ||
 
+            ((access(OEM_BOOTANIMATION_FILE, R_OK) == 0) &&
+            ((zipFile = ZipFileRO::open(OEM_BOOTANIMATION_FILE)) != NULL)) ||
+
             ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&
             ((zipFile = ZipFileRO::open(SYSTEM_BOOTANIMATION_FILE)) != NULL))) {
         mZip = zipFile;
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index e6e0f35..f08097b 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -44,10 +45,14 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.WindowManagerGlobal;
 
 import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -65,6 +70,11 @@
     private float mWallpaperXStep = -1;
     private float mWallpaperYStep = -1;
 
+    /** {@hide} */
+    private static final String PROP_WALLPAPER = "ro.config.wallpaper";
+    /** {@hide} */
+    private static final String PROP_WALLPAPER_COMPONENT = "ro.config.wallpaper_component";
+
     /**
      * Activity Action: Show settings for choosing wallpaper. Do not use directly to construct
      * an intent; instead, use {@link #getCropAndSetWallpaperIntent}.
@@ -298,8 +308,7 @@
         
         private Bitmap getDefaultWallpaperLocked(Context context) {
             try {
-                InputStream is = context.getResources().openRawResource(
-                        com.android.internal.R.drawable.default_wallpaper);
+                InputStream is = openDefaultWallpaper(context);
                 if (is != null) {
                     int width = mService.getWidthHint();
                     int height = mService.getHeightHint();
@@ -403,8 +412,7 @@
         horizontalAlignment = Math.max(0, Math.min(1, horizontalAlignment));
         verticalAlignment = Math.max(0, Math.min(1, verticalAlignment));
 
-        InputStream is = new BufferedInputStream(
-                resources.openRawResource(com.android.internal.R.drawable.default_wallpaper));
+        InputStream is = new BufferedInputStream(openDefaultWallpaper(mContext));
 
         if (is == null) {
             Log.e(TAG, "default wallpaper input stream is null");
@@ -429,8 +437,7 @@
                     }
                 }
 
-                is = new BufferedInputStream(resources.openRawResource(
-                        com.android.internal.R.drawable.default_wallpaper));
+                is = new BufferedInputStream(openDefaultWallpaper(mContext));
 
                 RectF cropRectF;
 
@@ -479,8 +486,7 @@
 
                 if (crop == null) {
                     // BitmapRegionDecoder has failed, try to crop in-memory
-                    is = new BufferedInputStream(resources.openRawResource(
-                            com.android.internal.R.drawable.default_wallpaper));
+                    is = new BufferedInputStream(openDefaultWallpaper(mContext));
                     Bitmap fullSize = null;
                     if (is != null) {
                         BitmapFactory.Options options = new BitmapFactory.Options();
@@ -1009,6 +1015,53 @@
      * wallpaper.
      */
     public void clear() throws IOException {
-        setResource(com.android.internal.R.drawable.default_wallpaper);
+        setStream(openDefaultWallpaper(mContext));
+    }
+
+    /**
+     * Open stream representing the default static image wallpaper.
+     *
+     * @hide
+     */
+    public static InputStream openDefaultWallpaper(Context context) {
+        final String path = SystemProperties.get(PROP_WALLPAPER);
+        if (!TextUtils.isEmpty(path)) {
+            final File file = new File(path);
+            if (file.exists()) {
+                try {
+                    return new FileInputStream(file);
+                } catch (IOException e) {
+                    // Ignored, fall back to platform default below
+                }
+            }
+        }
+        return context.getResources().openRawResource(
+                com.android.internal.R.drawable.default_wallpaper);
+    }
+
+    /**
+     * Return {@link ComponentName} of the default live wallpaper, or
+     * {@code null} if none is defined.
+     *
+     * @hide
+     */
+    public static ComponentName getDefaultWallpaperComponent(Context context) {
+        String flat = SystemProperties.get(PROP_WALLPAPER_COMPONENT);
+        if (!TextUtils.isEmpty(flat)) {
+            final ComponentName cn = ComponentName.unflattenFromString(flat);
+            if (cn != null) {
+                return cn;
+            }
+        }
+
+        flat = context.getString(com.android.internal.R.string.default_wallpaper_component);
+        if (!TextUtils.isEmpty(flat)) {
+            final ComponentName cn = ComponentName.unflattenFromString(flat);
+            if (cn != null) {
+                return cn;
+            }
+        }
+
+        return null;
     }
 }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 87953fe..3eb2d5f 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -25,6 +25,7 @@
 import android.app.IWallpaperManagerCallback;
 import android.app.PendingIntent;
 import android.app.WallpaperInfo;
+import android.app.WallpaperManager;
 import android.app.backup.BackupManager;
 import android.app.backup.WallpaperBackupHelper;
 import android.content.BroadcastReceiver;
@@ -844,13 +845,7 @@
         
         try {
             if (componentName == null) {
-                String defaultComponent = 
-                    mContext.getString(com.android.internal.R.string.default_wallpaper_component);
-                if (defaultComponent != null) {
-                    // See if there is a default wallpaper component specified
-                    componentName = ComponentName.unflattenFromString(defaultComponent);
-                    if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
-                }
+                componentName = WallpaperManager.getDefaultWallpaperComponent(mContext);
                 if (componentName == null) {
                     // Fall back to static image wallpaper
                     componentName = IMAGE_WALLPAPER;