1f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato/* 2f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Copyright (C) 2007 The Android Open Source Project 3f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * 4f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 5f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * you may not use this file except in compliance with the License. 6f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * You may obtain a copy of the License at 7f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * 8f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * http://www.apache.org/licenses/LICENSE-2.0 9f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * 10f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Unless required by applicable law or agreed to in writing, software 11f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 12f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * See the License for the specific language governing permissions and 14f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * limitations under the License. 15f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 16f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 17f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratopackage com.android.commands.am; 18f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 19f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.app.IActivityManager; 20f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.app.IInstrumentationWatcher; 21f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.app.Instrumentation; 22f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.app.UiAutomationConnection; 23f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.content.ComponentName; 24f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.content.pm.IPackageManager; 25f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.content.pm.InstrumentationInfo; 26f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.os.Build; 27f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.os.Bundle; 28f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.os.RemoteException; 29f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.os.ServiceManager; 30f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.os.UserHandle; 31f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.util.AndroidException; 32f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.util.proto.ProtoOutputStream; 33f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport android.view.IWindowManager; 34f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 35f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport java.io.IOException; 36f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport java.util.ArrayList; 37f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratoimport java.util.List; 38f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 39f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 40f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato/** 41f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Runs the am instrument command 42f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 43f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onoratopublic class Instrument { 44f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private final IActivityManager mAm; 45f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private final IPackageManager mPm; 46f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private final IWindowManager mWm; 47f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 48f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Command line arguments 49f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public String profileFile = null; 50f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public boolean wait = false; 51f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public boolean rawMode = false; 52f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public boolean proto = false; 53f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public boolean noWindowAnimation = false; 54f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public String abi = null; 55f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public int userId = UserHandle.USER_CURRENT; 56f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public Bundle args = new Bundle(); 57f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Required 58f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public String componentNameArg; 59f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 60f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 61f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Construct the instrument command runner. 62f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 63f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public Instrument(IActivityManager am, IPackageManager pm) { 64f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mAm = am; 65f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mPm = pm; 66f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 67f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 68f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 69f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 70f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Base class for status reporting. 71f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * 72f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * All the methods on this interface are called within the synchronized block 73f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * of the InstrumentationWatcher, so calls are in order. However, that means 74f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * you must be careful not to do blocking operations because you don't know 75f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * exactly the locking dependencies. 76f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 77f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private interface StatusReporter { 78f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 79f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Status update for tests. 80f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 81f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void onInstrumentationStatusLocked(ComponentName name, int resultCode, 82f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato Bundle results); 83f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 84f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 85f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * The tests finished. 86f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 87f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void onInstrumentationFinishedLocked(ComponentName name, int resultCode, 88f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato Bundle results); 89f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 90f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 91f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * @param errorText a description of the error 92f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * @param commandError True if the error is related to the commandline, as opposed 93f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * to a test failing. 94f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 95f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void onError(String errorText, boolean commandError); 96f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 97f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 98f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 99f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Printer for the 'classic' text based status reporting. 100f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 101f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private class TextStatusReporter implements StatusReporter { 102f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private boolean mRawMode; 103f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 104f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 105f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Human-ish readable output. 106f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * 107f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * @param rawMode In "raw mode" (true), all bundles are dumped. 108f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * In "pretty mode" (false), if a bundle includes 109f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Instrumentation.REPORT_KEY_STREAMRESULT, just print that. 110f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 111f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public TextStatusReporter(boolean rawMode) { 112f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mRawMode = rawMode; 113f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 114f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 115f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato @Override 116f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void onInstrumentationStatusLocked(ComponentName name, int resultCode, 117f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato Bundle results) { 118f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // pretty printer mode? 119f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato String pretty = null; 120f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (!mRawMode && results != null) { 121f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT); 122f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 123f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (pretty != null) { 124f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.out.print(pretty); 125f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else { 126f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (results != null) { 127f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato for (String key : results.keySet()) { 128f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.out.println( 129f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato "INSTRUMENTATION_STATUS: " + key + "=" + results.get(key)); 130f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 131f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 132f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode); 133f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 134f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 135f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 136f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato @Override 137f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void onInstrumentationFinishedLocked(ComponentName name, int resultCode, 138f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato Bundle results) { 139f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // pretty printer mode? 140f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato String pretty = null; 141f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (!mRawMode && results != null) { 142f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT); 143f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 144f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (pretty != null) { 145f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.out.println(pretty); 146f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else { 147f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (results != null) { 148f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato for (String key : results.keySet()) { 149f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.out.println( 150f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key)); 151f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 152f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 153f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.out.println("INSTRUMENTATION_CODE: " + resultCode); 154f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 155f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 156f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 157f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato @Override 158f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void onError(String errorText, boolean commandError) { 159f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // The regular BaseCommand error printing will print the commandErrors. 160f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (!commandError) { 161f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.out.println(errorText); 162f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 163f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 164f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 165f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 166f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 167f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Printer for the protobuf based status reporting. 168f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 169f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private class ProtoStatusReporter implements StatusReporter { 170f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato @Override 171f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void onInstrumentationStatusLocked(ComponentName name, int resultCode, 172f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato Bundle results) { 173f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final ProtoOutputStream proto = new ProtoOutputStream(); 174f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 175f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final long token = proto.startRepeatedObject(InstrumentationData.Session.TEST_STATUS); 176f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 177f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeSInt32(InstrumentationData.TestStatus.RESULT_CODE, resultCode); 178f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato writeBundle(proto, InstrumentationData.TestStatus.RESULTS, results); 179f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 180f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.endRepeatedObject(token); 181f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato writeProtoToStdout(proto); 182f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 183f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 184f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato @Override 185f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void onInstrumentationFinishedLocked(ComponentName name, int resultCode, 186f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato Bundle results) { 187f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final ProtoOutputStream proto = new ProtoOutputStream(); 188f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 189f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final long token = proto.startObject(InstrumentationData.Session.SESSION_STATUS); 190f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 191f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeEnum(InstrumentationData.SessionStatus.STATUS_CODE, 192f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato InstrumentationData.SESSION_FINISHED); 193f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeSInt32(InstrumentationData.SessionStatus.RESULT_CODE, resultCode); 194f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato writeBundle(proto, InstrumentationData.SessionStatus.RESULTS, results); 195f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 196f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.endObject(token); 197f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato writeProtoToStdout(proto); 198f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 199f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 200f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato @Override 201f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void onError(String errorText, boolean commandError) { 202f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final ProtoOutputStream proto = new ProtoOutputStream(); 203f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 204f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final long token = proto.startObject(InstrumentationData.Session.SESSION_STATUS); 205f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 206f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeEnum(InstrumentationData.SessionStatus.STATUS_CODE, 207f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato InstrumentationData.SESSION_ABORTED); 208f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeString(InstrumentationData.SessionStatus.ERROR_TEXT, errorText); 209f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 210f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.endObject(token); 211f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato writeProtoToStdout(proto); 212f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 213f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 214f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private void writeBundle(ProtoOutputStream proto, long fieldId, Bundle bundle) { 215f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final long bundleToken = proto.startObject(fieldId); 216f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 217f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato for (final String key: bundle.keySet()) { 218f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final long entryToken = proto.startRepeatedObject( 219f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato InstrumentationData.ResultsBundle.ENTRIES); 220f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 221f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeString(InstrumentationData.ResultsBundleEntry.KEY, key); 222f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 223f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final Object val = bundle.get(key); 224f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (val instanceof String) { 225f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeString(InstrumentationData.ResultsBundleEntry.VALUE_STRING, 226f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato (String)val); 227f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else if (val instanceof Byte) { 228f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeSInt32(InstrumentationData.ResultsBundleEntry.VALUE_INT, 229f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ((Byte)val).intValue()); 230f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else if (val instanceof Double) { 231f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeDouble(InstrumentationData.ResultsBundleEntry.VALUE_DOUBLE, 232f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ((Double)val).doubleValue()); 233f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else if (val instanceof Float) { 234f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeFloat(InstrumentationData.ResultsBundleEntry.VALUE_FLOAT, 235f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ((Float)val).floatValue()); 236f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else if (val instanceof Integer) { 237f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeSInt32(InstrumentationData.ResultsBundleEntry.VALUE_INT, 238f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ((Integer)val).intValue()); 239f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else if (val instanceof Long) { 240f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeSInt64(InstrumentationData.ResultsBundleEntry.VALUE_LONG, 241f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ((Long)val).longValue()); 242f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else if (val instanceof Short) { 243f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.writeSInt32(InstrumentationData.ResultsBundleEntry.VALUE_INT, 244f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ((Short)val).intValue()); 245f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else if (val instanceof Bundle) { 246f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato writeBundle(proto, InstrumentationData.ResultsBundleEntry.VALUE_BUNDLE, 247f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato (Bundle)val); 248f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 249f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 250f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.endRepeatedObject(entryToken); 251f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 252f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 253f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato proto.endObject(bundleToken); 254f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 255f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 256f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private void writeProtoToStdout(ProtoOutputStream proto) { 257f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato try { 258f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.out.write(proto.getBytes()); 259f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.out.flush(); 260f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } catch (IOException ex) { 261f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato System.err.println("Error writing finished response: "); 262f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ex.printStackTrace(System.err); 263f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 264f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 265f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 266f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 267f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 268f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 269f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Callbacks from the remote instrumentation instance. 270f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 271f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private class InstrumentationWatcher extends IInstrumentationWatcher.Stub { 272f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private final StatusReporter mReporter; 273f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 274f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private boolean mFinished = false; 275f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 276f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public InstrumentationWatcher(StatusReporter reporter) { 277f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mReporter = reporter; 278f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 279f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 280f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato @Override 281f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) { 282f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato synchronized (this) { 283f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mReporter.onInstrumentationStatusLocked(name, resultCode, results); 284f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato notifyAll(); 285f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 286f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 287f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 288f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato @Override 289f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void instrumentationFinished(ComponentName name, int resultCode, Bundle results) { 290f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato synchronized (this) { 291f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mReporter.onInstrumentationFinishedLocked(name, resultCode, results); 292f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mFinished = true; 293f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato notifyAll(); 294f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 295f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 296f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 297f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public boolean waitForFinish() { 298f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato synchronized (this) { 299f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato while (!mFinished) { 300f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato try { 301f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (!mAm.asBinder().pingBinder()) { 302f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato return false; 303f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 304f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato wait(1000); 305f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } catch (InterruptedException e) { 306f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato throw new IllegalStateException(e); 307f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 308f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 309f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 310f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato return true; 311f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 312f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 313f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 314f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 315f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Figure out which component they really meant. 316f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 317f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato private ComponentName parseComponentName(String cnArg) throws Exception { 318f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (cnArg.contains("/")) { 319f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ComponentName cn = ComponentName.unflattenFromString(cnArg); 320f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg); 321f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato return cn; 322f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else { 323f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato List<InstrumentationInfo> infos = mPm.queryInstrumentation(null, 0).getList(); 324f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 325f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final int numInfos = infos == null ? 0: infos.size(); 326f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ArrayList<ComponentName> cns = new ArrayList<>(); 327f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato for (int i = 0; i < numInfos; i++) { 328f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato InstrumentationInfo info = infos.get(i); 329f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 330f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato ComponentName c = new ComponentName(info.packageName, info.name); 331f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (cnArg.equals(info.packageName)) { 332f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato cns.add(c); 333f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 334f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 335f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 336f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (cns.size() == 0) { 337f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato throw new IllegalArgumentException("No instrumentation found for: " + cnArg); 338f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else if (cns.size() == 1) { 339f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato return cns.get(0); 340f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else { 341f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato StringBuilder cnsStr = new StringBuilder(); 342f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final int numCns = cns.size(); 343f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato for (int i = 0; i < numCns; i++) { 344f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato cnsStr.append(cns.get(i).flattenToString()); 345f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato cnsStr.append(", "); 346f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 347f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 348f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Remove last ", " 349f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato cnsStr.setLength(cnsStr.length() - 2); 350f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 351f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato throw new IllegalArgumentException("Found multiple instrumentations: " 352f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato + cnsStr.toString()); 353f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 354f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 355f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 356f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 357f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato /** 358f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato * Run the instrumentation. 359f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato */ 360f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato public void run() throws Exception { 361f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato StatusReporter reporter = null; 362f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato float[] oldAnims = null; 363f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 364f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato try { 365f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Choose which output we will do. 366f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (proto) { 367f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato reporter = new ProtoStatusReporter(); 368f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } else if (wait) { 369f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato reporter = new TextStatusReporter(rawMode); 370f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 371f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 372f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Choose whether we have to wait for the results. 373f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato InstrumentationWatcher watcher = null; 374f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato UiAutomationConnection connection = null; 375f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (reporter != null) { 376f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato watcher = new InstrumentationWatcher(reporter); 377f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato connection = new UiAutomationConnection(); 378f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 379f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 380f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Set the window animation if necessary 381f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (noWindowAnimation) { 382f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato oldAnims = mWm.getAnimationScales(); 383f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mWm.setAnimationScale(0, 0.0f); 384f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mWm.setAnimationScale(1, 0.0f); 385e5b44043f75bab47955652b5bd98502ce2294f37Chet Haase mWm.setAnimationScale(2, 0.0f); 386f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 387f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 388f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Figure out which component we are tring to do. 389f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final ComponentName cn = parseComponentName(componentNameArg); 390f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 391f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Choose an ABI if necessary 392f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (abi != null) { 393f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato final String[] supportedAbis = Build.SUPPORTED_ABIS; 394f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato boolean matched = false; 395f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato for (String supportedAbi : supportedAbis) { 396f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (supportedAbi.equals(abi)) { 397f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato matched = true; 398f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato break; 399f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 400f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 401f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (!matched) { 402f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato throw new AndroidException( 403f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato "INSTRUMENTATION_FAILED: Unsupported instruction set " + abi); 404f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 405f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 406f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 407f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Start the instrumentation 408f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId, 409f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato abi)) { 410f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString()); 411f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 412f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 413f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // If we have been requested to wait, do so until the instrumentation is finished. 414f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (watcher != null) { 415f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (!watcher.waitForFinish()) { 416f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato reporter.onError("INSTRUMENTATION_ABORTED: System has crashed.", false); 417f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato return; 418f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 419f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 420f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } catch (Exception ex) { 421f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Report failures 422f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (reporter != null) { 423f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato reporter.onError(ex.getMessage(), true); 424f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 425f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 426f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // And re-throw the exception 427f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato throw ex; 428f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } finally { 429f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato // Clean up 430f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato if (oldAnims != null) { 431f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato mWm.setAnimationScales(oldAnims); 432f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 433f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 434f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato } 435f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato} 436f0c719821dfdd32e37c4de6b4d640cefcda7b32aJoe Onorato 437