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