TrustArchive.java revision 2bb8bfd1e85c8359412159fde57dd5722f5be58c
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    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
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
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
77    public void logRevokeTrust(int userId, ComponentName agent) {
78        addEvent(new Event(TYPE_REVOKE_TRUST, userId, agent, null, 0, false, false));
79    }
80
81    public void logTrustTimeout(int userId, ComponentName agent) {
82        addEvent(new Event(TYPE_TRUST_TIMEOUT, userId, agent, null, 0, false, false));
83    }
84
85    public void logAgentDied(int userId, ComponentName agent) {
86        addEvent(new Event(TYPE_AGENT_DIED, userId, agent, null, 0, false, false));
87    }
88
89    public void logAgentConnected(int userId, ComponentName agent) {
90        addEvent(new Event(TYPE_AGENT_CONNECTED, userId, agent, null, 0, false, false));
91    }
92
93    public void logAgentStopped(int userId, ComponentName agent) {
94        addEvent(new Event(TYPE_AGENT_STOPPED, userId, agent, null, 0, false, false));
95    }
96
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
101    private void addEvent(Event e) {
102        if (mEvents.size() >= HISTORY_LIMIT) {
103            mEvents.removeFirst();
104        }
105        mEvents.addLast(e);
106    }
107
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
145    public static String formatDuration(long duration) {
146        StringBuilder sb = new StringBuilder();
147        TimeUtils.formatDuration(duration, sb);
148        return sb.toString();
149    }
150
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
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
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