• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&regex_, 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(&regex_);
283                 matchNames_ = false;
284             }
285             if (regcomp(&regex_, 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(&regex_);
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