1f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala/*
2f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * Copyright (C) 2013 The Android Open Source Project
3f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala *
4f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
5f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * you may not use this file except in compliance with the License.
6f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * You may obtain a copy of the License at
7f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala *
8f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
9f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala *
10f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
11f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
12f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * See the License for the specific language governing permissions and
14f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * limitations under the License.
15f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala */
16f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
17f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#define LOG_TAG "Camera3-Status"
18f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
19f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala//#define LOG_NDEBUG 0
20f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
21f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala// This is needed for stdint.h to define INT64_MAX in C++
22f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#define __STDC_LIMIT_MACROS
23f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
24f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <utils/Log.h>
25f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <utils/Trace.h>
26f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <ui/Fence.h>
27f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
28f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include "device3/StatusTracker.h"
29f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include "device3/Camera3Device.h"
30f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
31f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalanamespace android {
32f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
33f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalanamespace camera3 {
34f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
35f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville TalvalaStatusTracker::StatusTracker(wp<Camera3Device> parent) :
36f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mComponentsChanged(false),
37f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mParent(parent),
38f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mNextComponentId(0),
39f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mIdleFence(new Fence()),
40f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mDeviceState(IDLE) {
41f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
42f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
43f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville TalvalaStatusTracker::~StatusTracker() {
44f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
45f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
46f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalaint StatusTracker::addComponent() {
47f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    int id;
48f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ssize_t err;
49f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    {
50f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock l(mLock);
51f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        id = mNextComponentId++;
52f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        ALOGV("%s: Adding new component %d", __FUNCTION__, id);
53f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
54f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        err = mStates.add(id, IDLE);
55f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        ALOGE_IF(err < 0, "%s: Can't add new component %d: %s (%d)",
56f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                __FUNCTION__, id, strerror(-err), err);
57f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
58f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
59f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (err >= 0) {
60f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock pl(mPendingLock);
61f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mComponentsChanged = true;
62f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mPendingChangeSignal.signal();
63f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
64f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
65f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return err < 0 ? err : id;
66f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
67f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
68f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid StatusTracker::removeComponent(int id) {
69f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ssize_t idx;
70f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    {
71f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock l(mLock);
72f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        ALOGV("%s: Removing component %d", __FUNCTION__, id);
73f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        idx = mStates.removeItem(id);
74f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
75f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
76f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (idx >= 0) {
77f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock pl(mPendingLock);
78f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mComponentsChanged = true;
79f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mPendingChangeSignal.signal();
80f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
81f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
82f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return;
83f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
84f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
85f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
86f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid StatusTracker::markComponentIdle(int id, const sp<Fence>& componentFence) {
87f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    markComponent(id, IDLE, componentFence);
88f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
89f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
90f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid StatusTracker::markComponentActive(int id) {
91f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    markComponent(id, ACTIVE, Fence::NO_FENCE);
92f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
93f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
94f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid StatusTracker::markComponent(int id, ComponentState state,
95f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        const sp<Fence>& componentFence) {
96f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("%s: Component %d is now %s", __FUNCTION__, id,
97f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            state == IDLE ? "idle" : "active");
98f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock l(mPendingLock);
99f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
100f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    StateChange newState = {
101f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        id,
102f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        state,
103f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        componentFence
104f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    };
105f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
106f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mPendingChangeQueue.add(newState);
107f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mPendingChangeSignal.signal();
108f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
109f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
110f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid StatusTracker::requestExit() {
111f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // First mark thread dead
112f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Thread::requestExit();
113f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Then exit any waits
114f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mPendingChangeSignal.signal();
115f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
116f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
117f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville TalvalaStatusTracker::ComponentState StatusTracker::getDeviceStateLocked() {
118f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    for (size_t i = 0; i < mStates.size(); i++) {
119f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mStates.valueAt(i) == ACTIVE) {
120f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            ALOGV("%s: Component %d not idle", __FUNCTION__,
121f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                    mStates.keyAt(i));
122f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            return ACTIVE;
123f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
124f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
125f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // - If not yet signaled, getSignalTime returns INT64_MAX
126f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // - If invalid fence or error, returns -1
127f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // - Otherwise returns time of signalling.
128f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Treat -1 as 'signalled', since HAL may not be using fences, and want
129f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // to be able to idle in case of errors.
130f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    nsecs_t signalTime = mIdleFence->getSignalTime();
131f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    bool fencesDone = signalTime != INT64_MAX;
132f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
133f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV_IF(!fencesDone, "%s: Fences still to wait on", __FUNCTION__);
134f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
135f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return fencesDone ? IDLE : ACTIVE;
136f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
137f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
138f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalabool StatusTracker::threadLoop() {
139f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    status_t res;
140f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
141f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Wait for state updates
142f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    {
143f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock pl(mPendingLock);
144f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        while (mPendingChangeQueue.size() == 0 && !mComponentsChanged) {
145f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            res = mPendingChangeSignal.waitRelative(mPendingLock,
146f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                    kWaitDuration);
147f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            if (exitPending()) return false;
148f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            if (res != OK) {
149f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                if (res != TIMED_OUT) {
150f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                    ALOGE("%s: Error waiting on state changes: %s (%d)",
151f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                            __FUNCTION__, strerror(-res), res);
152f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                }
153f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                // TIMED_OUT is expected
154f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                break;
155f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            }
156f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
157f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
158f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
159f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // After new pending states appear, or timeout, check if we're idle.  Even
160f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // with timeout, need to check to account for fences that may still be
161f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // clearing out
162f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    sp<Camera3Device> parent;
163f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    {
164f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock pl(mPendingLock);
165f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock l(mLock);
166f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
167f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // Collect all pending state updates and see if the device
168f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // collectively transitions between idle and active for each one
169f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
170f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // First pass for changed components or fence completions
171f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        ComponentState prevState = getDeviceStateLocked();
172f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (prevState != mDeviceState) {
173f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            // Only collect changes to overall device state
174f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mStateTransitions.add(prevState);
175f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
176f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // For each pending component state update, check if we've transitioned
177f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // to a new overall device state
178f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        for (size_t i = 0; i < mPendingChangeQueue.size(); i++) {
179f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            const StateChange &newState = mPendingChangeQueue[i];
180f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            ssize_t idx = mStates.indexOfKey(newState.id);
181f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            // Ignore notices for unknown components
182f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            if (idx >= 0) {
183f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                // Update single component state
184f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                mStates.replaceValueAt(idx, newState.state);
185f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                mIdleFence = Fence::merge(String8("idleFence"),
186f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                        mIdleFence, newState.fence);
187f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                // .. and see if overall device state has changed
188f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                ComponentState newState = getDeviceStateLocked();
189f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                if (newState != prevState) {
190f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                    mStateTransitions.add(newState);
191f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                }
192f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                prevState = newState;
193f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            }
194f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
195f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mPendingChangeQueue.clear();
196f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mComponentsChanged = false;
197f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
198f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // Store final state after all pending state changes are done with
199f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
200f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mDeviceState = prevState;
201f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        parent = mParent.promote();
202f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
203f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
204f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Notify parent for all intermediate transitions
205f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (mStateTransitions.size() > 0 && parent.get()) {
206f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        for (size_t i = 0; i < mStateTransitions.size(); i++) {
207f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            bool idle = (mStateTransitions[i] == IDLE);
208f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            ALOGV("Camera device is now %s", idle ? "idle" : "active");
209f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            parent->notifyStatus(idle);
210f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
211f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
212f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mStateTransitions.clear();
213f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
214f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return true;
215f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
216f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
217f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala} // namespace android
218f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
219f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala} // namespace camera3
220