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