示例#1
0
    def event_intervals(self,
                        name=None,
                        task=None,
                        interval=None,
                        match_exact=True):
        """Returns event intervals for specified `name` and `task`
        Name here implies `section` or `counter` name.
        """
        if name is None:
            intervals = \
                IntervalList(sorted_items(self._tmw_intervals_by_name.values()))
        elif isinstance(name, string_types):
            if match_exact:
                intervals = self._tmw_intervals_by_name[name]
            else:
                intervals = IntervalList(
                    sorted_items(value for key, value in
                                 self._tmw_intervals_by_name.iteritems()
                                 if name in key))
        else:  # assume iterable (must match exact)
            intervals = IntervalList(
                sorted_items(
                    value
                    for key, value in self._tmw_intervals_by_name.iteritems()
                    if key in name))
        intervals = intervals.slice(interval=interval)
        if task:
            intervals = IntervalList(
                filter(lambda it: it.event.task == task, intervals))

        return intervals
示例#2
0
    def pwrstate_intervals(self, device=None, state=None, interval=None):
        """
        Returns pwr state intervals for specified state (if any)
        on device (if any) over the specified interval (if any).
        """
        try:
            self._pwrstate_intervals_by_device.keys()
        except AttributeError:
            self._pwrstate_events_handler()

        try:
            if device is not None:
                intervals = self._pwrstate_intervals_by_device[device]
            else:
                intervals = IntervalList(
                                sorted_items(
                                    self._pwrstate_intervals_by_device.values()))
            if is_list_like(state):
                filter_func = (lambda ti: ti.state in state) if state else None
            else:
                filter_func = (lambda ti: ti.state == state) if state else None
            return IntervalList(filter(filter_func,
                                       intervals.slice(interval=interval)))
        except:
            return IntervalList()
示例#3
0
 def lpm_intervals(self, cluster=None, interval=None):
     """Return Idle interval for specified cpu & interval
     when cluster is IDLE (in LPM) state
     """
     try:
         return IntervalList(
             filter(
                 lambda cii: cii.state == BusyState.IDLE,
                 self.cluster_intervals(cluster=cluster,
                                        interval=interval)))
     except:
         return IntervalList()
示例#4
0
 def busy_intervals(self, cluster=None, interval=None):
     """Return Busy interval for specified cluster & interval
     when cluster is not IDLE (in LPM) state
     """
     try:
         return IntervalList(
             filter(
                 lambda cii: cii.state != BusyState.IDLE,
                 self.cluster_intervals(cluster=cluster,
                                        interval=interval)))
     except:
         return IntervalList()
示例#5
0
    def bimc_aggregate_requests(self, interval=None):
        """
        Returns alll votes between BIMC clock changes.
        """
        rv = IntervalList()
        votes = {}
        max_voter, max_vote = '', 0
        for bimc_interval in \
            self._trace.clock.frequency_intervals(clock='bimc_clk',
                                                  interval=interval):
            for bus_requests in self.bus_request_intervals(
                    interval=bimc_interval.interval):
                ib_vote = bus_requests.instantaneous_bw_GBps
                device = bus_requests.device + ' ' + repr(
                    bus_requests.master_slave)
                votes[device] = ib_vote
                if ib_vote > max_vote:
                    max_voter = device
                    max_vote = ib_vote
            rv.append(
                AggBusRequestInterval(votes=votes,
                                      max_voter=max_voter,
                                      interval=bimc_interval.interval))

        return rv
示例#6
0
    def io_request_intervals(self, op=None, interval=None, by='issue'):
        """Returns event intervals for specified `op`

        If by ='issue' (default):
            returns intervals from block issue ==> complete
        Elif by = 'insert':
            returns intervals from insert to queue ==> complete

        For list of io_types (aka ops) see `trace.disk.ops`
        # TODO: Filter by # of sectors & devices.

        See `DiskIOType` in `ftrace.io` for op.
        """
        if by == 'insert':
            interval_dict = self._io_insert_intervals_by_op
        else:
            interval_dict = self._io_issue_intervals_by_op
        if op is None:
            intervals = \
                IntervalList(sorted_items(interval_dict.values()))
        else:
            intervals = interval_dict[op]

        intervals = intervals.slice(interval=interval)
        return intervals
