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