OSDN Git Service

Add View#cancelPendingInputEvents API
[android-x86/frameworks-base.git] / services / common_time / utils.cpp
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define LOG_TAG "common_time"
18 #include <utils/Log.h>
19
20 #include "utils.h"
21
22 namespace android {
23
24 void Timeout::setTimeout(int msec) {
25     if (msec < 0) {
26         mSystemEndTime = 0;
27         return;
28     }
29
30     mSystemEndTime = systemTime() + (static_cast<nsecs_t>(msec) * 1000000);
31 }
32
33 int Timeout::msecTillTimeout(nsecs_t nowTime) {
34     if (!mSystemEndTime) {
35         return -1;
36     }
37
38     if (mSystemEndTime < nowTime) {
39         return 0;
40     }
41
42     nsecs_t delta = mSystemEndTime - nowTime;
43     delta += 999999;
44     delta /= 1000000;
45     if (delta > 0x7FFFFFFF) {
46         return 0x7FFFFFFF;
47     }
48
49     return static_cast<int>(delta);
50 }
51
52 LogRing::LogRing(const char* header, size_t entries)
53     : mSize(entries)
54     , mWr(0)
55     , mIsFull(false)
56     , mHeader(header) {
57     mRingBuffer = new Entry[mSize];
58     if (NULL == mRingBuffer)
59         ALOGE("Failed to allocate log ring with %u entries.", mSize);
60 }
61
62 LogRing::~LogRing() {
63     if (NULL != mRingBuffer)
64         delete[] mRingBuffer;
65 }
66
67 void LogRing::log(int prio, const char* tag, const char* fmt, ...) {
68     va_list argp;
69     va_start(argp, fmt);
70     internalLog(prio, tag, fmt, argp);
71     va_end(argp);
72 }
73
74 void LogRing::log(const char* fmt, ...) {
75     va_list argp;
76     va_start(argp, fmt);
77     internalLog(0, NULL, fmt, argp);
78     va_end(argp);
79 }
80
81 void LogRing::internalLog(int prio,
82                           const char* tag,
83                           const char* fmt,
84                           va_list argp) {
85     if (NULL != mRingBuffer) {
86         Mutex::Autolock lock(&mLock);
87         String8 s(String8::formatV(fmt, argp));
88         Entry* last = NULL;
89
90         if (mIsFull || mWr)
91             last = &(mRingBuffer[(mWr + mSize - 1) % mSize]);
92
93
94         if ((NULL != last) && !last->s.compare(s)) {
95             gettimeofday(&(last->last_ts), NULL);
96             ++last->count;
97         } else {
98             gettimeofday(&mRingBuffer[mWr].first_ts, NULL);
99             mRingBuffer[mWr].last_ts = mRingBuffer[mWr].first_ts;
100             mRingBuffer[mWr].count = 1;
101             mRingBuffer[mWr].s.setTo(s);
102
103             mWr = (mWr + 1) % mSize;
104             if (!mWr)
105                 mIsFull = true;
106         }
107     }
108
109     if (NULL != tag)
110         LOG_PRI_VA(prio, tag, fmt, argp);
111 }
112
113 void LogRing::dumpLog(int fd) {
114     if (NULL == mRingBuffer)
115         return;
116
117     Mutex::Autolock lock(&mLock);
118
119     if (!mWr && !mIsFull)
120         return;
121
122     char buf[1024];
123     int res;
124     size_t start = mIsFull ? mWr : 0;
125     size_t count = mIsFull ? mSize : mWr;
126     static const char* kTimeFmt = "%a %b %d %Y %H:%M:%S";
127
128     res = snprintf(buf, sizeof(buf), "\n%s\n", mHeader);
129     if (res > 0)
130         write(fd, buf, res);
131
132     for (size_t i = 0; i < count; ++i) {
133         struct tm t;
134         char timebuf[64];
135         char repbuf[96];
136         size_t ndx = (start + i) % mSize;
137
138         if (1 != mRingBuffer[ndx].count) {
139             localtime_r(&mRingBuffer[ndx].last_ts.tv_sec, &t);
140             strftime(timebuf, sizeof(timebuf), kTimeFmt, &t);
141             snprintf(repbuf, sizeof(repbuf),
142                     " (repeated %d times, last was %s.%03ld)",
143                      mRingBuffer[ndx].count,
144                      timebuf,
145                      mRingBuffer[ndx].last_ts.tv_usec / 1000);
146             repbuf[sizeof(repbuf) - 1] = 0;
147         } else {
148             repbuf[0] = 0;
149         }
150
151         localtime_r(&mRingBuffer[ndx].first_ts.tv_sec, &t);
152         strftime(timebuf, sizeof(timebuf), kTimeFmt, &t);
153         res = snprintf(buf, sizeof(buf), "[%2d] %s.%03ld :: %s%s\n", 
154                        i, timebuf,
155                        mRingBuffer[ndx].first_ts.tv_usec / 1000,
156                        mRingBuffer[ndx].s.string(),
157                        repbuf);
158
159         if (res > 0)
160             write(fd, buf, res);
161     }
162 }
163
164 }  // namespace android