| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.server.am; |
| |
| import android.app.IInstrumentationWatcher; |
| import android.app.IUiAutomationConnection; |
| import android.content.ComponentName; |
| import android.content.pm.ApplicationInfo; |
| import android.os.Bundle; |
| import android.util.PrintWriterPrinter; |
| import android.util.proto.ProtoOutputStream; |
| |
| import java.io.PrintWriter; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| |
| class ActiveInstrumentation { |
| final ActivityManagerService mService; |
| |
| // Class installed to instrument app |
| ComponentName mClass; |
| |
| // All process names that should be instrumented |
| String[] mTargetProcesses; |
| |
| // The application being instrumented |
| ApplicationInfo mTargetInfo; |
| |
| // Where to save profiling |
| String mProfileFile; |
| |
| // Who is waiting |
| IInstrumentationWatcher mWatcher; |
| |
| // Connection to use the UI introspection APIs. |
| IUiAutomationConnection mUiAutomationConnection; |
| |
| // As given to us |
| Bundle mArguments; |
| |
| // Any intermediate results that have been collected. |
| Bundle mCurResults; |
| |
| // Copy of instrumentationClass. |
| ComponentName mResultClass; |
| |
| // Contains all running processes that have active instrumentation. |
| final ArrayList<ProcessRecord> mRunningProcesses = new ArrayList<>(); |
| |
| // Set to true when we have told the watcher the instrumentation is finished. |
| boolean mFinished; |
| |
| ActiveInstrumentation(ActivityManagerService service) { |
| mService = service; |
| } |
| |
| void removeProcess(ProcessRecord proc) { |
| mFinished = true; |
| mRunningProcesses.remove(proc); |
| if (mRunningProcesses.size() == 0) { |
| mService.mActiveInstrumentation.remove(this); |
| } |
| } |
| |
| public String toString() { |
| StringBuilder sb = new StringBuilder(128); |
| sb.append("ActiveInstrumentation{"); |
| sb.append(Integer.toHexString(System.identityHashCode(this))); |
| sb.append(' '); |
| sb.append(mClass.toShortString()); |
| if (mFinished) { |
| sb.append(" FINISHED"); |
| } |
| sb.append(" "); |
| sb.append(mRunningProcesses.size()); |
| sb.append(" procs"); |
| sb.append('}'); |
| return sb.toString(); |
| } |
| |
| void dump(PrintWriter pw, String prefix) { |
| pw.print(prefix); pw.print("mClass="); pw.print(mClass); |
| pw.print(" mFinished="); pw.println(mFinished); |
| pw.print(prefix); pw.println("mRunningProcesses:"); |
| for (int i=0; i<mRunningProcesses.size(); i++) { |
| pw.print(prefix); pw.print(" #"); pw.print(i); pw.print(": "); |
| pw.println(mRunningProcesses.get(i)); |
| } |
| pw.print(prefix); pw.print("mTargetProcesses="); |
| pw.println(Arrays.toString(mTargetProcesses)); |
| pw.print(prefix); pw.print("mTargetInfo="); |
| pw.println(mTargetInfo); |
| if (mTargetInfo != null) { |
| mTargetInfo.dump(new PrintWriterPrinter(pw), prefix + " ", 0); |
| } |
| if (mProfileFile != null) { |
| pw.print(prefix); pw.print("mProfileFile="); pw.println(mProfileFile); |
| } |
| if (mWatcher != null) { |
| pw.print(prefix); pw.print("mWatcher="); pw.println(mWatcher); |
| } |
| if (mUiAutomationConnection != null) { |
| pw.print(prefix); pw.print("mUiAutomationConnection="); |
| pw.println(mUiAutomationConnection); |
| } |
| pw.print(prefix); pw.print("mArguments="); |
| pw.println(mArguments); |
| } |
| |
| void writeToProto(ProtoOutputStream proto, long fieldId) { |
| long token = proto.start(fieldId); |
| mClass.writeToProto(proto, ActiveInstrumentationProto.CLASS); |
| proto.write(ActiveInstrumentationProto.FINISHED, mFinished); |
| for (int i=0; i<mRunningProcesses.size(); i++) { |
| mRunningProcesses.get(i).writeToProto(proto, |
| ActiveInstrumentationProto.RUNNING_PROCESSES); |
| } |
| for (String p : mTargetProcesses) { |
| proto.write(ActiveInstrumentationProto.TARGET_PROCESSES, p); |
| } |
| if (mTargetInfo != null) { |
| mTargetInfo.writeToProto(proto, ActiveInstrumentationProto.TARGET_INFO); |
| } |
| proto.write(ActiveInstrumentationProto.PROFILE_FILE, mProfileFile); |
| proto.write(ActiveInstrumentationProto.WATCHER, mWatcher.toString()); |
| proto.write(ActiveInstrumentationProto.UI_AUTOMATION_CONNECTION, |
| mUiAutomationConnection.toString()); |
| proto.write(ActiveInstrumentationProto.ARGUMENTS, mArguments.toString()); |
| proto.end(token); |
| } |
| } |