1 /*
2  * Copyright (C) 2017 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 
17 package com.android.server.am;
18 
19 import android.app.IInstrumentationWatcher;
20 import android.app.IUiAutomationConnection;
21 import android.content.ComponentName;
22 import android.content.pm.ApplicationInfo;
23 import android.os.Bundle;
24 import android.util.PrintWriterPrinter;
25 
26 import java.io.PrintWriter;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 
30 class ActiveInstrumentation {
31     final ActivityManagerService mService;
32 
33     // Class installed to instrument app
34     ComponentName mClass;
35 
36     // All process names that should be instrumented
37     String[] mTargetProcesses;
38 
39     // The application being instrumented
40     ApplicationInfo mTargetInfo;
41 
42     // Where to save profiling
43     String mProfileFile;
44 
45     // Who is waiting
46     IInstrumentationWatcher mWatcher;
47 
48     // Connection to use the UI introspection APIs.
49     IUiAutomationConnection mUiAutomationConnection;
50 
51     // As given to us
52     Bundle mArguments;
53 
54     // Any intermediate results that have been collected.
55     Bundle mCurResults;
56 
57     // Copy of instrumentationClass.
58     ComponentName mResultClass;
59 
60     // Contains all running processes that have active instrumentation.
61     final ArrayList<ProcessRecord> mRunningProcesses = new ArrayList<>();
62 
63     // Set to true when we have told the watcher the instrumentation is finished.
64     boolean mFinished;
65 
ActiveInstrumentation(ActivityManagerService service)66     ActiveInstrumentation(ActivityManagerService service) {
67         mService = service;
68     }
69 
removeProcess(ProcessRecord proc)70     void removeProcess(ProcessRecord proc) {
71         mFinished = true;
72         mRunningProcesses.remove(proc);
73         if (mRunningProcesses.size() == 0) {
74             mService.mActiveInstrumentation.remove(this);
75         }
76     }
77 
toString()78     public String toString() {
79         StringBuilder sb = new StringBuilder(128);
80         sb.append("ActiveInstrumentation{");
81         sb.append(Integer.toHexString(System.identityHashCode(this)));
82         sb.append(' ');
83         sb.append(mClass.toShortString());
84         if (mFinished) {
85             sb.append(" FINISHED");
86         }
87         sb.append(" ");
88         sb.append(mRunningProcesses.size());
89         sb.append(" procs");
90         sb.append('}');
91         return sb.toString();
92     }
93 
dump(PrintWriter pw, String prefix)94     void dump(PrintWriter pw, String prefix) {
95         pw.print(prefix); pw.print("mClass="); pw.print(mClass);
96         pw.print(" mFinished="); pw.println(mFinished);
97         pw.print(prefix); pw.println("mRunningProcesses:");
98         for (int i=0; i<mRunningProcesses.size(); i++) {
99             pw.print(prefix); pw.print("  #"); pw.print(i); pw.print(": ");
100             pw.println(mRunningProcesses.get(i));
101         }
102         pw.print(prefix); pw.print("mTargetProcesses=");
103         pw.println(Arrays.toString(mTargetProcesses));
104         pw.print(prefix); pw.print("mTargetInfo=");
105         pw.println(mTargetInfo);
106         if (mTargetInfo != null) {
107             mTargetInfo.dump(new PrintWriterPrinter(pw), prefix + "  ", 0);
108         }
109         if (mProfileFile != null) {
110             pw.print(prefix); pw.print("mProfileFile="); pw.println(mProfileFile);
111         }
112         if (mWatcher != null) {
113             pw.print(prefix); pw.print("mWatcher="); pw.println(mWatcher);
114         }
115         if (mUiAutomationConnection != null) {
116             pw.print(prefix); pw.print("mUiAutomationConnection=");
117             pw.println(mUiAutomationConnection);
118         }
119         pw.print(prefix); pw.print("mArguments=");
120         pw.println(mArguments);
121     }
122 }
123