Home | History | Annotate | Download | only in imagebackend
      1 /*
      2  * Copyright (C) 2014 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.processing.imagebackend;
     18 
     19 import com.google.common.base.Optional;
     20 
     21 import android.content.Context;
     22 import android.location.Location;
     23 
     24 import com.android.camera.app.CameraServices;
     25 import com.android.camera.debug.Log;
     26 import com.android.camera.processing.ProcessingTask;
     27 import com.android.camera.session.CaptureSession;
     28 
     29 import java.util.concurrent.locks.Condition;
     30 
     31 import javax.annotation.Nullable;
     32 import javax.annotation.ParametersAreNonnullByDefault;
     33 
     34 /**
     35  * Implements a placeholder task so that ImageBackend can communicate to the
     36  * ProcessingServiceManager, when it is running a set of task created by the
     37  * receiveImage call. The ImageShadow tasks also contains a Runnable which can
     38  * be executed when the set of TaskImageContainers associated with the
     39  * ImageShadow tasks completes. This implementation of the ProcessingTask will
     40  * block the ProcessingServiceManager from running any other jobs. However,
     41  * ProcessingServiceManager has no thread control over the ImageBackend. So
     42  * while ProcessingServiceManager may queue up this ImageShadowTask for later
     43  * execution, the ImageBackend will process the TaskImageContainer jobs without
     44  * regard to this ImageShadowTask being queued.
     45  */
     46 @ParametersAreNonnullByDefault
     47 class ImageShadowTask implements ProcessingTask {
     48     static final private Log.Tag TAG = new Log.Tag("ImageShadowTask");
     49 
     50     private final CaptureSession mCaptureSession;
     51     private final ImageBackend.BlockSignalProtocol mProtocol;
     52     private final Runnable mRunnableWhenDone;
     53     private ProcessingTaskDoneListener mDoneListener;
     54     private Condition mSignal;
     55 
     56     /**
     57      * Constructor
     58      *
     59      * @param protocol the blocking implementation that will keep this shadow
     60      *            task from completing before all of its associated subtasks are
     61      *            done
     62      * @param captureSession the capture session associated with this shadow
     63      *            task
     64      * @param runnableWhenDone optional runnable to be executed when all the
     65      *            associated sub-tasks of the ImageShadowTask are completed.
     66      *            This runnable will be executed on the Executor of the last
     67      *            subtask that completes (as specified in TaskImageContainer).
     68      *            This underlying runnable is a part of the ImageBackend
     69      *            infrastructure, and should NOT be associated with the
     70      *            ProcessingTask implementation.
     71      */
     72     ImageShadowTask(ImageBackend.BlockSignalProtocol protocol,
     73             CaptureSession captureSession, Optional<Runnable> runnableWhenDone) {
     74         mProtocol = protocol;
     75         mCaptureSession = captureSession;
     76         if(runnableWhenDone.isPresent()) {
     77             mRunnableWhenDone = runnableWhenDone.get();
     78         } else {
     79             mRunnableWhenDone = null;
     80         }
     81     }
     82 
     83     ImageBackend.BlockSignalProtocol getProtocol() {
     84         return mProtocol;
     85     }
     86 
     87     /**
     88      * Returns the Runnable to be executed when all the associated
     89      * TaskImageContainer of ImageShadowTask have been completed.
     90      */
     91     public Runnable getRunnableWhenDone() {
     92         return mRunnableWhenDone;
     93     }
     94 
     95     @Override
     96     public ProcessingResult process(Context context, CameraServices services, CaptureSession session) {
     97         try {
     98             mProtocol.block();
     99         } catch (InterruptedException e) {
    100             // Exit cleanly on Interrupt.
    101             Log.w(TAG, "Image Shadow task Interrupted.");
    102         }
    103 
    104         ProcessingResult finalResult = new ProcessingResult(true, mCaptureSession);
    105         // Always finishes alright.
    106         if (mDoneListener != null) {
    107             mDoneListener.onDone(finalResult);
    108         }
    109         return finalResult;
    110     }
    111 
    112     @Override
    113     public void suspend() {
    114         // Do nothing. We are unsuspendable.
    115     }
    116 
    117     @Override
    118     public void resume() {
    119         // Do nothing. We are unresumable.
    120     }
    121 
    122     @Override
    123     public String getName() {
    124         // Name is only required when Session is NULL. Session should never be
    125         // set to NULL.
    126         return null;
    127     }
    128 
    129     @Override
    130     public Location getLocation() {
    131         return null;
    132     }
    133 
    134     @Override
    135     public CaptureSession getSession() {
    136         return mCaptureSession;
    137     }
    138 
    139     @Override
    140     public void setDoneListener(ProcessingTaskDoneListener listener) {
    141         mDoneListener = listener;
    142     }
    143 
    144 }
    145