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 Event(int type, int userId, ComponentName agent, String message, long duration, boolean userInitiated, boolean managingTrust)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 logGrantTrust(int userId, ComponentName agent, String message, long duration, boolean userInitiated)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 logRevokeTrust(int userId, ComponentName agent)77 public void logRevokeTrust(int userId, ComponentName agent) { 78 addEvent(new Event(TYPE_REVOKE_TRUST, userId, agent, null, 0, false, false)); 79 } 80 logTrustTimeout(int userId, ComponentName agent)81 public void logTrustTimeout(int userId, ComponentName agent) { 82 addEvent(new Event(TYPE_TRUST_TIMEOUT, userId, agent, null, 0, false, false)); 83 } 84 logAgentDied(int userId, ComponentName agent)85 public void logAgentDied(int userId, ComponentName agent) { 86 addEvent(new Event(TYPE_AGENT_DIED, userId, agent, null, 0, false, false)); 87 } 88 logAgentConnected(int userId, ComponentName agent)89 public void logAgentConnected(int userId, ComponentName agent) { 90 addEvent(new Event(TYPE_AGENT_CONNECTED, userId, agent, null, 0, false, false)); 91 } 92 logAgentStopped(int userId, ComponentName agent)93 public void logAgentStopped(int userId, ComponentName agent) { 94 addEvent(new Event(TYPE_AGENT_STOPPED, userId, agent, null, 0, false, false)); 95 } 96 logManagingTrust(int userId, ComponentName agent, boolean managing)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 addEvent(Event e)101 private void addEvent(Event e) { 102 if (mEvents.size() >= HISTORY_LIMIT) { 103 mEvents.removeFirst(); 104 } 105 mEvents.addLast(e); 106 } 107 dump(PrintWriter writer, int limit, int userId, String linePrefix, boolean duplicateSimpleNames)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 formatDuration(long duration)145 public static String formatDuration(long duration) { 146 StringBuilder sb = new StringBuilder(); 147 TimeUtils.formatDuration(duration, sb); 148 return sb.toString(); 149 } 150 formatElapsed(long elapsed)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 getSimpleName(ComponentName cn)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 dumpType(int type)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