Add new "walk around" wallpaper.

Known issue: causes Camera to fail on start sometimes.

Change-Id: Ic3e5de7f973b8178d297817e21e5fd4d692bb115
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b450754..41ebac7 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -22,6 +22,7 @@
     package="com.android.wallpaper">
 
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.CAMERA" />
 
     <application
         android:label="@string/wallpapers"
@@ -120,6 +121,16 @@
             <meta-data android:name="android.service.wallpaper" android:resource="@xml/polar_clock" />
         </service>
 
+        <service
+            android:label="@string/wallpaper_walkaround"
+            android:name="com.android.wallpaper.walkaround.WalkAroundWallpaper"
+            android:permission="android.permission.BIND_WALLPAPER">
+            <intent-filter>
+                <action android:name="android.service.wallpaper.WallpaperService" />
+            </intent-filter>
+            <meta-data android:name="android.service.wallpaper" android:resource="@xml/walkaround" />
+        </service>
+
     </application>
 
 </manifest>
diff --git a/res/drawable-hdpi/seethru_thumb.png b/res/drawable-hdpi/seethru_thumb.png
new file mode 100644
index 0000000..5a09c78
--- /dev/null
+++ b/res/drawable-hdpi/seethru_thumb.png
Binary files differ
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 815fde6..20710c9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -25,7 +25,14 @@
 
     <!-- Wallpapers: -->
     <skip />    
-    
+
+    <!-- Wallpaper showing the camera preview -->
+    <string name="wallpaper_walkaround">See Through</string>
+    <string name="wallpaper_walkaround_author">Google</string>
+    <string name="wallpaper_walkaround_desc">
+        See through your phone and walk around without risking accidents.
+    </string>
+
     <!-- Wallpaper showing grass and the sky -->
     <string name="wallpaper_grass">Grass</string>
     <string name="wallpaper_grass_author">Google</string>
@@ -41,7 +48,7 @@
     </string>
 
     <!-- Wallpaper showing leaves floating on water -->
-    <string name="wallpaper_fall">Water</string>    
+    <string name="wallpaper_fall">Water</string>
     <string name="wallpaper_fall_author">Google</string>
     <string name="wallpaper_fall_desc">
         Autumn leaves tumble&lt;br&gt;
