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