Home | History | Annotate | Download | only in walkaround
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.wallpaper.walkaround;
     18 
     19 import android.service.wallpaper.WallpaperService;
     20 import android.view.SurfaceHolder;
     21 import android.hardware.Camera;
     22 import android.util.Log;
     23 import android.util.DisplayMetrics;
     24 import android.graphics.Canvas;
     25 import android.content.res.Configuration;
     26 import android.content.res.Resources;
     27 
     28 import java.io.IOException;
     29 import java.util.List;
     30 
     31 public class WalkAroundWallpaper extends WallpaperService {
     32     private static final String LOG_TAG = "WalkAround";
     33 
     34     private Camera mCamera;
     35     private WalkAroundEngine mOwner;
     36 
     37     public Engine onCreateEngine() {
     38         return mOwner = new WalkAroundEngine();
     39     }
     40 
     41     @Override
     42     public void onDestroy() {
     43         super.onDestroy();
     44         stopCamera();
     45     }
     46 
     47     @Override
     48     public void onCreate() {
     49         super.onCreate();
     50     }
     51 
     52     @Override
     53     public void onConfigurationChanged(Configuration newConfig) {
     54         super.onConfigurationChanged(newConfig);
     55 
     56         if (mCamera != null) {
     57             if (mCamera.previewEnabled()) {
     58                 boolean portrait = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT;
     59                 final Camera.Parameters params = mCamera.getParameters();
     60                 params.set("orientation", portrait ? "portrait" : "landscape");
     61                 mCamera.setParameters(params);
     62 
     63                 if (mCamera.previewEnabled()) mCamera.stopPreview();
     64                 mCamera.startPreview();
     65             }
     66         }
     67     }
     68 
     69     private void startCamera() {
     70         if (mCamera == null) {
     71             mCamera = Camera.open();
     72         } else {
     73             try {
     74                 mCamera.reconnect();
     75             } catch (IOException e) {
     76                 mCamera.release();
     77                 mCamera = null;
     78 
     79                 Log.e(LOG_TAG, "Error opening the camera", e);
     80             }
     81         }
     82     }
     83 
     84     private void stopCamera() {
     85         if (mCamera != null) {
     86             try {
     87                 mCamera.stopPreview();
     88             } catch (Exception e) {
     89                 // Ignore
     90             }
     91 
     92             try {
     93                 mCamera.release();
     94             } catch (Exception e) {
     95                 // Ignore
     96             }
     97 
     98             mCamera = null;
     99         }
    100     }
    101 
    102     class WalkAroundEngine extends Engine {
    103         private SurfaceHolder mHolder;
    104 
    105         WalkAroundEngine() {
    106         }
    107 
    108         @Override
    109         public void onCreate(SurfaceHolder surfaceHolder) {
    110             super.onCreate(surfaceHolder);
    111 
    112             surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    113             mHolder = surfaceHolder;
    114         }
    115 
    116         @Override
    117         public void onVisibilityChanged(boolean visible) {
    118             if (!visible) {
    119                 if (mOwner == this) {
    120                     stopCamera();
    121                 }
    122             } else {
    123                 try {
    124                     startCamera();
    125                     mCamera.setPreviewDisplay(mHolder);
    126                     startPreview();
    127                 } catch (IOException e) {
    128                     mCamera.release();
    129                     mCamera = null;
    130 
    131                     Log.e(LOG_TAG, "Error opening the camera", e);
    132                 }
    133             }
    134         }
    135 
    136         @Override
    137         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    138             super.onSurfaceChanged(holder, format, width, height);
    139 
    140             if (holder.isCreating()) {
    141                 try {
    142                     if (mCamera.previewEnabled()) mCamera.stopPreview();
    143                     mCamera.setPreviewDisplay(holder);
    144                 } catch (IOException e) {
    145                     mCamera.release();
    146                     mCamera = null;
    147 
    148                     Log.e(LOG_TAG, "Error opening the camera", e);
    149                 }
    150             }
    151 
    152             if (isVisible()) startPreview();
    153         }
    154 
    155         @Override
    156         public void onSurfaceCreated(SurfaceHolder holder) {
    157             super.onSurfaceCreated(holder);
    158             startCamera();
    159         }
    160 
    161         private void startPreview() {
    162             final Resources resources = getResources();
    163             final boolean portrait = resources.getConfiguration().orientation ==
    164                     Configuration.ORIENTATION_PORTRAIT;
    165 
    166             final Camera.Parameters params = mCamera.getParameters();
    167 
    168             final DisplayMetrics metrics = resources.getDisplayMetrics();
    169             final List<Camera.Size> sizes = params.getSupportedPreviewSizes();
    170 
    171             // Try to find a preview size that matches the screen first
    172             boolean found = false;
    173             for (Camera.Size size : sizes) {
    174                 if ((portrait &&
    175                         size.width == metrics.heightPixels && size.height == metrics.widthPixels) ||
    176                     (!portrait &&
    177                         size.width == metrics.widthPixels && size.height == metrics.heightPixels)) {
    178                     params.setPreviewSize(size.width, size.height);
    179                     found = true;
    180                 }
    181             }
    182 
    183             // If no suitable preview size was found, try to find something large enough
    184             if (!found) {
    185                 for (Camera.Size size : sizes) {
    186                     if (size.width >= metrics.widthPixels && size.height >= metrics.heightPixels) {
    187                         params.setPreviewSize(size.width, size.height);
    188                         found = true;
    189                     }
    190                 }
    191             }
    192 
    193             // If no suitable preview size was found, pick the first one
    194             if (!found) {
    195                 // Fill the canvas with black
    196                 Canvas canvas = null;
    197                 try {
    198                     canvas = mHolder.lockCanvas();
    199                     if (canvas != null) canvas.drawColor(0);
    200                 } finally {
    201                     if (canvas != null) mHolder.unlockCanvasAndPost(canvas);
    202                 }
    203 
    204 
    205                 Camera.Size size = sizes.get(0);
    206                 params.setPreviewSize(size.width, size.height);
    207             }
    208 
    209             params.set("orientation", portrait ? "portrait" : "landscape");
    210             mCamera.setParameters(params);
    211 
    212             mCamera.startPreview();
    213         }
    214     }
    215 }
    216