Home | History | Annotate | Download | only in trust
      1 /*
      2  * Copyright (C) 2014 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.server.trust;
     18 
     19 import android.content.ComponentName;
     20 import android.os.SystemClock;
     21 import android.os.UserHandle;
     22 import android.util.TimeUtils;
     23 
     24 import java.io.PrintWriter;
     25 import java.util.ArrayDeque;
     26 import java.util.Iterator;
     27 
     28 /**
     29  * An archive of trust events.
     30  */
     31 public class TrustArchive {
     32     private static final int TYPE_GRANT_TRUST = 0;
     33     private static final int TYPE_REVOKE_TRUST = 1;
     34     private static final int TYPE_TRUST_TIMEOUT = 2;
     35     private static final int TYPE_AGENT_DIED = 3;
     36     private static final int TYPE_AGENT_CONNECTED = 4;
     37     private static final int TYPE_AGENT_STOPPED = 5;
     38     private static final int TYPE_MANAGING_TRUST = 6;
     39 
     40     private static final int HISTORY_LIMIT = 200;
     41 
     42     private static class Event {
     43         final int type;
     44         final int userId;
     45         final ComponentName agent;
     46         final long elapsedTimestamp;
     47 
     48         // grantTrust
     49         final String message;
     50         final long duration;
     51         final boolean userInitiated;
     52 
     53         // managingTrust
     54         final boolean managingTrust;
     55 
     56         private Event(int type, int userId, ComponentName agent, String message,
     57                 long duration, boolean userInitiated, boolean managingTrust) {
     58             this.type = type;
     59             this.userId = userId;
     60             this.agent = agent;
     61             this.elapsedTimestamp = SystemClock.elapsedRealtime();
     62             this.message = message;
     63             this.duration = duration;
     64             this.userInitiated = userInitiated;
     65             this.managingTrust = managingTrust;
     66         }
     67     }
     68 
     69     ArrayDeque<Event> mEvents = new ArrayDeque<Event>();
     70 
     71     public void logGrantTrust(int userId, ComponentName agent, String message,
     72             long duration, boolean userInitiated) {
     73         addEvent(new Event(TYPE_GRANT_TRUST, userId, agent, message, duration,
     74                 userInitiated, false));
     75     }
     76 
     77     public void logRevokeTrust(int userId, ComponentName agent) {
     78         addEvent(new Event(TYPE_REVOKE_TRUST, userId, agent, null, 0, false, false));
     79     }
     80 
     81     public void logTrustTimeout(int userId, ComponentName agent) {
     82         addEvent(new Event(TYPE_TRUST_TIMEOUT, userId, agent, null, 0, false, false));
     83     }
     84 
     85     public void logAgentDied(int userId, ComponentName agent) {
     86         addEvent(new Event(TYPE_AGENT_DIED, userId, agent, null, 0, false, false));
     87     }
     88 
     89     public void logAgentConnected(int userId, ComponentName agent) {
     90         addEvent(new Event(TYPE_AGENT_CONNECTED, userId, agent, null, 0, false, false));
     91     }
     92 
     93     public void logAgentStopped(int userId, ComponentName agent) {
     94         addEvent(new Event(TYPE_AGENT_STOPPED, userId, agent, null, 0, false, false));
     95     }
     96 
     97     public void logManagingTrust(int userId, ComponentName agent, boolean managing) {
     98         addEvent(new Event(TYPE_MANAGING_TRUST, userId, agent, null, 0, false, managing));
     99     }
    100 
    101     private void addEvent(Event e) {
    102         if (mEvents.size() >= HISTORY_LIMIT) {
    103             mEvents.removeFirst();
    104         }
    105         mEvents.addLast(e);
    106     }
    107 
    108     public void dump(PrintWriter writer, int limit, int userId, String linePrefix,
    109             boolean duplicateSimpleNames) {
    110         int count = 0;
    111         Iterator<Event> iter = mEvents.descendingIterator();
    112         while (iter.hasNext() && count < limit) {
    113             Event ev = iter.next();
    114             if (userId != UserHandle.USER_ALL && userId != ev.userId) {
    115                 continue;
    116             }
    117 
    118             writer.print(linePrefix);
    119             writer.printf("#%-2d %s %s: ", count, formatElapsed(ev.elapsedTimestamp),
    120                     dumpType(ev.type));
    121             if (userId == UserHandle.USER_ALL) {
    122                 writer.print("user="); writer.print(ev.userId); writer.print(", ");
    123             }
    124             writer.print("agent=");
    125             if (duplicateSimpleNames) {
    126                 writer.print(ev.agent.flattenToShortString());
    127             } else {
    128                 writer.print(getSimpleName(ev.agent));
    129             }
    130             switch (ev.type) {
    131                 case TYPE_GRANT_TRUST:
    132                     writer.printf(", message=\"%s\", duration=%s, initiatedByUser=%d",
    133                             ev.message, formatDuration(ev.duration), ev.userInitiated ? 1 : 0);
    134                     break;
    135                 case TYPE_MANAGING_TRUST:
    136                     writer.printf(", managingTrust=" + ev.managingTrust);
    137                     break;
    138                 default:
    139             }
    140             writer.println();
    141             count++;
    142         }
    143     }
    144 
    145     public static String formatDuration(long duration) {
    146         StringBuilder sb = new StringBuilder();
    147         TimeUtils.formatDuration(duration, sb);
    148         return sb.toString();
    149     }
    150 
    151     private static String formatElapsed(long elapsed) {
    152         long delta = elapsed - SystemClock.elapsedRealtime();
    153         long wallTime = delta + System.currentTimeMillis();
    154         return TimeUtils.logTimeOfDay(wallTime);
    155     }
    156 
    157     /* package */ static String getSimpleName(ComponentName cn) {
    158         String name = cn.getClassName();
    159         int idx = name.lastIndexOf('.');
    160         if (idx < name.length() && idx >= 0) {
    161             return name.substring(idx + 1);
    162         } else {
    163             return name;
    164         }
    165     }
    166 
    167     private String dumpType(int type) {
    168         switch (type) {
    169             case TYPE_GRANT_TRUST:
    170                 return "GrantTrust";
    171             case TYPE_REVOKE_TRUST:
    172                 return "RevokeTrust";
    173             case TYPE_TRUST_TIMEOUT:
    174                 return "TrustTimeout";
    175             case TYPE_AGENT_DIED:
    176                 return "AgentDied";
    177             case TYPE_AGENT_CONNECTED:
    178                 return "AgentConnected";
    179             case TYPE_AGENT_STOPPED:
    180                 return "AgentStopped";
    181             case TYPE_MANAGING_TRUST:
    182                 return "ManagingTrust";
    183             default:
    184                 return "Unknown(" + type + ")";
    185         }
    186     }
    187 }
    188