示例#7
0
    def open_camera_intervals(self, interval=None):
        """
        Returns list of intervals to open camera device.
        Camera open should return in 200ms, and must return in 500ms.

        References:
        [1] http://source.android.com/devices/camera/camera3_requests_hal.html
        [2] https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/camera3.h
        """
        rv = IntervalList()
        # Several device vendors have different names

        cam_open_events = self._trace.android.event_intervals(
            name='openCameraDevice', interval=interval)  # Typical of SS
        if not cam_open_events:
            cam_open_events = self._trace.android.event_intervals(
                name='AndroidCamera.open', interval=interval)  # Huawei
        for cam_open_event in cam_open_events:
            interval = cam_open_event.interval
            if interval.duration > 0.5:
                log.warn("Camera open exceeded 500ms recommended time")
            rv.append(
                CameraLatency(op="Open Camera Device",
                              interval=interval,
                              latency=interval.duration))
        return rv
示例#8
0
    def input_events(self, task=None, interval=None):
        all_inputs = self.event_intervals(name='aq:pending:',
                                          task=task,
                                          interval=interval,
                                          match_exact=False)

        return IntervalList(
            filter(lambda input_event: input_event.value == 1, all_inputs))
示例#9
0
    def frequency_intervals(self, device=None, interval=None):
        """Returns freq intervals for specified interval on device"""
        try:
            self._pwrlevel_intervals_by_device.keys()
        except AttributeError:
            self._pwrlevel_events_handler()

        try:
            if device is not None:
                intervals = self._pwrlevel_intervals_by_device[device]
            else:
                intervals = IntervalList(
                                sorted_items(
                                    self._pwrlevel_intervals_by_device.values()))

            return intervals.slice(interval=interval)
        except:
            return IntervalList()
示例#10
0
    def buslevel_intervals(self, device=None, interval=None):
        """
        """
        try:
            self._buslevel_intervals_by_device.keys()
        except AttributeError:
            self._buslevel_events_handler()

        try:
            if device is not None:
                intervals = self._buslevel_intervals_by_device[device]
            else:
                intervals = IntervalList(
                                sorted_items(
                                    self._buslevel_intervals_by_device.values()))

            return intervals.slice(interval=interval)
        except:
            return IntervalList()
示例#11
0
 def clock_intervals(self, clock, state=None, interval=None):
     """Returns clock (enabled/disabled) intervals for specified `clock`.
     For list of clocks, dump `names`
     """
     try:
         clk_intervals = \
             self._clk_intervals_by_clock[clock].slice(interval=interval)
     except AttributeError:
         clk_intervals = \
             self._clk_events_handler()[clock].slice(interval=interval)
     except KeyError:
         log.warn('No such clock: {clock} in {clocks}'.format(
                 clock=clock, clocks=self.names))
         return IntervalList()
         
     # Hack in case clock was always ON:
     if not clk_intervals and self.frequency_intervals(clock=clock, interval=interval):
         clk_intervals = IntervalList([ClkInterval(clock, ClockState.ENABLED, self._trace.interval)])
             
     filter_func = lambda ci: ci.state is state if state else None
     return IntervalList(filter(filter_func, clk_intervals)).slice(interval=interval)
示例#12
0
 def rendering_intervals(self, interval=None):
     """
     """
     frames = self.frame_intervals(interval=interval)
     rendering_intervals = IntervalList()
     slice_start = frames[0].interval.start
     for i, j in zip(frames[:-1], frames[1:]):
         if j.interval.start - i.interval.end > 2 * VSYNC:
             # new group of frames.
             ri = Rendering(interval=Interval(slice_start, i.interval.end))
             rendering_intervals.append(ri)
             slice_start = j.interval.start
     return rendering_intervals
