CameraTraces.cpp revision ff3e31d2b100d8efd969b358b18e4405c49dd10d
1ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin/*
2ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin * Copyright (C) 2013 The Android Open Source Project
3ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin *
4ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin * you may not use this file except in compliance with the License.
6ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin * You may obtain a copy of the License at
7ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin *
8ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin *
10ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin * Unless required by applicable law or agreed to in writing, software
11ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin * See the License for the specific language governing permissions and
14ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin * limitations under the License.
15ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin */
16ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
17ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#define LOG_TAG "CameraTraces"
18ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#define ATRACE_TAG ATRACE_TAG_CAMERA
19ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin//#define LOG_NDEBUG 0
20ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
21ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include "utils/CameraTraces.h"
22ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include <utils/ProcessCallStack.h>
23ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
24ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include <utils/Mutex.h>
25ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include <utils/List.h>
26ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
27ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include <utils/Log.h>
28ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include <cutils/trace.h>
29ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
30ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkinnamespace android {
31ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkinnamespace camera3 {
32ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
33ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkinstruct CameraTracesImpl {
34ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    Mutex                    tracesLock;
35ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    List<ProcessCallStack>   pcsList;
36ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin}; // class CameraTraces::Impl;
37ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
38ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkinstatic CameraTracesImpl gImpl;
39ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor MurashkinCameraTracesImpl& CameraTraces::sImpl = gImpl;
40ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
41ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkinvoid CameraTraces::saveTrace() {
42ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    ALOGV("%s: begin", __FUNCTION__);
43ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    ATRACE_BEGIN("CameraTraces::saveTrace");
44ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    Mutex::Autolock al(sImpl.tracesLock);
45ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
46ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    List<ProcessCallStack>& pcsList = sImpl.pcsList;
47ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
48ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    // Insert new ProcessCallStack, and immediately crawl all the threads
49ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    pcsList.push_front(ProcessCallStack());
50ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    ProcessCallStack& pcs = *pcsList.begin();
51ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    pcs.update();
52ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
53ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    if (pcsList.size() > MAX_TRACES) {
54ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin        // Prune list periodically and discard oldest entry
55ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin        pcsList.erase(--pcsList.end());
56ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    }
57ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
58ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    IF_ALOGV() {
59ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin        pcs.log(LOG_TAG, ANDROID_LOG_VERBOSE);
60ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    }
61ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
62ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    ALOGD("Process trace saved. Use dumpsys media.camera to view.");
63ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
64ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    ATRACE_END();
65ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin}
66ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
67ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkinstatus_t CameraTraces::dump(int fd, const Vector<String16> &args __attribute__((unused))) {
68ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    ALOGV("%s: fd = %d", __FUNCTION__, fd);
69ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    Mutex::Autolock al(sImpl.tracesLock);
70ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    List<ProcessCallStack>& pcsList = sImpl.pcsList;
71ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
72ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    if (fd < 0) {
73ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin        ALOGW("%s: Negative FD (%d)", __FUNCTION__, fd);
74ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin        return BAD_VALUE;
75ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    }
76ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
77ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    fdprintf(fd, "Camera traces (%zu):\n", pcsList.size());
78ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
79ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    if (pcsList.empty()) {
80ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin        fdprintf(fd, "  No camera traces collected.\n");
81ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    }
82ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
83ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    // Print newest items first
84ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    List<ProcessCallStack>::iterator it, end;
85ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    for (it = pcsList.begin(), end = pcsList.end(); it != end; ++it) {
86ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin        const ProcessCallStack& pcs = *it;
87ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin        pcs.dump(fd, DUMP_INDENT);
88ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    }
89ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
90ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    return OK;
91ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin}
92ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
93ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin}; // namespace camera3
94ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin}; // namespace android
95