Generic Android viewer


In [ ]:
from conf import LisaLogging
LisaLogging.setup()

In [ ]:
%pylab inline

import json
import os

# Support to access the remote target
import devlib
from env import TestEnv

# Import support for Android devices
from android import Screen, Workload, System, ViewerWorkload
from target_script import TargetScript

# Support for trace events analysis
from trace import Trace

# Suport for FTrace events parsing and visualization
import trappy

import pandas as pd
import sqlite3

from IPython.display import display

Test environment setup

For more details on this please check out examples/utils/testenv_example.ipynb.

devlib requires the ANDROID_HOME environment variable configured to point to your local installation of the Android SDK. If you have not this variable configured in the shell used to start the notebook server, you need to run a cell to define where your Android SDK is installed or specify the ANDROID_HOME in your target configuration.

In case more than one Android device are connected to the host, you must specify the ID of the device you want to target in my_target_conf. Run adb devices on your host to get the ID.


In [ ]:
# Setup target configuration
my_conf = {

    # Target platform and board
    "platform"     : 'android',
    "board"        : 'hikey960',
    
    # Device serial ID
    # Not required if there is only one device connected to your computer
    "device"       : "0123456789ABCDEF",
    
    # Android home
    # Not required if already exported in your .bashrc
    #"ANDROID_HOME" : "/home/vagrant/lisa/tools/",

    # Folder where all the results will be collected
    "results_dir" : "Viewer_example",

    # Define devlib modules to load
    "modules"     : [
        'cpufreq'       # enable CPUFreq support
    ],

    # FTrace events to collect for all the tests configuration which have
    # the "ftrace" flag enabled
    "ftrace"  : {
         "events" : [
            "sched_switch",
            "sched_wakeup",
            "sched_wakeup_new",
            "sched_overutilized",
            "sched_load_avg_cpu",
            "sched_load_avg_task",
            "sched_load_waking_task",
            "cpu_capacity",
            "cpu_frequency",
            "cpu_idle",
            "sched_tune_config",
            "sched_tune_tasks_update",
            "sched_tune_boostgroup_update",
            "sched_tune_filter",
            "sched_boost_cpu",
            "sched_boost_task",
            "sched_energy_diff"
         ],
         "buffsize" : 100 * 1024,
    },

    # Tools required by the experiments
    "tools"   : [ 'trace-cmd', 'taskset'],
}

In [ ]:
# Initialize a test environment using:
te = TestEnv(my_conf, wipe=False)
target = te.target

Workload definition

The Viewer workload will simply read an URI and let Android pick the best application to view the item designated by that URI. That item could be a web page, a photo, a pdf, etc. For instance, if given an URL to a Google Maps location, the Google Maps application will be opened at that location. If the device doesn't have Google Play Services (e.g. HiKey960), it will open Google Maps through the default web browser.

The Viewer class is intended to be subclassed to customize your workload. There are pre_interact(), interact() and post_interact() methods that are made to be overridden.

In this case we'll simply execute a script on the target to swipe around a location on Gmaps. This script is generated using the TargetScript class, which is used here on System.{h,v}swipe() calls to accumulate commands instead of executing them directly. Those commands are then outputted to a script on the remote device, and that script is later on executed as the item is being viewed. See ${LISA_HOME}/libs/util/target_script.py


In [ ]:
class GmapsViewer(ViewerWorkload):
    
    def pre_interact(self):
        self.script = TargetScript(te, "gmaps_swiper.sh")

        # Define commands to execute during experiment
        for i in range(2):
            System.hswipe(self.script, 40, 60, 100, False)
            self.script.append('sleep 1')
            System.vswipe(self.script, 40, 60, 100, True)
            self.script.append('sleep 1')
            System.hswipe(self.script, 40, 60, 100, True)
            self.script.append('sleep 1')
            System.vswipe(self.script, 40, 60, 100, False)
            self.script.append('sleep 1')

        # Push script to the target
        self.script.push()
        
    def interact(self):
        self.script.run()

In [ ]:
def experiment():
    # Configure governor
    target.cpufreq.set_all_governors('sched')
    
    # Get workload
    wload = Workload.getInstance(te, 'gmapsviewer')
        
    # Run workload
    wload.run(out_dir=te.res_dir,
        collect="ftrace",
        uri="https://goo.gl/maps/D8Sn3hxsHw62")
    
    # Dump platform descriptor
    te.platform_dump(te.res_dir)

Workload execution


In [ ]:
results = experiment()

In [ ]:
# Load traces in memory (can take several minutes)
platform_file = os.path.join(te.res_dir, 'platform.json')

with open(platform_file, 'r') as fh:
    platform = json.load(fh)

trace_file = os.path.join(te.res_dir, 'trace.dat')
trace = Trace(trace_file, my_conf['ftrace']['events'], platform, normalize_time=False)

Traces visualisation


In [ ]:
!kernelshark {trace_file} 2>/dev/null