示例#13
0
    def _switch_device_latency_handler(self):
        """
        Returns list of all input events
        """
        self._switch_latencies = IntervalList()
        deliver_inputs = self._trace.android.event_intervals(
            "deliverInputEvent")

        def _preview_intervals():
            """
            Generator that yields intervals when still images are captured
            """
            last_timestamp = self._trace.interval.start
            sp_events = self._trace.android.event_intervals(
                'doStopPreviewSync')
            if not sp_events:
                preview_events = self._trace.android.event_intervals(
                    'AndroidCamera.startPreview')
                if preview_events:
                    camera_task = preview_events[0].event.task
                    sp_events = (context for context in \
                        self._trace.android.event_intervals('disconnect') \
                        if context.event.task.pid == camera_task.pid)

            for sp_event in sp_events:
                yield Interval(last_timestamp, sp_event.interval.start)
                last_timestamp = sp_event.interval.start

        for interval in _preview_intervals():
            touch_events = deliver_inputs.slice(interval=interval,
                                                trimmed=False)
            if touch_events:
                start_ts = touch_events[-1].interval.start
                end_ts = start_ts
                post_touch_interval = Interval(start_ts, self._trace.duration)
                si_events = self._trace.android.event_intervals(
                    name='StartPreviewThread', interval=post_touch_interval)
                if not si_events:
                    si_events = self._trace.android.event_intervals(
                        name='AndroidCamera.startPreview',
                        interval=post_touch_interval)
                if si_events:
                    end_ts = si_events[0].interval.end
                shutter_lag_interval = Interval(start=start_ts, end=end_ts)
                self._switch_latencies.append(
                    CameraLatency("Camera Switch",
                                  interval=shutter_lag_interval,
                                  latency=shutter_lag_interval.duration))

        return self._switch_latencies
示例#14
0
    def bus_request_intervals(self, device=None, state=None, interval=None):
        """Return device interval for specified cpu & interval
        """
        try:
            self._bur_intervals_by_dev
        except AttributeError:
            _ = self._bur_events_handler()

        if device is not None:
            try:
                intervals = self._bur_intervals_by_dev[device].slice(
                    interval=interval)
            except KeyError:
                log.warn('No such device: {device} in {devices}'.format(
                    device=device, devices=self.names))
                interval = IntervalList()
        else:
            intervals = IntervalList(
                sorted_items(self._bur_intervals_by_dev.values())).slice(
                    interval=interval)

        filter_func = (lambda bi: bi.state is state) if state else None
        return IntervalList(filter(filter_func, intervals))
示例#15
0
    def cluster_intervals(self, cluster, interval=None):
        """Return interval for specified cluster & interval
        """
        try:
            self._cluster_idle_intervals_by_cluster
        except AttributeError:
            _ = self._cluster_idle_events_handler()

        if cluster is not None:
            intervals = self._cluster_idle_intervals_by_cluster[cluster]
        else:
            intervals = IntervalList(
                sorted_items(self._cluster_idle_intervals_by_cluster.values()))

        return intervals.slice(interval=interval)
示例#16
0
 def store_image_intervals(self, interval=None):
     """
     Returns list of intervals to store image intervals.
     
     # IMPORTANT: Not supported on Huawei devices yet. Missing markers.
     """
     rv = IntervalList()
     for store_image_event in self._trace.android.event_intervals(
             name='storeImage', interval=interval):
         interval = store_image_event.interval
         rv.append(
             CameraLatency(op="Store Image/ Add To Media Store",
                           interval=interval,
                           latency=interval.duration))
     return rv
示例#17
0
    def _shutter_lag_latency_handler(self):
        """
        Returns list of all input events
        """
        self._shutter_lag_latencies = IntervalList()
        deliver_inputs = self._trace.android.event_intervals(
            "deliverInputEvent")

        def _still_capture_intervals():
            """
            Generator that yields intervals when still images are captured
            """
            last_timestamp = self._trace.interval.start
            for tp_event in self._trace.android.event_intervals(
                    'doTakePictureAsync'):
                yield Interval(last_timestamp, tp_event.interval.start)
                last_timestamp = tp_event.interval.start

        for interval in _still_capture_intervals():
            touch_events = deliver_inputs.slice(interval=interval,
                                                trimmed=False)
            # Necessary as we may be interested in different IRQ name
            if touch_events:
                # Use last input event within this interval
                start_ts = touch_events[-1].interval.start
                end_ts = start_ts
                post_touch_interval = Interval(interval.end,
                                               self._trace.duration)
                si_events = self._trace.android.event_intervals(
                    name='storeImage', interval=post_touch_interval)
                if si_events:
                    end_ts = si_events[0].interval.end
                shutter_lag_interval = Interval(start=start_ts, end=end_ts)
                self._shutter_lag_latencies.append(
                    CameraLatency("Shutter Lag",
                                  interval=shutter_lag_interval,
                                  latency=shutter_lag_interval.duration))

            return self._shutter_lag_latencies
