blob: aaac2979049b4bd0ee79edc5dfb36a59f30298df [file] [log] [blame]
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001/*
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;
Adrian Roos94e15a52015-04-16 12:23:18 -070022import android.service.trust.TrustAgentService;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020023import android.util.TimeUtils;
24
25import java.io.PrintWriter;
26import java.util.ArrayDeque;
27import java.util.Iterator;
28
29/**
30 * An archive of trust events.
31 */
32public 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;
Adrian Roos7d59b4f2014-05-27 20:01:31 +020037 private static final int TYPE_AGENT_CONNECTED = 4;
38 private static final int TYPE_AGENT_STOPPED = 5;
Adrian Roos7861c662014-07-25 15:37:28 +020039 private static final int TYPE_MANAGING_TRUST = 6;
Adrian Roos9d6fc922016-08-10 17:09:55 -070040 private static final int TYPE_POLICY_CHANGED = 7;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020041
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;
Adrian Roos94e15a52015-04-16 12:23:18 -070053 final int flags;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020054
Adrian Roos7861c662014-07-25 15:37:28 +020055 // managingTrust
56 final boolean managingTrust;
57
Adrian Roos7a4f3d42014-05-02 12:12:20 +020058 private Event(int type, int userId, ComponentName agent, String message,
Adrian Roos94e15a52015-04-16 12:23:18 -070059 long duration, int flags, boolean managingTrust) {
Adrian Roos7a4f3d42014-05-02 12:12:20 +020060 this.type = type;
61 this.userId = userId;
62 this.agent = agent;
63 this.elapsedTimestamp = SystemClock.elapsedRealtime();
64 this.message = message;
65 this.duration = duration;
Adrian Roos94e15a52015-04-16 12:23:18 -070066 this.flags = flags;
Adrian Roos7861c662014-07-25 15:37:28 +020067 this.managingTrust = managingTrust;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020068 }
69 }
70
71 ArrayDeque<Event> mEvents = new ArrayDeque<Event>();
72
73 public void logGrantTrust(int userId, ComponentName agent, String message,
Adrian Roos94e15a52015-04-16 12:23:18 -070074 long duration, int flags) {
Adrian Roos7a4f3d42014-05-02 12:12:20 +020075 addEvent(new Event(TYPE_GRANT_TRUST, userId, agent, message, duration,
Adrian Roos94e15a52015-04-16 12:23:18 -070076 flags, false));
Adrian Roos7a4f3d42014-05-02 12:12:20 +020077 }
78
79 public void logRevokeTrust(int userId, ComponentName agent) {
Adrian Roos94e15a52015-04-16 12:23:18 -070080 addEvent(new Event(TYPE_REVOKE_TRUST, userId, agent, null, 0, 0, false));
Adrian Roos7a4f3d42014-05-02 12:12:20 +020081 }
82
83 public void logTrustTimeout(int userId, ComponentName agent) {
Adrian Roos94e15a52015-04-16 12:23:18 -070084 addEvent(new Event(TYPE_TRUST_TIMEOUT, userId, agent, null, 0, 0, false));
Adrian Roos7a4f3d42014-05-02 12:12:20 +020085 }
86
87 public void logAgentDied(int userId, ComponentName agent) {
Adrian Roos94e15a52015-04-16 12:23:18 -070088 addEvent(new Event(TYPE_AGENT_DIED, userId, agent, null, 0, 0, false));
Adrian Roos7a4f3d42014-05-02 12:12:20 +020089 }
90
Adrian Roos7d59b4f2014-05-27 20:01:31 +020091 public void logAgentConnected(int userId, ComponentName agent) {
Adrian Roos94e15a52015-04-16 12:23:18 -070092 addEvent(new Event(TYPE_AGENT_CONNECTED, userId, agent, null, 0, 0, false));
Adrian Roos7d59b4f2014-05-27 20:01:31 +020093 }
94
95 public void logAgentStopped(int userId, ComponentName agent) {
Adrian Roos94e15a52015-04-16 12:23:18 -070096 addEvent(new Event(TYPE_AGENT_STOPPED, userId, agent, null, 0, 0, false));
Adrian Roos7861c662014-07-25 15:37:28 +020097 }
98
99 public void logManagingTrust(int userId, ComponentName agent, boolean managing) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700100 addEvent(new Event(TYPE_MANAGING_TRUST, userId, agent, null, 0, 0, managing));
Adrian Roos7d59b4f2014-05-27 20:01:31 +0200101 }
102
Adrian Roos9d6fc922016-08-10 17:09:55 -0700103 public void logDevicePolicyChanged() {
104 addEvent(new Event(TYPE_POLICY_CHANGED, UserHandle.USER_ALL, null, null, 0, 0, false));
105 }
106
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200107 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();
Adrian Roos9d6fc922016-08-10 17:09:55 -0700120 if (userId != UserHandle.USER_ALL && userId != ev.userId
121 && ev.userId != UserHandle.USER_ALL) {
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200122 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 }
Adrian Roos9d6fc922016-08-10 17:09:55 -0700131 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 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200138 }
139 switch (ev.type) {
140 case TYPE_GRANT_TRUST:
Adrian Roos94e15a52015-04-16 12:23:18 -0700141 writer.printf(", message=\"%s\", duration=%s, flags=%s",
142 ev.message, formatDuration(ev.duration), dumpGrantFlags(ev.flags));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200143 break;
Adrian Roos7861c662014-07-25 15:37:28 +0200144 case TYPE_MANAGING_TRUST:
145 writer.printf(", managingTrust=" + ev.managingTrust);
146 break;
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200147 default:
148 }
149 writer.println();
150 count++;
151 }
152 }
153
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200154 public static String formatDuration(long duration) {
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200155 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";
Adrian Roos7d59b4f2014-05-27 20:01:31 +0200186 case TYPE_AGENT_CONNECTED:
187 return "AgentConnected";
188 case TYPE_AGENT_STOPPED:
189 return "AgentStopped";
Adrian Roos7861c662014-07-25 15:37:28 +0200190 case TYPE_MANAGING_TRUST:
191 return "ManagingTrust";
Adrian Roos9d6fc922016-08-10 17:09:55 -0700192 case TYPE_POLICY_CHANGED:
193 return "DevicePolicyChanged";
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200194 default:
195 return "Unknown(" + type + ")";
196 }
197 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700198
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 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200214}