LogViewer Overview

This article reviews LogViewer, the in-app browser for MobileInsight logs.

What is LogViewer?

LogViewer (in mobileInsight-mobile/demo_app/log_viewer_app.py) implements the in-device *.mi2log log viewer. When user clicks the “In-App Logviewer” button, a log_viewer_app.LogViewerScreen will be launched as the main UI, and the following tasks will be done:

  1. Browse all files in /sdcard/mobile_insight/log/, filters out all *.mi2log files under this directories, show them on screen and ask user to select one;
  2. Once user selects one *.mi2log, it will use OfflineReplayer to load the log, and use LogAnalyzer to parse the logs. Once it is done, per-message view will be generated on screen. Note that in the current implementation, the message will be shown on screen until all logs are parsed. This causes long waiting time for user, and should be avoided in future version.
  3. When user selects one message, a popup is created to show the decoded message contents (in xml format);
  4. When filter button is pressed, a popup will be generated to show all the type ids MobileInsight currently offers and user can select type ids they would like to view;
  5. When search button is pressed, a popup with a textbox will be generated. Once user writes in the message and clicks “Ok”, log viewer will only show the packets that contain that message.

Code Review

To use log_viewer_app.py, you need to add the following statement in the code

#Requires Kivy
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.checkbox import CheckBox
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.uix.screenmanager import Screen
from kivy.uix.scrollview import ScrollView
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.effects.scroll import ScrollEffect
from kivy.factory import Factory
from kivy.graphics import *
from kivy.properties import ObjectProperty, StringProperty

#Requires MobileInsight plug-in
from mobile_insight.analyzer import LogAnalyzer
from mobile_insight.monitor.dm_collector.dm_endec.dm_log_packet import DMLogPacket

from datetime import datetime, timedelta
from threading import Thread
import time
import os
import sys
import xml.dom.minidom

The following figure shows the dependency graph of the classes and methods in log_viewer_app.py. Overall, it has three main classes: Open_Popup, LogViewerApp and LogViewerScreen. We next elaborate each.

logviewer

Open_Popup

Class Open_Popup is used for a popup that is used for loading a log.

class Open_Popup(FloatLayout):
    “””
    Declares object property to “load” and “cancel” used when creating a popup for loading a log
    “””

LogViewerScreen

Class LogViewerScreen is used for all the utilities that log viewer has.

class LogViewerScreen(Screen):
    def __init__(self):
        """
        Initialization
        """

    def onOpen(self, *args):
        """
        Generates a popup used for loading a log
        """

    def load(self, path, filename, *args):
        """
        Runs the thread when user selects a log
        """

    def openFile(self, Paths,selectedTypes):
        """
        Runs log analyzer on a selected log
        """

    def OnReadComplete(self):
        """
        Is ran after log is loaded
        """

    def check_scroll_limit(self, *args):
        """
        Used for switching the grid when it is scrolled to the end
        """

    def SetUpGrid(self, data, rows, Move):
        """
        Used for switching the grid when it is scrolled to the end
        """

    def grid_popup(self, data):
        """
        Used for switching the grid when it is scrolled to the end
        """

    def loading(self, *args):
        """
        Popup that is created while loading a log
        """

    def onFilter(self):
        """
        Generates a pop up used for filtering
        """

    def filter_ok(self, *args):
        """
        Sets up the grid when Ok button is pressed
        """

    def filter_select_all(self, *args):
        """
        Selects all the type ids
        """

    def onSearch(self):
        """
        Generates a popup used for searching
        """

    def search_ok(self, *args):
        """
        Sets up the grid when Ok button is pressed
        """

    def onReset(self):
        """
        Resets the filter and search when pressed
        """

    def onGoTo(self): ):
        """
        Generates a popup used for goto
        """

    def goto_ok(self, *args): ):
        """
        Sets up the grid when Ok button is pressed
        """