Loading services/camera/libcameraservice/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ LOCAL_SRC_FILES:= \ device3/Camera3ZslStream.cpp \ device3/StatusTracker.cpp \ gui/RingBufferConsumer.cpp \ utils/CameraTraces.cpp \ LOCAL_SHARED_LIBRARIES:= \ libui \ Loading services/camera/libcameraservice/CameraService.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include "api1/Camera2Client.h" #include "api_pro/ProCamera2Client.h" #include "api2/CameraDeviceClient.h" #include "utils/CameraTraces.h" #include "CameraDeviceFactory.h" namespace android { Loading Loading @@ -1219,6 +1220,10 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { if (locked) mServiceLock.unlock(); // Dump camera traces if there were any write(fd, "\n", 1); camera3::CameraTraces::dump(fd, args); // change logging level int n = args.size(); for (int i = 0; i + 1 < n; i++) { Loading services/camera/libcameraservice/device3/Camera3Device.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #include <utils/Trace.h> #include <utils/Timers.h> #include "utils/CameraTraces.h" #include "device3/Camera3Device.h" #include "device3/Camera3OutputStream.h" #include "device3/Camera3InputStream.h" Loading Loading @@ -1363,6 +1364,10 @@ void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) { // But only do error state transition steps for the first error if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return; // Save stack trace. View by dumping it later. CameraTraces::saveTrace(); // TODO: consider adding errorCause and client pid/procname mErrorCause = errorCause; mRequestThread->setPaused(true); Loading services/camera/libcameraservice/utils/CameraTraces.cpp 0 → 100644 +94 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "CameraTraces" #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 #include "utils/CameraTraces.h" #include <utils/ProcessCallStack.h> #include <utils/Mutex.h> #include <utils/List.h> #include <utils/Log.h> #include <cutils/trace.h> namespace android { namespace camera3 { struct CameraTracesImpl { Mutex tracesLock; List<ProcessCallStack> pcsList; }; // class CameraTraces::Impl; static CameraTracesImpl gImpl; CameraTracesImpl& CameraTraces::sImpl = gImpl; void CameraTraces::saveTrace() { ALOGV("%s: begin", __FUNCTION__); ATRACE_BEGIN("CameraTraces::saveTrace"); Mutex::Autolock al(sImpl.tracesLock); List<ProcessCallStack>& pcsList = sImpl.pcsList; // Insert new ProcessCallStack, and immediately crawl all the threads pcsList.push_front(ProcessCallStack()); ProcessCallStack& pcs = *pcsList.begin(); pcs.update(); if (pcsList.size() > MAX_TRACES) { // Prune list periodically and discard oldest entry pcsList.erase(--pcsList.end()); } IF_ALOGV() { pcs.log(LOG_TAG, ANDROID_LOG_VERBOSE); } ALOGD("Process trace saved. Use dumpsys media.camera to view."); ATRACE_END(); } status_t CameraTraces::dump(int fd, const Vector<String16> &args __attribute__((unused))) { ALOGV("%s: fd = %d", __FUNCTION__, fd); Mutex::Autolock al(sImpl.tracesLock); List<ProcessCallStack>& pcsList = sImpl.pcsList; if (fd < 0) { ALOGW("%s: Negative FD (%d)", __FUNCTION__, fd); return BAD_VALUE; } fdprintf(fd, "Camera traces (%zu):\n", pcsList.size()); if (pcsList.empty()) { fdprintf(fd, " No camera traces collected.\n"); } // Print newest items first List<ProcessCallStack>::iterator it, end; for (it = pcsList.begin(), end = pcsList.end(); it != end; ++it) { const ProcessCallStack& pcs = *it; pcs.dump(fd, DUMP_INDENT); } return OK; } }; // namespace camera3 }; // namespace android services/camera/libcameraservice/utils/CameraTraces.h 0 → 100644 +66 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_SERVERS_CAMERA_TRACES_H_ #define ANDROID_SERVERS_CAMERA_TRACES_H_ #include <utils/Errors.h> #include <utils/String16.h> #include <utils/Vector.h> namespace android { namespace camera3 { class CameraTracesImpl; // Collect a list of the process's stack traces class CameraTraces { public: /** * Save the current stack trace for each thread in the process. At most * MAX_TRACES will be saved, after which the oldest traces will be discarded. * * <p>Use CameraTraces::dump to print out the traces.</p> */ static void saveTrace(); /** * Prints all saved traces to the specified file descriptor. * * <p>Each line is indented by DUMP_INDENT spaces.</p> */ static status_t dump(int fd, const Vector<String16>& args); private: enum { // Don't collect more than 100 traces. Discard oldest. MAX_TRACES = 100, // Insert 2 spaces when dumping the traces DUMP_INDENT = 2, }; CameraTraces(); ~CameraTraces(); CameraTraces(CameraTraces& rhs); static CameraTracesImpl& sImpl; }; // class CameraTraces }; // namespace camera3 }; // namespace android #endif // ANDROID_SERVERS_CAMERA_TRACES_H_ Loading
services/camera/libcameraservice/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ LOCAL_SRC_FILES:= \ device3/Camera3ZslStream.cpp \ device3/StatusTracker.cpp \ gui/RingBufferConsumer.cpp \ utils/CameraTraces.cpp \ LOCAL_SHARED_LIBRARIES:= \ libui \ Loading
services/camera/libcameraservice/CameraService.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include "api1/Camera2Client.h" #include "api_pro/ProCamera2Client.h" #include "api2/CameraDeviceClient.h" #include "utils/CameraTraces.h" #include "CameraDeviceFactory.h" namespace android { Loading Loading @@ -1219,6 +1220,10 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { if (locked) mServiceLock.unlock(); // Dump camera traces if there were any write(fd, "\n", 1); camera3::CameraTraces::dump(fd, args); // change logging level int n = args.size(); for (int i = 0; i + 1 < n; i++) { Loading
services/camera/libcameraservice/device3/Camera3Device.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #include <utils/Trace.h> #include <utils/Timers.h> #include "utils/CameraTraces.h" #include "device3/Camera3Device.h" #include "device3/Camera3OutputStream.h" #include "device3/Camera3InputStream.h" Loading Loading @@ -1363,6 +1364,10 @@ void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) { // But only do error state transition steps for the first error if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return; // Save stack trace. View by dumping it later. CameraTraces::saveTrace(); // TODO: consider adding errorCause and client pid/procname mErrorCause = errorCause; mRequestThread->setPaused(true); Loading
services/camera/libcameraservice/utils/CameraTraces.cpp 0 → 100644 +94 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "CameraTraces" #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 #include "utils/CameraTraces.h" #include <utils/ProcessCallStack.h> #include <utils/Mutex.h> #include <utils/List.h> #include <utils/Log.h> #include <cutils/trace.h> namespace android { namespace camera3 { struct CameraTracesImpl { Mutex tracesLock; List<ProcessCallStack> pcsList; }; // class CameraTraces::Impl; static CameraTracesImpl gImpl; CameraTracesImpl& CameraTraces::sImpl = gImpl; void CameraTraces::saveTrace() { ALOGV("%s: begin", __FUNCTION__); ATRACE_BEGIN("CameraTraces::saveTrace"); Mutex::Autolock al(sImpl.tracesLock); List<ProcessCallStack>& pcsList = sImpl.pcsList; // Insert new ProcessCallStack, and immediately crawl all the threads pcsList.push_front(ProcessCallStack()); ProcessCallStack& pcs = *pcsList.begin(); pcs.update(); if (pcsList.size() > MAX_TRACES) { // Prune list periodically and discard oldest entry pcsList.erase(--pcsList.end()); } IF_ALOGV() { pcs.log(LOG_TAG, ANDROID_LOG_VERBOSE); } ALOGD("Process trace saved. Use dumpsys media.camera to view."); ATRACE_END(); } status_t CameraTraces::dump(int fd, const Vector<String16> &args __attribute__((unused))) { ALOGV("%s: fd = %d", __FUNCTION__, fd); Mutex::Autolock al(sImpl.tracesLock); List<ProcessCallStack>& pcsList = sImpl.pcsList; if (fd < 0) { ALOGW("%s: Negative FD (%d)", __FUNCTION__, fd); return BAD_VALUE; } fdprintf(fd, "Camera traces (%zu):\n", pcsList.size()); if (pcsList.empty()) { fdprintf(fd, " No camera traces collected.\n"); } // Print newest items first List<ProcessCallStack>::iterator it, end; for (it = pcsList.begin(), end = pcsList.end(); it != end; ++it) { const ProcessCallStack& pcs = *it; pcs.dump(fd, DUMP_INDENT); } return OK; } }; // namespace camera3 }; // namespace android
services/camera/libcameraservice/utils/CameraTraces.h 0 → 100644 +66 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_SERVERS_CAMERA_TRACES_H_ #define ANDROID_SERVERS_CAMERA_TRACES_H_ #include <utils/Errors.h> #include <utils/String16.h> #include <utils/Vector.h> namespace android { namespace camera3 { class CameraTracesImpl; // Collect a list of the process's stack traces class CameraTraces { public: /** * Save the current stack trace for each thread in the process. At most * MAX_TRACES will be saved, after which the oldest traces will be discarded. * * <p>Use CameraTraces::dump to print out the traces.</p> */ static void saveTrace(); /** * Prints all saved traces to the specified file descriptor. * * <p>Each line is indented by DUMP_INDENT spaces.</p> */ static status_t dump(int fd, const Vector<String16>& args); private: enum { // Don't collect more than 100 traces. Discard oldest. MAX_TRACES = 100, // Insert 2 spaces when dumping the traces DUMP_INDENT = 2, }; CameraTraces(); ~CameraTraces(); CameraTraces(CameraTraces& rhs); static CameraTracesImpl& sImpl; }; // class CameraTraces }; // namespace camera3 }; // namespace android #endif // ANDROID_SERVERS_CAMERA_TRACES_H_