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