1 /*
2 * Copyright (C) 2023 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 #include <time.h>
18 #include <pthread.h>
19 #include <sys/timerfd.h>
20 #include <inttypes.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include <regex.h>
24
25 #include <algorithm>
26 #include <list>
27 #include <memory>
28 #include <set>
29 #include <string>
30 #include <vector>
31 #include <map>
32
33 #define LOG_TAG "AnrTimerService"
34 #define ATRACE_TAG ATRACE_TAG_ACTIVITY_MANAGER
35 #define ANR_TIMER_TRACK "AnrTimerTrack"
36
37 #include <jni.h>
38 #include <nativehelper/JNIHelp.h>
39 #include <android_runtime/AndroidRuntime.h>
40 #include <core_jni_helpers.h>
41
42 #include <processgroup/processgroup.h>
43 #include <utils/Log.h>
44 #include <utils/Mutex.h>
45 #include <utils/Timers.h>
46 #include <utils/Trace.h>
47
48 #include <android-base/logging.h>
49 #include <android-base/stringprintf.h>
50 #include <android-base/unique_fd.h>
51
52 using ::android::base::StringPrintf;
53
54
55 // Native support is unavailable on WIN32 platforms. This macro preemptively disables it.
56 #ifdef _WIN32
57 #define NATIVE_SUPPORT 0
58 #else
59 #define NATIVE_SUPPORT 1
60 #endif
61
62 namespace android {
63
64 // using namespace android;
65
66 // Almost nothing in this module needs to be in the android namespace.
67 namespace {
68
69 // If not on a Posix system, create stub timerfd methods. These are defined to allow
70 // compilation. They are not functional. Also, they do not leak outside this compilation unit.
71 #ifdef _WIN32
timer_create()72 int timer_create() {
73 return -1;
74 }
timer_settime(int,int,void const *,void *)75 int timer_settime(int, int, void const *, void *) {
76 return -1;
77 }
78 #else
79 int timer_create() {
80 return timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
81 }
82 int timer_settime(int fd, int flags, const struct itimerspec *new_value,
83 struct itimerspec *_Nullable old_value) {
84 return timerfd_settime(fd, flags, new_value, old_value);
85 }
86 #endif
87
88 // A local debug flag that gates a set of log messages for debug only. This is normally const
89 // false so the debug statements are not included in the image. The flag can be set true in a
90 // unit test image to debug test failures.
91 const bool DEBUG_TIMER = false;
92
93 // A local debug flag to debug the timer thread itself.
94 const bool DEBUG_TICKER = false;
95
96 // Enable error logging.
97 const bool DEBUG_ERROR = true;
98
99 // Return the current time in nanoseconds. This time is relative to system boot.
now()100 nsecs_t now() {
101 return systemTime(SYSTEM_TIME_MONOTONIC);
102 }
103
104 // The current process. This is cached here on startup.
105 const pid_t sThisProcess = getpid();
106
107 // Return true if the process exists and false if we cannot know.
processExists(pid_t pid)108 bool processExists(pid_t pid) {
109 char path[PATH_MAX];
110 snprintf(path, sizeof(path), "/proc/%d", pid);
111 struct stat buff;
112 return stat(path, &buff) == 0;
113 }
114
115 // Return the name of the process whose pid is the input. If the process does not exist, the
116 // name will "notfound".
getProcessName(pid_t pid)117 std::string getProcessName(pid_t pid) {
118 char path[PATH_MAX];
119 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
120 FILE* cmdline = fopen(path, "r");
121 if (cmdline != nullptr) {
122 char name[PATH_MAX];
123 char const *retval = fgets(name, sizeof(name), cmdline);
124 fclose(cmdline);
125 if (retval == nullptr) {
126 return std::string("unknown");
127 } else {
128 return std::string(name);
129 }
130 } else {
131 return std::string("notfound");
132 }
133 }
134
135 /**
136 * Three wrappers of the trace utilities, which hard-code the timer track.
137 */
traceBegin(const char * msg,int cookie)138 void traceBegin(const char* msg, int cookie) {
139 ATRACE_ASYNC_FOR_TRACK_BEGIN(ANR_TIMER_TRACK, msg, cookie);
140 }
141
traceEnd(int cookie)142 void traceEnd(int cookie) {
143 ATRACE_ASYNC_FOR_TRACK_END(ANR_TIMER_TRACK, cookie);
144 }
145
traceEvent(const char * msg)146 void traceEvent(const char* msg) {
147 ATRACE_INSTANT_FOR_TRACK(ANR_TIMER_TRACK, msg);
148 }
149
150 /**
151 * This class captures tracing information for processes tracked by an AnrTimer. A user can
152 * configure tracing to have the AnrTimerService emit extra information for watched processes.
153 * singleton.
154 *
155 * The tracing configuration has two components: process selection and an optional early action.
156 *
157 * Processes are selected in one of three ways:
158 * 1. A list of numeric linux process IDs.
159 * 2. A regular expression, matched against process names.
160 * 3. The keyword "all", to trace every process that uses an AnrTimer.
161 * Perfetto trace events are always emitted for every operation on a traced process.
162 *
163 * An early action occurs before the scheduled timeout. The early timeout is specified as a
164 * percentage (integer value in the range 0:100) of the programmed timeout. The AnrTimer will
165 * execute the early action at the early timeout. The early action may terminate the timer.
166 *
167 * There is one early action:
168 * 1. Expire - consider the AnrTimer expired and report it to the upper layers.
169 */
170 class AnrTimerTracer {
171 public:
172 // Actions that can be taken when an early timer expires.
173 enum EarlyAction {
174 // Take no action. This is the value used when tracing is disabled.
175 None,
176 // Trace the timer but take no other action.
177 Trace,
178 // Report timer expiration to the upper layers. This is terminal, in that
179 Expire,
180 };
181
182 // The trace information for a single timer.
183 struct TraceConfig {
184 bool enabled = false;
185 EarlyAction action = None;
186 int earlyTimeout = 0;
187 };
188
AnrTimerTracer()189 AnrTimerTracer() {
190 AutoMutex _l(lock_);
191 resetLocked();
192 }
193
194 // Return the TraceConfig for a process.
getConfig(int pid)195 TraceConfig getConfig(int pid) {
196 AutoMutex _l(lock_);
197 // The most likely situation: no tracing is configured.
198 if (!config_.enabled) return {};
199 if (matchAllPids_) return config_;
200 if (watched_.contains(pid)) return config_;
201 if (!matchNames_) return {};
202 if (matchedPids_.contains(pid)) return config_;
203 if (unmatchedPids_.contains(pid)) return {};
204 std::string proc_name = getProcessName(pid);
205 bool matched = regexec(®ex_, proc_name.c_str(), 0, 0, 0) == 0;
206 if (matched) {
207 matchedPids_.insert(pid);
208 return config_;
209 } else {
210 unmatchedPids_.insert(pid);
211 return {};
212 }
213 }
214
215 // Set the trace configuration. The input is a string that contains key/value pairs of the
216 // form "key=value". Pairs are separated by spaces. The function returns a string status.
217 // On success, the normalized config is returned. On failure, the configuration reset the
218 // result contains an error message. As a special case, an empty set of configs, or a
219 // config that contains only the keyword "show", will do nothing except return the current
220 // configuration. On any error, all tracing is disabled.
setConfig(const std::vector<std::string> & config)221 std::pair<bool, std::string> setConfig(const std::vector<std::string>& config) {
222 AutoMutex _l(lock_);
223 if (config.size() == 0) {
224 // Implicit "show"
225 return { true, currentConfigLocked() };
226 } else if (config.size() == 1) {
227 // Process the one-word commands
228 const char* s = config[0].c_str();
229 if (strcmp(s, "show") == 0) {
230 return { true, currentConfigLocked() };
231 } else if (strcmp(s, "off") == 0) {
232 resetLocked();
233 return { true, currentConfigLocked() };
234 } else if (strcmp(s, "help") == 0) {
235 return { true, help() };
236 }
237 } else if (config.size() > 2) {
238 return { false, "unexpected values in config" };
239 }
240
241 // Barring an error in the remaining specification list, tracing will be enabled.
242 resetLocked();
243 // Fetch the process specification. This must be the first configuration entry.
244 {
245 auto result = setTracedProcess(config[0]);
246 if (!result.first) return result;
247 }
248
249 // Process optional actions.
250 if (config.size() > 1) {
251 auto result = setTracedAction(config[1]);
252 if (!result.first) return result;
253 }
254
255 // Accept the result.
256 config_.enabled = true;
257 return { true, currentConfigLocked() };
258 }
259
260 private:
261 // Identify the processes to be traced.
setTracedProcess(std::string config)262 std::pair<bool, std::string> setTracedProcess(std::string config) {
263 const char* s = config.c_str();
264 const char* word = nullptr;
265
266 if (strcmp(s, "pid=all") == 0) {
267 matchAllPids_ = true;
268 } else if ((word = startsWith(s, "pid=")) != nullptr) {
269 int p;
270 int n;
271 while (sscanf(word, "%d%n", &p, &n) == 1) {
272 watched_.insert(p);
273 word += n;
274 if (*word == ',') word++;
275 }
276 if (*word != 0) {
277 return { false, "invalid pid list" };
278 }
279 config_.action = Trace;
280 } else if ((word = startsWith(s, "name=")) != nullptr) {
281 if (matchNames_) {
282 regfree(®ex_);
283 matchNames_ = false;
284 }
285 if (regcomp(®ex_, word, REG_EXTENDED) != 0) {
286 return { false, "invalid regex" };
287 }
288 matchNames_ = true;
289 namePattern_ = word;
290 config_.action = Trace;
291 } else {
292 return { false, "no process specified" };
293 }
294 return { true, "" };
295 }
296
297 // Set the action to be taken on a traced process. The incoming default action is Trace;
298 // this method may overwrite that action.
setTracedAction(std::string config)299 std::pair<bool, std::string> setTracedAction(std::string config) {
300 const char* s = config.c_str();
301 const char* word = nullptr;
302 if (sscanf(s, "expire=%d", &config_.earlyTimeout) == 1) {
303 if (config_.earlyTimeout < 0) {
304 return { false, "invalid expire timeout" };
305 }
306 config_.action = Expire;
307 } else {
308 return { false, std::string("cannot parse action ") + s };
309 }
310 return { true, "" };
311 }
312
313 // Return the string value of an action.
toString(EarlyAction action)314 static const char* toString(EarlyAction action) {
315 switch (action) {
316 case None: return "none";
317 case Trace: return "trace";
318 case Expire: return "expire";
319 }
320 return "unknown";
321 }
322
323 // Return the action represented by the string.
fromString(const char * action)324 static EarlyAction fromString(const char* action) {
325 if (strcmp(action, "expire") == 0) return Expire;
326 return None;
327 }
328
329 // Return the help message. This has everything except the invocation command.
help()330 static std::string help() {
331 static const char* msg =
332 "help show this message\n"
333 "show report the current configuration\n"
334 "off clear the current configuration, turning off all tracing\n"
335 "spec... configure tracing according to the specification list\n"
336 " action=<action> what to do when a split timer expires\n"
337 " expire expire the timer to the upper levels\n"
338 " event generate extra trace events\n"
339 " pid=<pid>[,<pid>] watch the processes in the pid list\n"
340 " pid=all watch every process in the system\n"
341 " name=<regex> watch the processes whose name matches the regex\n";
342 return msg;
343 }
344
345 // A small convenience function for parsing. If the haystack starts with the needle and the
346 // haystack has at least one more character following, return a pointer to the following
347 // character. Otherwise return null.
startsWith(const char * haystack,const char * needle)348 static const char* startsWith(const char* haystack, const char* needle) {
349 if (strncmp(haystack, needle, strlen(needle)) == 0 && strlen(haystack) + strlen(needle)) {
350 return haystack + strlen(needle);
351 }
352 return nullptr;
353 }
354
355 // Return the currently watched pids as a comma-separated list. The lock must be held.
watchedPidsLocked() const356 std::string watchedPidsLocked() const {
357 if (watched_.size() == 0) return "none";
358 bool first = true;
359 std::string result = "";
360 for (auto i = watched_.cbegin(); i != watched_.cend(); i++) {
361 if (first) {
362 result += StringPrintf("%d", *i);
363 first = false;
364 } else {
365 result += StringPrintf(",%d", *i);
366 }
367 }
368 return result;
369 }
370
371 // Return the current configuration, in a form that can be consumed by setConfig().
currentConfigLocked() const372 std::string currentConfigLocked() const {
373 if (!config_.enabled) return "off";
374 std::string result;
375 if (matchAllPids_) {
376 result = "pid=all";
377 } else if (matchNames_) {
378 result = StringPrintf("name=\"%s\"", namePattern_.c_str());
379 } else {
380 result = std::string("pid=") + watchedPidsLocked();
381 }
382 switch (config_.action) {
383 case None:
384 break;
385 case Trace:
386 // The default action is Trace
387 break;
388 case Expire:
389 result += StringPrintf(" %s=%d", toString(config_.action), config_.earlyTimeout);
390 break;
391 }
392 return result;
393 }
394
395 // Reset the current configuration.
resetLocked()396 void resetLocked() {
397 if (!config_.enabled) return;
398
399 config_.enabled = false;
400 config_.earlyTimeout = 0;
401 config_.action = {};
402 matchAllPids_ = false;
403 watched_.clear();
404 if (matchNames_) regfree(®ex_);
405 matchNames_ = false;
406 namePattern_ = "";
407 matchedPids_.clear();
408 unmatchedPids_.clear();
409 }
410
411 // The lock for all operations
412 mutable Mutex lock_;
413
414 // The current tracing information, when a process matches.
415 TraceConfig config_;
416
417 // A short-hand flag that causes all processes to be tracing without the overhead of
418 // searching any of the maps.
419 bool matchAllPids_;
420
421 // A set of process IDs that should be traced. This is updated directly in setConfig()
422 // and only includes pids that were explicitly called out in the configuration.
423 std::set<pid_t> watched_;
424
425 // Name mapping is a relatively expensive operation, since the process name must be fetched
426 // from the /proc file system and then a regex must be evaluated. However, name mapping is
427 // useful to ensure processes are traced at the moment they start. To make this faster, a
428 // process's name is matched only once, and the result is stored in the matchedPids_ or
429 // unmatchedPids_ set, as appropriate. This can lead to confusion if a process changes its
430 // name after it starts.
431
432 // The global flag that enables name matching. If this is disabled then all name matching
433 // is disabled.
434 bool matchNames_;
435
436 // The regular expression that matches processes to be traced. This is saved for logging.
437 std::string namePattern_;
438
439 // The compiled regular expression.
440 regex_t regex_;
441
442 // The set of all pids that whose process names match (or do not match) the name regex.
443 // There is one set for pids that match and one set for pids that do not match.
444 std::set<pid_t> matchedPids_;
445 std::set<pid_t> unmatchedPids_;
446 };
447
448 /**
449 * This class encapsulates the anr timer service. The service manages a list of individual
450 * timers. A timer is either Running or Expired. Once started, a timer may be canceled or
451 * accepted. Both actions collect statistics about the timer and then delete it. An expired
452 * timer may also be discarded, which deletes the timer without collecting any statistics.
453 *
454 * All public methods in this class are thread-safe.
455 */
456 class AnrTimerService {
457 private:
458 class ProcessStats;
459 class Timer;
460
461 public:
462
463 // The class that actually runs the clock.
464 class Ticker;
465
466 // A timer is identified by a timer_id_t. Timer IDs are unique in the moment.
467 using timer_id_t = uint32_t;
468
469 // A manifest constant. No timer is ever created with this ID.
470 static const timer_id_t NOTIMER = 0;
471
472 // A notifier is called with a timer ID, the timer's tag, and the client's cookie. The pid
473 // and uid that were originally assigned to the timer are passed as well. The elapsed time
474 // is the time since the timer was scheduled.
475 using notifier_t = bool (*)(timer_id_t, int pid, int uid, nsecs_t elapsed,
476 void* cookie, jweak object);
477
478 enum Status {
479 Invalid,
480 Running,
481 Expired,
482 Canceled
483 };
484
485 /**
486 * Create a timer service. The service is initialized with a name used for logging. The
487 * constructor is also given the notifier callback, and two cookies for the callback: the
488 * traditional void* and Java object pointer. The remaining parameters are
489 * configuration options.
490 */
491 AnrTimerService(const char* label, notifier_t notifier, void* cookie, jweak jtimer, Ticker*,
492 bool extend, bool freeze);
493
494 // Delete the service and clean up memory.
495 ~AnrTimerService();
496
497 // Start a timer and return the associated timer ID. It does not matter if the same pid/uid
498 // are already in the running list. Once start() is called, one of cancel(), accept(), or
499 // discard() must be called to clean up the internal data structures.
500 timer_id_t start(int pid, int uid, nsecs_t timeout);
501
502 // Cancel a timer and remove it from all lists. This is called when the event being timed
503 // has occurred. If the timer was Running, the function returns true. The other
504 // possibilities are that the timer was Expired or non-existent; in both cases, the function
505 // returns false.
506 bool cancel(timer_id_t timerId);
507
508 // Accept a timer. This is called when the upper layers accept that a timer has expired.
509 // If the timer was Expired and its process was frozen, the timer is pushed to the expired
510 // list and 'true' is returned. Otherwise the function returns false.
511 bool accept(timer_id_t timerId);
512
513 // Discard a timer without collecting any statistics. This is called when the upper layers
514 // recognize that a timer expired but decide the expiration is not significant. If the
515 // timer was Expired, the function returns true. The other possibilities are tha the timer
516 // was Running or non-existing; in both cases, the function returns false.
517 bool discard(timer_id_t timerId);
518
519 // A timer has expired.
520 void expire(timer_id_t);
521
522 // Release a timer. The timer must be in the expired list.
523 bool release(timer_id_t);
524
525 // Configure a trace specification to trace selected timers. See AnrTimerTracer for details.
trace(const std::vector<std::string> & spec)526 static std::pair<bool, std::string> trace(const std::vector<std::string>& spec) {
527 return tracer_.setConfig(spec);
528 }
529
530 // Return the Java object associated with this instance.
jtimer() const531 jweak jtimer() const {
532 return notifierObject_;
533 }
534
535 // Return the per-instance statistics.
536 std::vector<std::string> getDump() const;
537
538 private:
539 // The service cannot be copied.
540 AnrTimerService(const AnrTimerService&) = delete;
541
542 // Insert a timer into the running list. The lock must be held by the caller.
543 void insertLocked(const Timer&);
544
545 // Remove a timer from the lists and return it. The lock must be held by the caller.
546 Timer removeLocked(timer_id_t timerId);
547
548 // Add a timer to the expired list.
549 void addExpiredLocked(const Timer&);
550
551 // Scrub the expired list by removing all entries for non-existent processes. The expired
552 // lock must be held by the caller.
553 void scrubExpiredLocked();
554
555 // Return a string representation of a status value.
556 static const char* statusString(Status);
557
558 // The name of this service, for logging.
559 const std::string label_;
560
561 // The callback that is invoked when a timer expires.
562 const notifier_t notifier_;
563
564 // The two cookies passed to the notifier.
565 void* notifierCookie_;
566 jweak notifierObject_;
567
568 // True if extensions can be granted to expired timers.
569 const bool extend_;
570
571 // True if the service should freeze anr'ed processes.
572 const bool freeze_;
573
574 // The global lock
575 mutable Mutex lock_;
576
577 // The list of all timers that are still running. This is sorted by ID for fast lookup.
578 std::set<Timer> running_;
579
580 // The list of all expired timers that are awaiting release.
581 std::set<Timer> expired_;
582
583 // The maximum number of active timers.
584 size_t maxRunning_;
585
586 // Simple counters
587 struct Counters {
588 // The number of timers started, canceled, accepted, discarded, and expired.
589 size_t started;
590 size_t canceled;
591 size_t accepted;
592 size_t discarded;
593 size_t expired;
594 size_t extended;
595 size_t released;
596
597 // The number of times there were zero active timers.
598 size_t drained;
599
600 // The number of times a protocol error was seen.
601 size_t error;
602 };
603
604 Counters counters_;
605
606 // The clock used by this AnrTimerService.
607 Ticker *ticker_;
608
609 // The global tracing specification.
610 static AnrTimerTracer tracer_;
611 };
612
613 AnrTimerTracer AnrTimerService::tracer_;
614
615 class AnrTimerService::ProcessStats {
616 public:
617 nsecs_t cpu_time;
618 nsecs_t cpu_delay;
619
ProcessStats()620 ProcessStats() :
621 cpu_time(0),
622 cpu_delay(0) {
623 }
624
625 // Collect all statistics for a process. Return true if the fill succeeded and false if it
626 // did not. If there is any problem, the statistics are zeroed.
fill(int pid)627 bool fill(int pid) {
628 cpu_time = 0;
629 cpu_delay = 0;
630
631 char path[PATH_MAX];
632 snprintf(path, sizeof(path), "/proc/%u/schedstat", pid);
633 ::android::base::unique_fd fd(open(path, O_RDONLY | O_CLOEXEC));
634 if (!fd.ok()) {
635 return false;
636 }
637 char buffer[128];
638 ssize_t len = read(fd, buffer, sizeof(buffer));
639 if (len <= 0) {
640 return false;
641 }
642 if (len >= sizeof(buffer)) {
643 ALOGE("proc file too big: %s", path);
644 return false;
645 }
646 buffer[len] = 0;
647 unsigned long t1;
648 unsigned long t2;
649 if (sscanf(buffer, "%lu %lu", &t1, &t2) != 2) {
650 return false;
651 }
652 cpu_time = t1;
653 cpu_delay = t2;
654 return true;
655 }
656 };
657
658 class AnrTimerService::Timer {
659 public:
660 // A unique ID assigned when the Timer is created.
661 const timer_id_t id;
662
663 // The creation parameters. The timeout is the original, relative timeout.
664 const int pid;
665 const int uid;
666 const nsecs_t timeout;
667 // True if the timer may be extended.
668 const bool extend;
669 // True if process should be frozen when its timer expires.
670 const bool freeze;
671 // This is a percentage between 0 and 100. If it is non-zero then timer will fire at
672 // timeout*split/100, and the EarlyAction will be invoked. The timer may continue running
673 // or may expire, depending on the action. Thus, this value "splits" the timeout into two
674 // pieces.
675 const int split;
676 // The action to take if split (above) is non-zero, when the timer reaches the split point.
677 const AnrTimerTracer::EarlyAction action;
678
679 // The state of this timer.
680 Status status;
681
682 // The time at which the timer was started.
683 nsecs_t started;
684
685 // The scheduled timeout. This is an absolute time. It may be extended.
686 nsecs_t scheduled;
687
688 // True if this timer is split and in its second half
689 bool splitting;
690
691 // True if this timer has been extended.
692 bool extended;
693
694 // True if the process has been frozen.
695 bool frozen;
696
697 // Bookkeeping for extensions. The initial state of the process. This is collected only if
698 // the timer is extensible.
699 ProcessStats initial;
700
701 // The default constructor is used to create timers that are Invalid, representing the "not
702 // found" condition when a collection is searched.
Timer()703 Timer() : Timer(NOTIMER) { }
704
705 // This constructor creates a timer with the specified id and everything else set to
706 // "empty". This can be used as the argument to find().
Timer(timer_id_t id)707 Timer(timer_id_t id) :
708 id(id),
709 pid(0),
710 uid(0),
711 timeout(0),
712 extend(false),
713 freeze(false),
714 split(0),
715 action(AnrTimerTracer::None),
716 status(Invalid),
717 started(0),
718 scheduled(0),
719 splitting(false),
720 extended(false),
721 frozen(false) {
722 }
723
724 // Create a new timer. This starts the timer.
Timer(int pid,int uid,nsecs_t timeout,bool extend,bool freeze,AnrTimerTracer::TraceConfig trace)725 Timer(int pid, int uid, nsecs_t timeout, bool extend, bool freeze,
726 AnrTimerTracer::TraceConfig trace) :
727 id(nextId()),
728 pid(pid),
729 uid(uid),
730 timeout(timeout),
731 extend(extend),
732 freeze(freeze),
733 split(trace.earlyTimeout),
734 action(trace.action),
735 status(Running),
736 started(now()),
737 scheduled(started + (split > 0 ? (timeout*split)/100 : timeout)),
738 splitting(false),
739 extended(false),
740 frozen(false) {
741 if (extend && pid != 0) {
742 initial.fill(pid);
743 }
744
745 // A zero-pid is odd but it means the upper layers will never ANR the process. Freezing
746 // is always disabled. (It won't work anyway, but disabling it avoids error messages.)
747 ALOGI_IF(DEBUG_ERROR && pid == 0, "error: zero-pid %s", toString().c_str());
748 }
749
750 // Start a timer. This interface exists to generate log messages, if enabled.
start()751 void start() {
752 event("start", /* verbose= */ true);
753 }
754
755 // Cancel a timer.
cancel()756 void cancel() {
757 ALOGW_IF(DEBUG_ERROR && status != Running, "error: canceling %s", toString().c_str());
758 status = Canceled;
759 event("cancel");
760 }
761
762 // Expire a timer. Return true if the timer is expired and false otherwise. The function
763 // returns false if the timer is eligible for extension. If the function returns false, the
764 // scheduled time is updated.
expire()765 bool expire() {
766 if (split > 0 && !splitting) {
767 scheduled = started + timeout;
768 splitting = true;
769 event("split");
770 switch (action) {
771 case AnrTimerTracer::None:
772 case AnrTimerTracer::Trace:
773 break;
774 case AnrTimerTracer::Expire:
775 status = Expired;
776 maybeFreezeProcess();
777 event("expire");
778 break;
779 }
780 return status == Expired;
781 }
782
783 nsecs_t extension = 0;
784 if (extend && !extended) {
785 // Only one extension is permitted.
786 extended = true;
787 ProcessStats current;
788 current.fill(pid);
789 extension = current.cpu_delay - initial.cpu_delay;
790 if (extension < 0) extension = 0;
791 if (extension > timeout) extension = timeout;
792 }
793 if (extension == 0) {
794 status = Expired;
795 maybeFreezeProcess();
796 event("expire");
797 } else {
798 scheduled += extension;
799 event("extend");
800 }
801 return status == Expired;
802 }
803
804 // Accept a timeout. This does nothing other than log the state machine change.
accept()805 void accept() {
806 event("accept");
807 }
808
809 // Discard a timeout.
discard()810 void discard() {
811 maybeUnfreezeProcess();
812 status = Canceled;
813 event("discard");
814 }
815
816 // Release the timer.
release()817 void release() {
818 // If timer represents a frozen process, unfreeze it at this time.
819 maybeUnfreezeProcess();
820 event("release");
821 }
822
823 // Return true if this timer corresponds to a running process.
alive() const824 bool alive() const {
825 return processExists(pid);
826 }
827
828 // Timers are sorted by id, which is unique. This provides fast lookups.
operator <(Timer const & r) const829 bool operator<(Timer const &r) const {
830 return id < r.id;
831 }
832
operator ==(timer_id_t r) const833 bool operator==(timer_id_t r) const {
834 return id == r;
835 }
836
toString() const837 std::string toString() const {
838 return StringPrintf("id=%d pid=%d uid=%d status=%s",
839 id, pid, uid, statusString(status));
840 }
841
toString(nsecs_t now) const842 std::string toString(nsecs_t now) const {
843 uint32_t ms = nanoseconds_to_milliseconds(now - scheduled);
844 return StringPrintf("id=%d pid=%d uid=%d status=%s scheduled=%ums",
845 id, pid, uid, statusString(status), -ms);
846 }
847
maxId()848 static int maxId() {
849 return idGen;
850 }
851
852 private:
853 /**
854 * Collect the name of the process.
855 */
getName() const856 std::string getName() const {
857 return getProcessName(pid);
858 }
859
860 /**
861 * Freeze the process identified here. Failures are not logged, as they are primarily due
862 * to a process having died (therefore failed to respond).
863 */
maybeFreezeProcess()864 void maybeFreezeProcess() {
865 if (!freeze || !alive()) return;
866
867 // Construct a unique event ID. The id*2 spans from the beginning of the freeze to the
868 // end of the freeze. The id*2+1 spans the period inside the freeze/unfreeze
869 // operations.
870 const uint32_t cookie = id << 1;
871
872 char tag[PATH_MAX];
873 snprintf(tag, sizeof(tag), "freeze(pid=%d,uid=%d)", pid, uid);
874 traceBegin(tag, cookie);
875 if (SetProcessProfiles(uid, pid, {"Frozen"})) {
876 ALOGI("freeze %s name=%s", toString().c_str(), getName().c_str());
877 frozen = true;
878 traceBegin("frozen", cookie+1);
879 } else {
880 ALOGE("error: freezing %s name=%s error=%s",
881 toString().c_str(), getName().c_str(), strerror(errno));
882 traceEnd(cookie);
883 }
884 }
885
maybeUnfreezeProcess()886 void maybeUnfreezeProcess() {
887 if (!freeze || !frozen) return;
888
889 // See maybeFreezeProcess for an explanation of the cookie.
890 const uint32_t cookie = id << 1;
891
892 traceEnd(cookie+1);
893 if (SetProcessProfiles(uid, pid, {"Unfrozen"})) {
894 ALOGI("unfreeze %s name=%s", toString().c_str(), getName().c_str());
895 frozen = false;
896 } else {
897 ALOGE("error: unfreezing %s name=%s error=%s",
898 toString().c_str(), getName().c_str(), strerror(errno));
899 }
900 traceEnd(cookie);
901 }
902
903 // Get the next free ID. NOTIMER is never returned.
nextId()904 static timer_id_t nextId() {
905 timer_id_t id = idGen.fetch_add(1);
906 while (id == NOTIMER) {
907 id = idGen.fetch_add(1);
908 }
909 return id;
910 }
911
912 // Log an event, non-verbose.
event(const char * tag)913 void event(const char* tag) {
914 event(tag, false);
915 }
916
917 // Log an event, guarded by the debug flag.
event(const char * tag,bool verbose)918 void event(const char* tag, bool verbose) {
919 if (action != AnrTimerTracer::None) {
920 char msg[PATH_MAX];
921 snprintf(msg, sizeof(msg), "%s(pid=%d)", tag, pid);
922 traceEvent(msg);
923 }
924 if (verbose) {
925 char name[PATH_MAX];
926 ALOGI_IF(DEBUG_TIMER, "event %s %s name=%s",
927 tag, toString().c_str(), getName().c_str());
928 } else {
929 ALOGI_IF(DEBUG_TIMER, "event %s id=%u", tag, id);
930 }
931 }
932
933 // IDs start at 1. A zero ID is invalid.
934 static std::atomic<timer_id_t> idGen;
935 };
936
937 // IDs start at 1.
938 std::atomic<AnrTimerService::timer_id_t> AnrTimerService::Timer::idGen(1);
939
940 /**
941 * Manage a set of timers and notify clients when there is a timeout.
942 */
943 class AnrTimerService::Ticker {
944 private:
945 struct Entry {
946 const nsecs_t scheduled;
947 const timer_id_t id;
948 AnrTimerService* service;
949
Entryandroid::__anon0ffdf8210111::AnrTimerService::Ticker::Entry950 Entry(nsecs_t scheduled, timer_id_t id, AnrTimerService* service) :
951 scheduled(scheduled), id(id), service(service) {};
952
operator <android::__anon0ffdf8210111::AnrTimerService::Ticker::Entry953 bool operator<(const Entry& r) const {
954 return scheduled == r.scheduled ? id < r.id : scheduled < r.scheduled;
955 }
956 };
957
958 public:
959
960 // Construct the ticker. This creates the timerfd file descriptor and starts the monitor
961 // thread. The monitor thread is given a unique name.
Ticker()962 Ticker() :
963 id_(idGen_.fetch_add(1))
964 {
965 timerFd_ = timer_create();
966 if (timerFd_ < 0) {
967 ALOGE("failed to create timerFd: %s", strerror(errno));
968 return;
969 }
970
971 if (pthread_create(&watcher_, 0, run, this) != 0) {
972 ALOGE("failed to start thread: %s", strerror(errno));
973 watcher_ = 0;
974 ::close(timerFd_);
975 return;
976 }
977
978 // 16 is a magic number from the kernel. Thread names may not be longer than this many
979 // bytes, including the terminating null. The snprintf() method will truncate properly.
980 char name[16];
981 snprintf(name, sizeof(name), "AnrTimerService");
982 pthread_setname_np(watcher_, name);
983
984 ready_ = true;
985 }
986
~Ticker()987 ~Ticker() {
988 // Closing the file descriptor will close the monitor process, if any.
989 if (timerFd_ >= 0) ::close(timerFd_);
990 timerFd_ = -1;
991 watcher_ = 0;
992 }
993
994 // Insert a timer. Unless canceled, the timer will expire at the scheduled time. If it
995 // expires, the service will be notified with the id.
insert(nsecs_t scheduled,timer_id_t id,AnrTimerService * service)996 void insert(nsecs_t scheduled, timer_id_t id, AnrTimerService *service) {
997 Entry e(scheduled, id, service);
998 AutoMutex _l(lock_);
999 timer_id_t front = headTimerId();
1000 running_.insert(e);
1001 if (front != headTimerId()) restartLocked();
1002 maxRunning_ = std::max(maxRunning_, running_.size());
1003 }
1004
1005 // Remove a timer. The timer is identified by its scheduled timeout and id. Technically,
1006 // the id is sufficient (because timer IDs are unique) but using the timeout is more
1007 // efficient.
remove(nsecs_t scheduled,timer_id_t id)1008 void remove(nsecs_t scheduled, timer_id_t id) {
1009 Entry key(scheduled, id, 0);
1010 AutoMutex _l(lock_);
1011 timer_id_t front = headTimerId();
1012 auto found = running_.find(key);
1013 if (found != running_.end()) running_.erase(found);
1014 if (running_.empty()) drained_++;
1015 }
1016
1017 // Remove every timer associated with the service.
remove(const AnrTimerService * service)1018 void remove(const AnrTimerService* service) {
1019 AutoMutex _l(lock_);
1020 timer_id_t front = headTimerId();
1021 for (auto i = running_.begin(); i != running_.end(); ) {
1022 if (i->service == service) {
1023 i = running_.erase(i);
1024 } else {
1025 i++;
1026 }
1027 }
1028 }
1029
1030 // The unique ID of this particular ticker. Used for debug and logging.
id() const1031 size_t id() const {
1032 return id_;
1033 }
1034
1035 // Return the number of timers still running.
running() const1036 size_t running() const {
1037 AutoMutex _l(lock_);
1038 return running_.size();
1039 }
1040
1041 // Return the high-water mark of timers running.
maxRunning() const1042 size_t maxRunning() const {
1043 AutoMutex _l(lock_);
1044 return maxRunning_;
1045 }
1046
1047 private:
1048
1049 // Return the head of the running list. The lock must be held by the caller.
headTimerId()1050 timer_id_t headTimerId() {
1051 return running_.empty() ? NOTIMER : running_.cbegin()->id;
1052 }
1053
1054 // A simple wrapper that meets the requirements of pthread_create.
run(void * arg)1055 static void* run(void* arg) {
1056 reinterpret_cast<Ticker*>(arg)->monitor();
1057 ALOGI_IF(DEBUG_TICKER, "monitor exited");
1058 return 0;
1059 }
1060
1061 // Loop (almost) forever. Whenever the timerfd expires, expire as many entries as
1062 // possible. The loop terminates when the read fails; this generally indicates that the
1063 // file descriptor has been closed and the thread can exit.
monitor()1064 void monitor() {
1065 uint64_t token = 0;
1066 while (read(timerFd_, &token, sizeof(token)) == sizeof(token)) {
1067 // Move expired timers into the local ready list. This is done inside
1068 // the lock. Then, outside the lock, expire them.
1069 nsecs_t current = now();
1070 std::vector<Entry> ready;
1071 {
1072 AutoMutex _l(lock_);
1073 while (!running_.empty()) {
1074 Entry timer = *(running_.begin());
1075 if (timer.scheduled <= current) {
1076 ready.push_back(timer);
1077 running_.erase(running_.cbegin());
1078 } else {
1079 break;
1080 }
1081 }
1082 restartLocked();
1083 }
1084 // Call the notifiers outside the lock. Calling the notifiers with the lock held
1085 // can lead to deadlock, if the Java-side handler also takes a lock. Note that the
1086 // timerfd is already running.
1087 for (auto i = ready.begin(); i != ready.end(); i++) {
1088 Entry e = *i;
1089 e.service->expire(e.id);
1090 }
1091 }
1092 }
1093
1094 // Restart the ticker. The caller must be holding the lock. This method updates the
1095 // timerFd_ to expire at the time of the first Entry in the running list. This method does
1096 // not check to see if the currently programmed expiration time is different from the
1097 // scheduled expiration time of the first entry.
restartLocked()1098 void restartLocked() {
1099 if (!running_.empty()) {
1100 const Entry x = *(running_.cbegin());
1101 nsecs_t delay = x.scheduled - now();
1102 // Force a minimum timeout of 10ns.
1103 if (delay < 10) delay = 10;
1104 time_t sec = nanoseconds_to_seconds(delay);
1105 time_t ns = delay - seconds_to_nanoseconds(sec);
1106 struct itimerspec setting = {
1107 .it_interval = { 0, 0 },
1108 .it_value = { sec, ns },
1109 };
1110 timer_settime(timerFd_, 0, &setting, nullptr);
1111 restarted_++;
1112 ALOGI_IF(DEBUG_TICKER, "restarted timerfd for %ld.%09ld", sec, ns);
1113 } else {
1114 const struct itimerspec setting = {
1115 .it_interval = { 0, 0 },
1116 .it_value = { 0, 0 },
1117 };
1118 timer_settime(timerFd_, 0, &setting, nullptr);
1119 drained_++;
1120 ALOGI_IF(DEBUG_TICKER, "drained timer list");
1121 }
1122 }
1123
1124 // The usual lock.
1125 mutable Mutex lock_;
1126
1127 // True if the object was initialized properly. Android does not support throwing C++
1128 // exceptions, so clients should check this flag after constructing the object. This is
1129 // effectively const after the instance has been created.
1130 bool ready_ = false;
1131
1132 // The file descriptor of the timer.
1133 int timerFd_ = -1;
1134
1135 // The thread that monitors the timer.
1136 pthread_t watcher_ = 0;
1137
1138 // The number of times the timer was restarted.
1139 size_t restarted_ = 0;
1140
1141 // The number of times the timer list was exhausted.
1142 size_t drained_ = 0;
1143
1144 // The highwater mark of timers that are running.
1145 size_t maxRunning_ = 0;
1146
1147 // The list of timers that are scheduled. This set is sorted by timeout and then by timer
1148 // ID. A set is sufficient (as opposed to a multiset) because timer IDs are unique.
1149 std::set<Entry> running_;
1150
1151 // A unique ID assigned to this instance.
1152 const size_t id_;
1153
1154 // The ID generator.
1155 static std::atomic<size_t> idGen_;
1156 };
1157
1158 std::atomic<size_t> AnrTimerService::Ticker::idGen_;
1159
1160
AnrTimerService(const char * label,notifier_t notifier,void * cookie,jweak jtimer,Ticker * ticker,bool extend,bool freeze)1161 AnrTimerService::AnrTimerService(const char* label, notifier_t notifier, void* cookie,
1162 jweak jtimer, Ticker* ticker, bool extend, bool freeze) :
1163 label_(label),
1164 notifier_(notifier),
1165 notifierCookie_(cookie),
1166 notifierObject_(jtimer),
1167 extend_(extend),
1168 freeze_(freeze),
1169 ticker_(ticker) {
1170
1171 // Zero the statistics
1172 maxRunning_ = 0;
1173 memset(&counters_, 0, sizeof(counters_));
1174
1175 ALOGI_IF(DEBUG_TIMER, "initialized %s", label);
1176 }
1177
~AnrTimerService()1178 AnrTimerService::~AnrTimerService() {
1179 AutoMutex _l(lock_);
1180 ticker_->remove(this);
1181 }
1182
statusString(Status s)1183 const char* AnrTimerService::statusString(Status s) {
1184 switch (s) {
1185 case Invalid: return "invalid";
1186 case Running: return "running";
1187 case Expired: return "expired";
1188 case Canceled: return "canceled";
1189 }
1190 return "unknown";
1191 }
1192
start(int pid,int uid,nsecs_t timeout)1193 AnrTimerService::timer_id_t AnrTimerService::start(int pid, int uid, nsecs_t timeout) {
1194 // Use the freezer only if the pid is not 0 (a nonsense value) and the pid is not self.
1195 // Freezing the current process is a fatal error.
1196 bool useFreezer = freeze_ && (pid != 0) && (pid != sThisProcess);
1197 AutoMutex _l(lock_);
1198 Timer t(pid, uid, timeout, extend_, useFreezer, tracer_.getConfig(pid));
1199 insertLocked(t);
1200 t.start();
1201 counters_.started++;
1202 return t.id;
1203 }
1204
cancel(timer_id_t timerId)1205 bool AnrTimerService::cancel(timer_id_t timerId) {
1206 if (timerId == NOTIMER) return false;
1207 AutoMutex _l(lock_);
1208 Timer timer = removeLocked(timerId);
1209
1210 bool result = timer.status == Running;
1211 if (timer.status != Invalid) {
1212 timer.cancel();
1213 } else {
1214 counters_.error++;
1215 }
1216 counters_.canceled++;
1217 return result;
1218 }
1219
accept(timer_id_t timerId)1220 bool AnrTimerService::accept(timer_id_t timerId) {
1221 if (timerId == NOTIMER) return false;
1222 AutoMutex _l(lock_);
1223 Timer timer = removeLocked(timerId);
1224
1225 bool result = false;
1226 if (timer.status == Expired) {
1227 timer.accept();
1228 if (timer.frozen) {
1229 addExpiredLocked(timer);
1230 result = true;
1231 }
1232 } else {
1233 counters_.error++;
1234 }
1235 counters_.accepted++;
1236 return result;
1237 }
1238
discard(timer_id_t timerId)1239 bool AnrTimerService::discard(timer_id_t timerId) {
1240 if (timerId == NOTIMER) return false;
1241 AutoMutex _l(lock_);
1242 Timer timer = removeLocked(timerId);
1243
1244 bool result = timer.status == Expired;
1245 if (timer.status == Expired) {
1246 timer.discard();
1247 } else {
1248 counters_.error++;
1249 }
1250 counters_.discarded++;
1251 return result;
1252 }
1253
release(timer_id_t id)1254 bool AnrTimerService::release(timer_id_t id) {
1255 if (id == NOTIMER) return true;
1256
1257 Timer key(id);
1258 bool okay = false;
1259 AutoMutex _l(lock_);
1260 std::set<Timer>::iterator found = expired_.find(key);
1261 if (found != expired_.end()) {
1262 Timer t = *found;
1263 t.release();
1264 counters_.released++;
1265 expired_.erase(found);
1266 okay = true;
1267 } else {
1268 ALOGI_IF(DEBUG_ERROR, "error: unable to release (%u)", id);
1269 counters_.error++;
1270 }
1271 scrubExpiredLocked();
1272 return okay;
1273 }
1274
addExpiredLocked(const Timer & timer)1275 void AnrTimerService::addExpiredLocked(const Timer& timer) {
1276 scrubExpiredLocked();
1277 expired_.insert(timer);
1278 }
1279
scrubExpiredLocked()1280 void AnrTimerService::scrubExpiredLocked() {
1281 for (auto i = expired_.begin(); i != expired_.end(); ) {
1282 if (!i->alive()) {
1283 i = expired_.erase(i);
1284 } else {
1285 i++;
1286 }
1287 }
1288 }
1289
1290 // Hold the lock in order to manage the running list.
expire(timer_id_t timerId)1291 void AnrTimerService::expire(timer_id_t timerId) {
1292 // Save the timer attributes for the notification
1293 int pid = 0;
1294 int uid = 0;
1295 nsecs_t elapsed = 0;
1296 bool expired = false;
1297 {
1298 AutoMutex _l(lock_);
1299 Timer t = removeLocked(timerId);
1300 expired = t.expire();
1301 if (t.status == Invalid) {
1302 ALOGW_IF(DEBUG_ERROR, "error: expired invalid timer %u", timerId);
1303 return;
1304 } else {
1305 // The timer is either Running (because it was extended) or expired (and is awaiting an
1306 // accept or discard).
1307 insertLocked(t);
1308 }
1309 pid = t.pid;
1310 uid = t.uid;
1311 elapsed = now() - t.started;
1312 }
1313
1314 if (expired) {
1315 counters_.expired++;
1316 } else {
1317 counters_.extended++;
1318 }
1319
1320 // Deliver the notification outside of the lock.
1321 if (expired) {
1322 if (!notifier_(timerId, pid, uid, elapsed, notifierCookie_, notifierObject_)) {
1323 // Notification failed, which means the listener will never call accept() or
1324 // discard(). Do not reinsert the timer.
1325 discard(timerId);
1326 }
1327 }
1328 }
1329
insertLocked(const Timer & t)1330 void AnrTimerService::insertLocked(const Timer& t) {
1331 running_.insert(t);
1332 if (t.status == Running) {
1333 // Only forward running timers to the ticker. Expired timers are handled separately.
1334 ticker_->insert(t.scheduled, t.id, this);
1335 }
1336 maxRunning_ = std::max(maxRunning_, running_.size());
1337 }
1338
removeLocked(timer_id_t timerId)1339 AnrTimerService::Timer AnrTimerService::removeLocked(timer_id_t timerId) {
1340 Timer key(timerId);
1341 auto found = running_.find(key);
1342 if (found != running_.end()) {
1343 Timer result = *found;
1344 running_.erase(found);
1345 ticker_->remove(result.scheduled, result.id);
1346 if (running_.size() == 0) counters_.drained++;
1347 return result;
1348 }
1349 return Timer();
1350 }
1351
getDump() const1352 std::vector<std::string> AnrTimerService::getDump() const {
1353 std::vector<std::string> r;
1354 AutoMutex _l(lock_);
1355 r.push_back(StringPrintf("started:%zu canceled:%zu accepted:%zu discarded:%zu expired:%zu",
1356 counters_.started,
1357 counters_.canceled,
1358 counters_.accepted,
1359 counters_.discarded,
1360 counters_.expired));
1361 r.push_back(StringPrintf("extended:%zu drained:%zu error:%zu running:%zu maxRunning:%zu",
1362 counters_.extended,
1363 counters_.drained,
1364 counters_.error,
1365 running_.size(),
1366 maxRunning_));
1367 r.push_back(StringPrintf("released:%zu releasing:%zu",
1368 counters_.released,
1369 expired_.size()));
1370 r.push_back(StringPrintf("ticker:%zu ticking:%zu maxTicking:%zu",
1371 ticker_->id(),
1372 ticker_->running(),
1373 ticker_->maxRunning()));
1374 return r;
1375 }
1376
1377 /**
1378 * True if the native methods are supported in this process. Native methods are supported only
1379 * if the initialization succeeds.
1380 */
1381 bool nativeSupportEnabled = false;
1382
1383 /**
1384 * Singleton/globals for the anr timer. Among other things, this includes a Ticker* and a use
1385 * count. The JNI layer creates a single Ticker for all operational AnrTimers. The Ticker is
1386 * created when the first AnrTimer is created; this means that the Ticker is only created if
1387 * native anr timers are used.
1388 */
1389 static Mutex gAnrLock;
1390 struct AnrArgs {
1391 jclass clazz = NULL;
1392 jmethodID func = NULL;
1393 JavaVM* vm = NULL;
1394 AnrTimerService::Ticker* ticker = nullptr;
1395 };
1396 static AnrArgs gAnrArgs;
1397
1398 // The cookie is the address of the AnrArgs object to which the notification should be sent.
anrNotify(AnrTimerService::timer_id_t timerId,int pid,int uid,nsecs_t elapsed,void * cookie,jweak jtimer)1399 static bool anrNotify(AnrTimerService::timer_id_t timerId, int pid, int uid, nsecs_t elapsed,
1400 void* cookie, jweak jtimer) {
1401 AutoMutex _l(gAnrLock);
1402 AnrArgs* target = reinterpret_cast<AnrArgs* >(cookie);
1403 JNIEnv *env;
1404 if (target->vm->AttachCurrentThread(&env, 0) != JNI_OK) {
1405 ALOGE("failed to attach thread to JavaVM");
1406 return false;
1407 }
1408 jboolean r = false;
1409 jobject timer = env->NewGlobalRef(jtimer);
1410 if (timer != nullptr) {
1411 // Convert the elsapsed time from ns (native) to ms (Java)
1412 r = env->CallBooleanMethod(timer, target->func, timerId, pid, uid, ns2ms(elapsed));
1413 env->DeleteGlobalRef(timer);
1414 }
1415 target->vm->DetachCurrentThread();
1416 return r;
1417 }
1418
anrTimerSupported(JNIEnv * env,jclass)1419 jboolean anrTimerSupported(JNIEnv* env, jclass) {
1420 return nativeSupportEnabled;
1421 }
1422
anrTimerCreate(JNIEnv * env,jobject jtimer,jstring jname,jboolean extend,jboolean freeze)1423 jlong anrTimerCreate(JNIEnv* env, jobject jtimer, jstring jname,
1424 jboolean extend, jboolean freeze) {
1425 if (!nativeSupportEnabled) return 0;
1426 AutoMutex _l(gAnrLock);
1427 if (gAnrArgs.ticker == nullptr) {
1428 gAnrArgs.ticker = new AnrTimerService::Ticker();
1429 }
1430
1431 ScopedUtfChars name(env, jname);
1432 jobject timer = env->NewWeakGlobalRef(jtimer);
1433 AnrTimerService* service = new AnrTimerService(name.c_str(),
1434 anrNotify, &gAnrArgs, timer, gAnrArgs.ticker, extend, freeze);
1435 return reinterpret_cast<jlong>(service);
1436 }
1437
toService(jlong pointer)1438 AnrTimerService *toService(jlong pointer) {
1439 return reinterpret_cast<AnrTimerService*>(pointer);
1440 }
1441
anrTimerClose(JNIEnv * env,jclass,jlong ptr)1442 jint anrTimerClose(JNIEnv* env, jclass, jlong ptr) {
1443 if (!nativeSupportEnabled) return -1;
1444 if (ptr == 0) return -1;
1445 AutoMutex _l(gAnrLock);
1446 AnrTimerService *s = toService(ptr);
1447 env->DeleteWeakGlobalRef(s->jtimer());
1448 delete s;
1449 return 0;
1450 }
1451
anrTimerStart(JNIEnv * env,jclass,jlong ptr,jint pid,jint uid,jlong timeout)1452 jint anrTimerStart(JNIEnv* env, jclass, jlong ptr, jint pid, jint uid, jlong timeout) {
1453 if (!nativeSupportEnabled) return 0;
1454 // On the Java side, timeouts are expressed in milliseconds and must be converted to
1455 // nanoseconds before being passed to the library code.
1456 return toService(ptr)->start(pid, uid, milliseconds_to_nanoseconds(timeout));
1457 }
1458
anrTimerCancel(JNIEnv * env,jclass,jlong ptr,jint timerId)1459 jboolean anrTimerCancel(JNIEnv* env, jclass, jlong ptr, jint timerId) {
1460 if (!nativeSupportEnabled) return false;
1461 return toService(ptr)->cancel(timerId);
1462 }
1463
anrTimerAccept(JNIEnv * env,jclass,jlong ptr,jint timerId)1464 jboolean anrTimerAccept(JNIEnv* env, jclass, jlong ptr, jint timerId) {
1465 if (!nativeSupportEnabled) return false;
1466 return toService(ptr)->accept(timerId);
1467 }
1468
anrTimerDiscard(JNIEnv * env,jclass,jlong ptr,jint timerId)1469 jboolean anrTimerDiscard(JNIEnv* env, jclass, jlong ptr, jint timerId) {
1470 if (!nativeSupportEnabled) return false;
1471 return toService(ptr)->discard(timerId);
1472 }
1473
anrTimerRelease(JNIEnv * env,jclass,jlong ptr,jint timerId)1474 jboolean anrTimerRelease(JNIEnv* env, jclass, jlong ptr, jint timerId) {
1475 if (!nativeSupportEnabled) return false;
1476 return toService(ptr)->release(timerId);
1477 }
1478
anrTimerTrace(JNIEnv * env,jclass,jobjectArray jconfig)1479 jstring anrTimerTrace(JNIEnv* env, jclass, jobjectArray jconfig) {
1480 if (!nativeSupportEnabled) return nullptr;
1481 std::vector<std::string> config;
1482 const jsize jlen = jconfig == nullptr ? 0 : env->GetArrayLength(jconfig);
1483 for (size_t i = 0; i < jlen; i++) {
1484 jstring je = static_cast<jstring>(env->GetObjectArrayElement(jconfig, i));
1485 ScopedUtfChars e(env, je);
1486 config.push_back(e.c_str());
1487 }
1488 auto r = AnrTimerService::trace(config);
1489 return env->NewStringUTF(r.second.c_str());
1490 }
1491
anrTimerDump(JNIEnv * env,jclass,jlong ptr)1492 jobjectArray anrTimerDump(JNIEnv *env, jclass, jlong ptr) {
1493 if (!nativeSupportEnabled) return nullptr;
1494 std::vector<std::string> stats = toService(ptr)->getDump();
1495 jclass sclass = env->FindClass("java/lang/String");
1496 jobjectArray r = env->NewObjectArray(stats.size(), sclass, nullptr);
1497 for (size_t i = 0; i < stats.size(); i++) {
1498 env->SetObjectArrayElement(r, i, env->NewStringUTF(stats[i].c_str()));
1499 }
1500 return r;
1501 }
1502
1503 static const JNINativeMethod methods[] = {
nativeAnrTimerSupported()1504 {"nativeAnrTimerSupported", "()Z", (void*) anrTimerSupported},
nativeAnrTimerCreate(Ljava/lang/String;ZZ)1505 {"nativeAnrTimerCreate", "(Ljava/lang/String;ZZ)J", (void*) anrTimerCreate},
nativeAnrTimerClose(J)1506 {"nativeAnrTimerClose", "(J)I", (void*) anrTimerClose},
nativeAnrTimerStart(JIIJ)1507 {"nativeAnrTimerStart", "(JIIJ)I", (void*) anrTimerStart},
nativeAnrTimerCancel(JI)1508 {"nativeAnrTimerCancel", "(JI)Z", (void*) anrTimerCancel},
nativeAnrTimerAccept(JI)1509 {"nativeAnrTimerAccept", "(JI)Z", (void*) anrTimerAccept},
nativeAnrTimerDiscard(JI)1510 {"nativeAnrTimerDiscard", "(JI)Z", (void*) anrTimerDiscard},
nativeAnrTimerRelease(JI)1511 {"nativeAnrTimerRelease", "(JI)Z", (void*) anrTimerRelease},
nativeAnrTimerTrace([Ljava/lang/String;)1512 {"nativeAnrTimerTrace", "([Ljava/lang/String;)Ljava/lang/String;", (void*) anrTimerTrace},
nativeAnrTimerDump(J)1513 {"nativeAnrTimerDump", "(J)[Ljava/lang/String;", (void*) anrTimerDump},
1514 };
1515
1516 } // anonymous namespace
1517
register_android_server_utils_AnrTimer(JNIEnv * env)1518 int register_android_server_utils_AnrTimer(JNIEnv* env)
1519 {
1520 static const char* className = "com/android/server/utils/AnrTimer";
1521 jniRegisterNativeMethods(env, className, methods, NELEM(methods));
1522
1523 nativeSupportEnabled = NATIVE_SUPPORT;
1524
1525 // Do not perform any further initialization if native support is not enabled.
1526 if (!nativeSupportEnabled) return 0;
1527
1528 jclass service = FindClassOrDie(env, className);
1529 gAnrArgs.clazz = MakeGlobalRefOrDie(env, service);
1530 gAnrArgs.func = env->GetMethodID(gAnrArgs.clazz, "expire", "(IIIJ)Z");
1531 env->GetJavaVM(&gAnrArgs.vm);
1532
1533 return 0;
1534 }
1535
1536 } // namespace android
1537