ProcessingServiceManager.java revision dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2
1dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling/*
2dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * Copyright (C) 2014 The Android Open Source Project
3dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling *
4dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * Licensed under the Apache License, Version 2.0 (the "License");
5dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * you may not use this file except in compliance with the License.
6dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * You may obtain a copy of the License at
7dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling *
8dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling *      http://www.apache.org/licenses/LICENSE-2.0
9dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling *
10dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * Unless required by applicable law or agreed to in writing, software
11dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * distributed under the License is distributed on an "AS IS" BASIS,
12dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * See the License for the specific language governing permissions and
14dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * limitations under the License.
15dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling */
16dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
17dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberlingpackage com.android.camera.processing;
18dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
19dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberlingimport android.content.Context;
20dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberlingimport android.content.Intent;
21dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberlingimport android.util.Log;
22dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
23dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberlingimport java.util.LinkedList;
24dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberlingimport java.util.NoSuchElementException;
25dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
26dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling/**
27dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * Manages a queue of processing tasks as well as the processing service
28dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * lifecycle.
29dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * <p>
30dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * Clients should only use this class and not the {@link ProcessingService}
31dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling * directly.
32dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling */
33dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberlingpublic class ProcessingServiceManager {
34dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    private static final String TAG = "ProcessingServiceManager";
35dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
36dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    /** The singleton instance of this manager. */
37dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    private static ProcessingServiceManager sInstance;
38dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
39dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    /** The application context. */
40dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    private final Context mAppContext;
41dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
42dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    /** Queue of tasks to be processed. */
43dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    private final LinkedList<ProcessingTask> mQueue = new LinkedList<ProcessingTask>();
44dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
45dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    /** Whether a processing service is currently running. */
46dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    private volatile boolean mServiceRunning = false;
47dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
48dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    /**
49dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * Initializes the singleton instance.
50dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     *
51dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * @param context the application context.
52dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     */
53dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    public static void initSingleton(Context appContext) {
54dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        sInstance = new ProcessingServiceManager(appContext);
55dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    }
56dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
57dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    /**
58dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * Note: Make sure to call {@link #initSingleton(Context)} first.
59dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     *
60dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * @return the singleton instance of the processing service manager.
61dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     */
62dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    public static ProcessingServiceManager getInstance() {
63dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        if (sInstance == null) {
64dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling            throw new IllegalStateException("initSingleton() not yet called.");
65dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        }
66dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        return sInstance;
67dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    }
68dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
69dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    private ProcessingServiceManager(Context context) {
70dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        mAppContext = context;
71dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    }
72dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
73dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    /**
74dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * Enqueues a new task. If the service is not already running, it will be
75dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * started.
76dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     *
77dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * @param task The task to be enqueued.
78dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     */
79dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    public synchronized void enqueueTask(ProcessingTask task) {
80dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        mQueue.add(task);
81dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        Log.d(TAG, "Task added. Queue size now: " + mQueue.size());
82dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
83dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        if (!mServiceRunning) {
84dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling            // Starts the service which will then work through the queue. Once
85dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling            // the queue is empty (#popNextSession() returns null), the task
86dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling            // will kill itself automatically and call #stitchingFinished().
87dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling            mAppContext.startService(new Intent(mAppContext, ProcessingService.class));
88dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        }
89dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        mServiceRunning = true;
90dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    }
91dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
92dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    /**
93dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * Remove the next task from the queue and return it.
94dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     *
95dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * @return The next Task or <code>null</code>, of no more tasks are in the
96dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     *         queue.
97dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     */
98dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    public synchronized ProcessingTask popNextSession() {
99dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        try {
100dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling            return mQueue.remove();
101dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        } catch (NoSuchElementException e) {
102dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling            return null;
103dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        }
104dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    }
105dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling
106dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    /**
107dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     * Called by the processing service, notifying us that it has finished.
108dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling     */
109dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    public synchronized void notifyStitchingFinished() {
110dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling        this.mServiceRunning = false;
111dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling    }
112dd2d9e610aa9dc71fe0938f38de43bb0e26f3bb2Sascha Haeberling}
113