示例#18
0
    def _input_latency_handler(self, irq_name):
        """
        Returns list of all input events
        """
        self._input_latencies = IntervalList()
        all_tasks = self._trace.cpu.task_intervals()
        all_aq_events = self.input_events()
        touch_irqs = IntervalList(
            filter_by_task(all_tasks, 'name', irq_name, 'any'))

        def _input_intervals():
            """
            Generator that yields intervals when discrete input event(s)
            are read & decoded by Android `Input Reader`.

            x__x__x____IR___ID_ID_ID___DI_SU__DI_SU__DI_SU______

            x = multiple input IRQs (multi-touch translated by Android Input Framework)
            IR = Input Reader [read/decodes multiple events @ once]
            ID = Input Dispatch [dispatches each input event]
            DI = Deliver Input [ appropriate window consumes input event ]
            SU = SurfaceFlinger Screen Update due to window handling input event

            Please note InputReader 'iq' will be set to 1 whenever InputReader
            had event to process. This could be disabled in some systems.
            """
            last_timestamp = self._trace.interval.start
            for ir_event in filter_by_task(all_tasks, 'name', 'InputReader',
                                           'any'):
                yield Interval(last_timestamp, ir_event.interval.end)
                last_timestamp = ir_event.interval.end

        for interval in _input_intervals():
            irqs = touch_irqs.slice(interval=interval, trimmed=False)
            # Necessary as we may be interested in different IRQ name
            if irqs:
                # Use longest IRQ
                start_ts = max(
                    irqs, key=lambda x: x.interval.duration).interval.start

                end_ts = start_ts
                post_ir_interval = Interval(start_ts, self._trace.duration)
                di_events = self.event_intervals(
                    name=['deliverInputEvent', 'input'],
                    interval=post_ir_interval)

                if di_events:
                    # IMPORTANT: If InputDispatcher sythesizes multiple
                    # events to same application, we ignore consequent event
                    # and only parse 1st event. This is because we heuristically
                    # can't determine start of next input event to differentiate.
                    di_event = di_events[0]
                    # necessary in case a synthetic events is cancelled
                    # canceled appropriately when the events are no longer
                    # being resynthesized (because the application or IME is
                    # already handling them or dropping them entirely)
                    # This is done by checking for dumping input latencies when
                    # active input event queue length (aq) is > 1 for same task.

                    # For more details, see
                    # https://android.googlesource.com/platform/frameworks/base.git/+
                    # /f9e989d5f09e72f5c9a59d713521f37d3fdd93dd%5E!/

                    # This returns first interval when aq has pending event(s)
                    di_event_name = getattr(di_event, 'name', None)
                    if di_event_name and di_event_name == 'input':
                        pfb_events = self.event_intervals(
                            name='doComposition', interval=post_ir_interval)
                    else:
                        aq_event = filter_by_task(
                            all_aq_events.slice(interval=post_ir_interval),
                            'pid', di_event.event.task.pid)

                        if aq_event and aq_event.value > 0:
                            post_di_start = aq_event.interval.start
                        else:
                            if aq_event:
                                continue  # if AQ event exists.
                            post_di_start = di_events[0].interval.start

                        post_di_interval = Interval(post_di_start,
                                                    self._trace.duration)

                        pfb_events = self.event_intervals(
                            name='doComposition', interval=post_di_interval)

                    if pfb_events:
                        end_ts = pfb_events[0].interval.end
                if start_ts != end_ts and end_ts > start_ts and start_ts not in self._input_latencies._start_timestamps:
                    input_interval = Interval(start=start_ts, end=end_ts)
                    self._input_latencies.append(
                        InputLatency(interval=input_interval,
                                     latency=input_interval.duration))

        return self._input_latencies
示例#19
0
 def jank_intervals(self, interval=None):
     """
     Returns list of intervals when a jank (missed frame) occurred.
     """
     missedFrames = self.event_intervals('FrameMissed', interval=interval)
     return IntervalList(filter(lambda x: x.value == 1, missedFrames))