Home | History | Annotate | Download | only in state
      1 /*
      2  * Copyright (C) 2015 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.camera.captureintent.state;
     18 
     19 import com.google.common.base.Optional;
     20 
     21 import com.android.camera.async.RefCountBase;
     22 import com.android.camera.captureintent.CaptureIntentConfig;
     23 import com.android.camera.captureintent.resource.ResourceConstructed;
     24 import com.android.camera.captureintent.stateful.State;
     25 import com.android.camera.captureintent.stateful.StateImpl;
     26 import com.android.camera.debug.Log;
     27 import com.android.camera.util.CameraUtil;
     28 
     29 import android.content.Intent;
     30 import android.graphics.Bitmap;
     31 import android.net.Uri;
     32 import android.os.Bundle;
     33 import android.provider.MediaStore;
     34 
     35 import java.io.IOException;
     36 import java.io.OutputStream;
     37 
     38 /**
     39  * Represents a state that the module is saving the picture to disk.
     40  */
     41 public class StateSavingPicture extends StateImpl {
     42     private static final Log.Tag TAG = new Log.Tag("StateSavePic");
     43 
     44     private final RefCountBase<ResourceConstructed> mResourceConstructed;
     45     private final byte[] mPictureData;
     46 
     47     public static StateSavingPicture from(
     48             StateReviewingPicture reviewingPicture,
     49             RefCountBase<ResourceConstructed> resourceConstructed,
     50             byte[] pictureData) {
     51         return new StateSavingPicture(reviewingPicture, resourceConstructed, pictureData);
     52     }
     53 
     54     private StateSavingPicture(
     55             State previousState,
     56             RefCountBase<ResourceConstructed> resourceConstructed,
     57             byte[] pictureData) {
     58         super(previousState);
     59         mResourceConstructed = resourceConstructed;
     60         mResourceConstructed.addRef();  // Will be balanced in onLeave().
     61         mPictureData = pictureData;
     62     }
     63 
     64     @Override
     65     public Optional<State> onEnter() {
     66         /**
     67          * The caller may pass an extra EXTRA_OUTPUT to control where this
     68          * image will be written. If the EXTRA_OUTPUT is not present, then
     69          * a small sized image is returned as a Bitmap object in the extra
     70          * field. This is useful for applications that only need a small
     71          * image. If the EXTRA_OUTPUT is present, then the full-sized image
     72          * will be written to the Uri value of EXTRA_OUTPUT.
     73          */
     74         Optional<Uri> saveUri = Optional.absent();
     75         final Bundle myExtras = mResourceConstructed.get().getIntent().getExtras();
     76         if (myExtras != null) {
     77             saveUri = Optional.of((Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT));
     78             String cropValue = myExtras.getString("crop");
     79         }
     80 
     81         if (saveUri.isPresent()) {
     82             OutputStream outputStream = null;
     83             try {
     84                 outputStream = mResourceConstructed.get().getContext().getContentResolver()
     85                         .openOutputStream(saveUri.get());
     86                 outputStream.write(mPictureData);
     87                 outputStream.close();
     88 
     89                 Log.v(TAG, "saved result to URI: " + saveUri);
     90                 return Optional.of((State) StateIntentCompleted.from(
     91                         this, mResourceConstructed, new Intent()));
     92             } catch (IOException ex) {
     93                 Log.e(TAG, "exception while saving result to URI: " + saveUri, ex);
     94             } finally {
     95                 CameraUtil.closeSilently(outputStream);
     96             }
     97         } else {
     98             /** Inline the bitmap into capture intent result */
     99             final Bitmap bitmap = CameraUtil.makeBitmap(
    100                     mPictureData, CaptureIntentConfig.INLINE_BITMAP_MAX_PIXEL_NUM);
    101             return Optional.of((State) StateIntentCompleted.from(
    102                     this, mResourceConstructed,
    103                     new Intent("inline-data").putExtra("data", bitmap)));
    104         }
    105         return Optional.of((State) StateIntentCompleted.from(this, mResourceConstructed));
    106     }
    107 
    108     @Override
    109     public void onLeave() {
    110         mResourceConstructed.close();
    111     }
    112 }