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 Event(int type, int userId, ComponentName agent, String message, long duration, int flags, boolean managingTrust)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 logGrantTrust(int userId, ComponentName agent, String message, long duration, int flags)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 logRevokeTrust(int userId, ComponentName agent)79 public void logRevokeTrust(int userId, ComponentName agent) { 80 addEvent(new Event(TYPE_REVOKE_TRUST, userId, agent, null, 0, 0, false)); 81 } 82 logTrustTimeout(int userId, ComponentName agent)83 public void logTrustTimeout(int userId, ComponentName agent) { 84 addEvent(new Event(TYPE_TRUST_TIMEOUT, userId, agent, null, 0, 0, false)); 85 } 86 logAgentDied(int userId, ComponentName agent)87 public void logAgentDied(int userId, ComponentName agent) { 88 addEvent(new Event(TYPE_AGENT_DIED, userId, agent, null, 0, 0, false)); 89 } 90 logAgentConnected(int userId, ComponentName agent)91 public void logAgentConnected(int userId, ComponentName agent) { 92 addEvent(new Event(TYPE_AGENT_CONNECTED, userId, agent, null, 0, 0, false)); 93 } 94 logAgentStopped(int userId, ComponentName agent)95 public void logAgentStopped(int userId, ComponentName agent) { 96 addEvent(new Event(TYPE_AGENT_STOPPED, userId, agent, null, 0, 0, false)); 97 } 98 logManagingTrust(int userId, ComponentName agent, boolean managing)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 logDevicePolicyChanged()103 public void logDevicePolicyChanged() { 104 addEvent(new Event(TYPE_POLICY_CHANGED, UserHandle.USER_ALL, null, null, 0, 0, false)); 105 } 106 addEvent(Event e)107 private void addEvent(Event e) { 108 if (mEvents.size() >= HISTORY_LIMIT) { 109 mEvents.removeFirst(); 110 } 111 mEvents.addLast(e); 112 } 113 dump(PrintWriter writer, int limit, int userId, String linePrefix, boolean duplicateSimpleNames)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 formatDuration(long duration)154 public static String formatDuration(long duration) { 155 StringBuilder sb = new StringBuilder(); 156 TimeUtils.formatDuration(duration, sb); 157 return sb.toString(); 158 } 159 formatElapsed(long elapsed)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 getSimpleName(ComponentName cn)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 dumpType(int type)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 dumpGrantFlags(int flags)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