FrameProcessorBase.cpp revision 204e3295e2814052aef7e45ee9edd60128efbbd0
127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/*
227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Copyright (C) 2013 The Android Open Source Project
327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Licensed under the Apache License, Version 2.0 (the "License");
527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * you may not use this file except in compliance with the License.
627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * You may obtain a copy of the License at
727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *      http://www.apache.org/licenses/LICENSE-2.0
927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
1027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Unless required by applicable law or agreed to in writing, software
1127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * distributed under the License is distributed on an "AS IS" BASIS,
1227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * See the License for the specific language governing permissions and
1427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * limitations under the License.
1527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi */
1627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
172272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi#define LOG_TAG "Camera2-FrameProcessorBase"
1827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#define ATRACE_TAG ATRACE_TAG_CAMERA
1927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//#define LOG_NDEBUG 0
2027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <utils/Log.h>
2227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <utils/Trace.h>
2327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
24927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski#include "common/FrameProcessorBase.h"
2527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "common/CameraDeviceBase.h"
2627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
27927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinskinamespace android {
2827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshinamespace camera2 {
2927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiFrameProcessorBase::FrameProcessorBase(wp<CameraDeviceBase> device) :
3127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Thread(/*canCallJava*/false),
3227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    mDevice(device),
338d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang    mNumPartialResults(1) {
348d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang    sp<CameraDeviceBase> cameraDevice = device.promote();
358d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang    if (cameraDevice != 0 &&
3627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            cameraDevice->getDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_2) {
3727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        CameraMetadata staticInfo = cameraDevice->info();
388f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang        camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
398f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang        if (entry.count > 0) {
40927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski            mNumPartialResults = entry.data.i32[0];
41927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski        }
42927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski    }
43927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski}
44927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski
45927634a98167e24241b89d80a1ea4511c0bb9cd1Adam LesinskiFrameProcessorBase::~FrameProcessorBase() {
4627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    ALOGV("%s: Exit", __FUNCTION__);
4727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
4827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
492272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t FrameProcessorBase::registerListener(int32_t minId,
5027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        int32_t maxId, wp<FilteredListener> listener, bool sendPartials) {
5127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Mutex::Autolock l(mInputMutex);
5227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    List<RangeListener>::iterator item = mRangeListeners.begin();
538d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang    while (item != mRangeListeners.end()) {
548d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang        if (item->minId == minId &&
55927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski                item->maxId == maxId &&
56927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski                item->listener == listener) {
57927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski            // already registered, just return
58927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski            ALOGV("%s: Attempt to register the same client twice, ignoring",
59927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski                    __FUNCTION__);
60927634a98167e24241b89d80a1ea4511c0bb9cd1Adam Lesinski            return OK;
6127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
6227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        item++;
6327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
6427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    ALOGV("%s: Registering listener for frame id range %d - %d",
6527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            __FUNCTION__, minId, maxId);
6627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    RangeListener rListener = { minId, maxId, listener, sendPartials };
6727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    mRangeListeners.push_back(rListener);
685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    return OK;
6927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
7027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
7127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatus_t FrameProcessorBase::removeListener(int32_t minId,
7227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                           int32_t maxId,
7327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                           wp<FilteredListener> listener) {
748d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang    Mutex::Autolock l(mInputMutex);
758d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang    List<RangeListener>::iterator item = mRangeListeners.begin();
768d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang    while (item != mRangeListeners.end()) {
778d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang        if (item->minId == minId &&
788d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang                item->maxId == maxId &&
7927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                item->listener == listener) {
808d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang            item = mRangeListeners.erase(item);
8127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        } else {
8227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            item++;
83e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        }
84e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    }
8527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return OK;
8627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
87e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi
88e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimivoid FrameProcessorBase::dump(int fd, const Vector<String16>& /*args*/) {
8927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    String8 result("    Latest received frame:\n");
9027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    write(fd, result.string(), result.size());
9127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
92b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    CameraMetadata lastFrame;
93b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    {
9427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        // Don't race while dumping metadata
9527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        Mutex::Autolock al(mLastFrameMutex);
96c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi        lastFrame = CameraMetadata(mLastFrame);
97c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi    }
9827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    lastFrame.dump(fd, 2, 6);
9927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
10027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
10127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool FrameProcessorBase::threadLoop() {
10227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    status_t res;
10327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
104b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    sp<CameraDeviceBase> device;
105b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    {
10627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        device = mDevice.promote();
10727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (device == 0) return false;
10827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
10927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
1103473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    res = device->waitForNextFrame(kWaitDuration);
1113473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    if (res == OK) {
1123473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi        processNewFrames(device);
1133473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    } else if (res != TIMED_OUT) {
1143473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi        ALOGE("FrameProcessorBase: Error waiting for new "
1153473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi                "frames: %s (%d)", strerror(-res), res);
1163473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    }
1173473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi
118b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    return true;
119b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang}
12027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
12127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshivoid FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) {
12227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    status_t res;
12327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    ATRACE_CALL();
12427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    CaptureResult result;
12527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
12627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId());
127b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang
128b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    while ( (res = device->getNextResult(&result)) == OK) {
12927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
13027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        // TODO: instead of getting frame number from metadata, we should read
13127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        // this from result.mResultExtras when CameraDeviceBase interface is fixed.
13227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        camera_metadata_entry_t entry;
13327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
13427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
13527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (entry.count == 0) {
136b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang            ALOGE("%s: Camera %d: Error reading frame number",
137b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang                    __FUNCTION__, device->getId());
13827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            break;
13927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
14027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        ATRACE_INT("cam2_frame", entry.data.i32[0]);
14127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
14227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (!processSingleFrame(result, device)) {
14327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            break;
14427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
1452272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
14627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (!result.mMetadata.isEmpty()) {
1478d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang            Mutex::Autolock al(mLastFrameMutex);
148b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang            mLastFrame.acquire(result.mMetadata);
14927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
15027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
151b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    if (res != NOT_ENOUGH_DATA) {
152bf5b3b29e31b293313788d7464cfb258ac0da803James Dong        ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
15327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                __FUNCTION__, device->getId(), strerror(-res), res);
15427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return;
155bf5b3b29e31b293313788d7464cfb258ac0da803James Dong    }
15627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
15727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return;
15827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
15927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
16027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool FrameProcessorBase::processSingleFrame(CaptureResult &result,
16127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                            const sp<CameraDeviceBase> &device) {
16227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    ALOGV("%s: Camera %d: Process single frame (is empty? %d)",
16327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi          __FUNCTION__, device->getId(), result.mMetadata.isEmpty());
164b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    return processListeners(result, device) == OK;
165b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang}
16627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
16727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatus_t FrameProcessorBase::processListeners(const CaptureResult &result,
16827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        const sp<CameraDeviceBase> &device) {
16927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    ATRACE_CALL();
17027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
17127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    camera_metadata_ro_entry_t entry;
17227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
17327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    // Check if this result is partial.
174b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    bool isPartialResult = false;
175b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    if (device->getDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_2) {
17627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        isPartialResult = result.mResultExtras.partialResultCount < mNumPartialResults;
17727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    } else {
17827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        entry = result.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT);
17927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (entry.count != 0 &&
1802272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
181b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang            ALOGV("%s: Camera %d: This is a partial result",
182b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang                    __FUNCTION__, device->getId());
1832272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            isPartialResult = true;
184b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang        }
185b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    }
186b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang
18727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    // TODO: instead of getting requestID from CameraMetadata, we should get it
1882272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    // from CaptureResultExtras. This will require changing Camera2Device.
18927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    // Currently Camera2Device uses MetadataQueue to store results, which does not
19027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    // include CaptureResultExtras.
1912272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    entry = result.mMetadata.find(ANDROID_REQUEST_ID);
192b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    if (entry.count == 0) {
193b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang        ALOGE("%s: Camera %d: Error reading frame id", __FUNCTION__, device->getId());
1942272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        return BAD_VALUE;
195b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    }
1962272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    int32_t requestId = entry.data.i32[0];
197b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang
19827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    List<sp<FilteredListener> > listeners;
1992272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    {
20027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        Mutex::Autolock l(mInputMutex);
20127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
20227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        List<RangeListener>::iterator item = mRangeListeners.begin();
203b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang        // Don't deliver partial results to listeners that don't want them
204b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang        while (item != mRangeListeners.end()) {
20527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            if (requestId >= item->minId && requestId < item->maxId &&
20627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                    (!isPartialResult || item->sendPartials)) {
207b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang                sp<FilteredListener> listener = item->listener.promote();
208b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang                if (listener == 0) {
20927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                    item = mRangeListeners.erase(item);
21027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                    continue;
21127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                } else {
21227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                    listeners.push_back(listener);
2132272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                }
2142272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            }
21527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            item++;
2162272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
21727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
2182272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    ALOGV("%s: Camera %d: Got %zu range listeners out of %zu", __FUNCTION__,
21927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi          device->getId(), listeners.size(), mRangeListeners.size());
22027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2212272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    List<sp<FilteredListener> >::iterator item = listeners.begin();
2222272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    for (; item != listeners.end(); item++) {
22327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        (*item)->onResultAvailable(result);
22427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
225b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    return OK;
226b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang}
22727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
22827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}; // namespace camera2
22927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}; // namespace android
23027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi