blob: c05cc3ff882706f0225b02f9bff3ecaefb5e7bfb [file] [log] [blame]
Felipe Lemef4006d92016-10-07 17:57:13 -07001/**
2 * Copyright (c) 2016, 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.utils;
18
19import java.io.FileDescriptor;
20import java.io.PrintWriter;
21
22/**
23 * Helper for {@link android.os.Binder#dump(java.io.FileDescriptor, String[])} that supports the
24 * {@link #PRIORITY_ARG} argument.
25 * <p>
26 * Typical usage:
27 *
28 * <pre><code>
29public class SpringfieldNuclearPowerPlant extends Binder {
30
31 private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
32
33 @Override
34 public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) {
35 pw.println("Donuts in the box: 1");
36 }
37
38 @Override
39 public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
40 pw.println("Nuclear reactor status: DANGER - MELTDOWN IMMINENT");
41 }
42 };
43
44 @Override
45 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
46 PriorityDump.dump(mPriorityDumper, fd, pw, args);
47 }
48}
49
50 * </code></pre>
51 *
52 * <strong>Disclaimer</strong>: a real-life service should prioritize core status over donuts :-)
53 *
54 * <p>Then to invoke it:
55 *
56 * <pre><code>
57 *
58 $ adb shell dumpsys snpp
59 Donuts in the box: 1
60 Nuclear reactor status: DANGER - MELTDOWN IMMINENT
61
62 $ adb shell dumpsys snpp --dump_priority CRITICAL
63 Donuts in the box: 1
64
65 $ adb shell dumpsys snpp --dump_priority NORMAL
66 Nuclear reactor status: DANGER - MELTDOWN IMMINENT
67
68 * </code></pre>
69 *
70 *
71 *
72 * <p>To run the unit tests:
73 * <pre><code>
74 *
75 mmm -j32 frameworks/base/services/tests/servicestests/ && \
76 adb install -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && \
77 adb shell am instrument -e class "com.android.server.utils.PriorityDumpTest" \
78 -w "com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner"
79
80 * </code></pre>
81 *
82 *
83 * @hide
84 */
85public final class PriorityDump {
86
87 public static final String PRIORITY_ARG = "--dump_priority";
88
89 private PriorityDump() {
90 throw new UnsupportedOperationException();
91 }
92
93 /**
94 * Parses {@code} and call the proper {@link PriorityDumper} method when the first argument is
95 * {@code --dump_priority}, stripping the priority and its type.
96 * <p>
97 * For example, if called as {@code --dump_priority HIGH arg1 arg2 arg3}, it will call
98 * <code>dumper.dumpHigh(fd, pw, {"arg1", "arg2", "arg3"}) </code>
99 * <p>
100 * If the {@code --dump_priority} is not set, it calls
101 * {@link PriorityDumper#dump(FileDescriptor, PrintWriter, String[])} passing the whole
102 * {@code args} instead.
103 */
104 public static void dump(PriorityDumper dumper, FileDescriptor fd, PrintWriter pw,
105 String[] args) {
106 if (args != null && args.length >= 2 && args[0].equals(PRIORITY_ARG)) {
107 final String priority = args[1];
108 switch (priority) {
109 case "CRITICAL": {
110 dumper.dumpCritical(fd, pw, getStrippedArgs(args));
111 return;
112 }
113 case "HIGH": {
114 dumper.dumpHigh(fd, pw, getStrippedArgs(args));
115 return;
116 }
117 case "NORMAL": {
118 dumper.dumpNormal(fd, pw, getStrippedArgs(args));
119 return;
120 }
121 }
122 }
123 dumper.dump(fd, pw, args);
124 }
125
126 /**
127 * Gets an array without the {@code --dump_priority PRIORITY} prefix.
128 */
129 private static String[] getStrippedArgs(String[] args) {
130 final String[] stripped = new String[args.length - 2];
131 System.arraycopy(args, 2, stripped, 0, stripped.length);
132 return stripped;
133 }
134
135 /**
136 * Helper for {@link android.os.Binder#dump(java.io.FileDescriptor, String[])} that supports the
137 * {@link #PRIORITY_ARG} argument.
138 *
139 * @hide
140 */
141 public static interface PriorityDumper {
142
143 /**
144 * Dumps only the critical section.
145 */
146 @SuppressWarnings("unused")
147 default void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) {
148 }
149
150 /**
151 * Dumps only the high-priority section.
152 */
153 @SuppressWarnings("unused")
154 default void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args) {
155 }
156
157 /**
158 * Dumps only the normal section.
159 */
160 @SuppressWarnings("unused")
161 default void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
162 }
163
164 /**
165 * Dumps all sections.
166 * <p>
167 * This method is called when
168 * {@link PriorityDump#dump(PriorityDumper, FileDescriptor, PrintWriter, String[])} is
169 * called without priority arguments. By default, it calls the 3 {@code dumpTYPE} methods,
170 * so sub-classes just need to implement the priority types they support.
171 */
172 @SuppressWarnings("unused")
173 default void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
174 dumpCritical(fd, pw, args);
175 dumpHigh(fd, pw, args);
176 dumpNormal(fd, pw, args);
177 }
178 }
179}