Home | History | Annotate | Download | only in event
      1 /*
      2  * Copyright (C) 2009 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 package com.android.ddmuilib.log.event;
     18 
     19 import com.android.ddmlib.log.EventContainer;
     20 import com.android.ddmlib.log.EventLogParser;
     21 import com.android.ddmlib.log.InvalidTypeException;
     22 
     23 import java.awt.Color;
     24 
     25 abstract public class SyncCommon extends EventDisplay {
     26 
     27     // State information while processing the event stream
     28     private int mLastState; // 0 if event started, 1 if event stopped
     29     private long mLastStartTime; // ms
     30     private long mLastStopTime; //ms
     31     private String mLastDetails;
     32     private int mLastSyncSource; // poll, server, user, etc.
     33 
     34     // Some common variables for sync display.  These define the sync backends
     35     //and how they should be displayed.
     36     protected static final int CALENDAR = 0;
     37     protected static final int GMAIL = 1;
     38     protected static final int FEEDS = 2;
     39     protected static final int CONTACTS = 3;
     40     protected static final int ERRORS = 4;
     41     protected static final int NUM_AUTHS = (CONTACTS + 1);
     42     protected static final String AUTH_NAMES[] = {"Calendar", "Gmail", "Feeds", "Contacts",
     43             "Errors"};
     44     protected static final Color AUTH_COLORS[] = {Color.MAGENTA, Color.GREEN, Color.BLUE,
     45             Color.ORANGE, Color.RED};
     46 
     47     // Values from data/etc/event-log-tags
     48     final int EVENT_SYNC = 2720;
     49     final int EVENT_TICKLE = 2742;
     50     final int EVENT_SYNC_DETAILS = 2743;
     51     final int EVENT_CONTACTS_AGGREGATION = 2747;
     52 
     53     protected SyncCommon(String name) {
     54         super(name);
     55     }
     56 
     57     /**
     58      * Resets the display.
     59      */
     60     @Override
     61     void resetUI() {
     62         mLastStartTime = 0;
     63         mLastStopTime = 0;
     64         mLastState = -1;
     65         mLastSyncSource = -1;
     66         mLastDetails = "";
     67     }
     68 
     69     /**
     70      * Updates the display with a new event.  This is the main entry point for
     71      * each event.  This method has the logic to tie together the start event,
     72      * stop event, and details event into one graph item.  The combined sync event
     73      * is handed to the subclass via processSycnEvent.  Note that the details
     74      * can happen before or after the stop event.
     75      *
     76      * @param event     The event
     77      * @param logParser The parser providing the event.
     78      */
     79     @Override
     80     void newEvent(EventContainer event, EventLogParser logParser) {
     81         try {
     82             if (event.mTag == EVENT_SYNC) {
     83                 int state = Integer.parseInt(event.getValueAsString(1));
     84                 if (state == 0) { // start
     85                     mLastStartTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
     86                     mLastState = 0;
     87                     mLastSyncSource = Integer.parseInt(event.getValueAsString(2));
     88                     mLastDetails = "";
     89                 } else if (state == 1) { // stop
     90                     if (mLastState == 0) {
     91                         mLastStopTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
     92                         if (mLastStartTime == 0) {
     93                             // Log starts with a stop event
     94                             mLastStartTime = mLastStopTime;
     95                         }
     96                         int auth = getAuth(event.getValueAsString(0));
     97                         processSyncEvent(event, auth, mLastStartTime, mLastStopTime, mLastDetails,
     98                                 true, mLastSyncSource);
     99                         mLastState = 1;
    100                     }
    101                 }
    102             } else if (event.mTag == EVENT_SYNC_DETAILS) {
    103                 mLastDetails = event.getValueAsString(3);
    104                 if (mLastState != 0) { // Not inside event
    105                     long updateTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
    106                     if (updateTime - mLastStopTime <= 250) {
    107                         // Got details within 250ms after event, so delete and re-insert
    108                         // Details later than 250ms (arbitrary) are discarded as probably
    109                         // unrelated.
    110                         int auth = getAuth(event.getValueAsString(0));
    111                         processSyncEvent(event, auth, mLastStartTime, mLastStopTime, mLastDetails,
    112                                 false, mLastSyncSource);
    113                     }
    114                 }
    115             } else if (event.mTag == EVENT_CONTACTS_AGGREGATION) {
    116                 long stopTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
    117                 long startTime = stopTime - Long.parseLong(event.getValueAsString(0));
    118                 String details;
    119                 int count = Integer.parseInt(event.getValueAsString(1));
    120                 if (count < 0) {
    121                     details = "g" + (-count);
    122                 } else {
    123                     details = "G" + count;
    124                 }
    125                 processSyncEvent(event, CONTACTS, startTime, stopTime, details,
    126                         true /* newEvent */, mLastSyncSource);
    127             }
    128         } catch (InvalidTypeException e) {
    129         }
    130     }
    131 
    132     /**
    133      * Callback hook for subclass to process a sync event.  newEvent has the logic
    134      * to combine start and stop events and passes a processed event to the
    135      * subclass.
    136      *
    137      * @param event     The sync event
    138      * @param auth      The sync authority
    139      * @param startTime Start time (ms) of events
    140      * @param stopTime  Stop time (ms) of events
    141      * @param details   Details associated with the event.
    142      * @param newEvent  True if this event is a new sync event.  False if this event
    143      * @param syncSource Poll, user, server, etc.
    144      */
    145     abstract void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
    146             String details, boolean newEvent, int syncSource);
    147 
    148     /**
    149      * Converts authority name to auth number.
    150      *
    151      * @param authname "calendar", etc.
    152      * @return number series number associated with the authority
    153      */
    154     protected int getAuth(String authname) throws InvalidTypeException {
    155         if ("calendar".equals(authname) || "cl".equals(authname) ||
    156                 "com.android.calendar".equals(authname)) {
    157             return CALENDAR;
    158         } else if ("contacts".equals(authname) || "cp".equals(authname) ||
    159                 "com.android.contacts".equals(authname)) {
    160             return CONTACTS;
    161         } else if ("subscribedfeeds".equals(authname)) {
    162             return FEEDS;
    163         } else if ("gmail-ls".equals(authname) || "mail".equals(authname)) {
    164             return GMAIL;
    165         } else if ("gmail-live".equals(authname)) {
    166             return GMAIL;
    167         } else if ("unknown".equals(authname)) {
    168             return -1; // Unknown tickles; discard
    169         } else {
    170             throw new InvalidTypeException("Unknown authname " + authname);
    171         }
    172     }
    173 }
    174