diff --git a/res/xml/walkaround.xml b/res/xml/walkaround.xml
new file mode 100644
index 0000000..3ec573c
--- /dev/null
+++ b/res/xml/walkaround.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2008, 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.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- about the walk around wallpaper. -->
+
+<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
+    android:wallpaperAuthor="@string/wallpaper_walkaround_author"
+    android:wallpaperDescription="@string/wallpaper_walkaround_desc"
+    android:thumbnail="@drawable/seethru_thumb" />
diff --git a/src/com/android/wallpaper/walkaround/WalkAroundWallpaper.java b/src/com/android/wallpaper/walkaround/WalkAroundWallpaper.java
new file mode 100644
index 0000000..932c0b8
--- /dev/null
+++ b/src/com/android/wallpaper/walkaround/WalkAroundWallpaper.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2009 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 com.android.wallpaper.walkaround;
+
+import android.service.wallpaper.WallpaperService;
+import android.view.SurfaceHolder;
+import android.hardware.Camera;
+import android.util.Log;
+import android.util.DisplayMetrics;
+import android.graphics.Canvas;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+
+import java.io.IOException;
+import java.util.List;
+
+public class WalkAroundWallpaper extends WallpaperService {
+    private static final String LOG_TAG = "WalkAround";
+
+    private Camera mCamera;
+    private WalkAroundEngine mOwner;
+
+    public Engine onCreateEngine() {
+        return mOwner = new WalkAroundEngine();
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        stopCamera();
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    private void startCamera() {
+        if (mCamera == null) {
+            mCamera = Camera.open();
+        } else {
+            try {
+                mCamera.reconnect();
+            } catch (IOException e) {
+                mCamera.release();
+                mCamera = null;
+
+                Log.e(LOG_TAG, "Error opening the camera", e);
+            }
+        }
+    }
+    
+    private void stopCamera() {
+        if (mCamera != null) {
+            try {
+                mCamera.stopPreview();
+            } catch (Exception e) {
+                // Ignore
+            }
+
+            try {
+                mCamera.release();
+            } catch (Exception e) {
+                // Ignore
+            }
+
+            mCamera = null;
+        }
+    }
+
+    class WalkAroundEngine extends Engine {
+        private SurfaceHolder mHolder;
+
+        WalkAroundEngine() {
+        }
+
+        @Override
+        public void onCreate(SurfaceHolder surfaceHolder) {
+            super.onCreate(surfaceHolder);
+
+            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+            mHolder = surfaceHolder;
+        }
+
+        @Override
+        public void onVisibilityChanged(boolean visible) {
+            if (!visible) {
+                if (mOwner == this) {
+                    stopCamera();
+                }
+            } else {
+                try {
+                    startCamera();
+                    mCamera.setPreviewDisplay(mHolder);
+                    startPreview();
+                } catch (IOException e) {
+                    mCamera.release();
+                    mCamera = null;
+    
+                    Log.e(LOG_TAG, "Error opening the camera", e);                    
+                }
+            }
+        }
+
+        @Override
+        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+            super.onSurfaceChanged(holder, format, width, height);
+
+            if (holder.isCreating()) {
+                try {
+                    if (mCamera.previewEnabled()) mCamera.stopPreview();
+                    mCamera.setPreviewDisplay(holder);
+                } catch (IOException e) {
+                    mCamera.release();
+                    mCamera = null;
+    
+                    Log.e(LOG_TAG, "Error opening the camera", e);
+                }
+            }
+
+            if (isVisible()) startPreview();
+        }
+
+        @Override
+        public void onSurfaceCreated(SurfaceHolder holder) {
+            super.onSurfaceCreated(holder);
+            startCamera();
+        }
+
+        private void startPreview() {
+            final Resources resources = getResources();
+            final boolean portrait = resources.getConfiguration().orientation ==
+                    Configuration.ORIENTATION_PORTRAIT;
+
+            final Camera.Parameters params = mCamera.getParameters();
+            
+            final DisplayMetrics metrics = resources.getDisplayMetrics();
+            final List<Camera.Size> sizes = params.getSupportedPreviewSizes();
+
+            // Try to find a preview size that matches the screen first
+            boolean found = false;
+            for (Camera.Size size : sizes) {
+                if ((portrait &&
+                        size.width == metrics.heightPixels && size.height == metrics.widthPixels) ||
+                    (!portrait &&
+                        size.width == metrics.widthPixels && size.height == metrics.heightPixels)) {
+                    params.setPreviewSize(size.width, size.height);
+                    found = true;
+                }
+            }
+
+            // If no suitable preview size was found, try to find something large enough 
+            if (!found) {
+                for (Camera.Size size : sizes) {
+                    if (size.width >= metrics.widthPixels && size.height >= metrics.heightPixels) {
+                        params.setPreviewSize(size.width, size.height);
+                        found = true;
+                    }
+                }
+            }
+
+            // If no suitable preview size was found, pick the first one
+            if (!found) {
+                // Fill the canvas with black
+                Canvas canvas = null;
+                try {
+                    canvas = mHolder.lockCanvas();
+                    if (canvas != null) canvas.drawColor(0);
+                } finally {
+                    if (canvas != null) mHolder.unlockCanvasAndPost(canvas);
+                }
+
+
+                Camera.Size size = sizes.get(0);
+                params.setPreviewSize(size.width, size.height);
+            }
+
+            params.set("orientation", portrait ? "portrait" : "landscape");
+            mCamera.setParameters(params);
+            mCamera.startPreview();
+        }
+    }
+}