1 /*
2  * Copyright (C) 2019 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.content.ComponentName;
20 
21 /**
22  * This class describes various information required to start a process.
23  *
24  * The {@code mHostingType} field describes the reason why we started a process, and
25  * is only used for logging and stats.
26  *
27  * The {@code mHostingName} field describes the Component for which we are starting the
28  * process, and is only used for logging and stats.
29  *
30  * The {@code mHostingZygote} field describes from which Zygote the new process should be spawned.
31  *
32  * {@code mDefiningPackageName} contains the packageName of the package that defines the
33  * component we want to start; this can be different from the packageName and uid in the
34  * ApplicationInfo that we're creating the process with, in case the service is a
35  * {@link android.content.Context#BIND_EXTERNAL_SERVICE} service. In that case, the packageName
36  * and uid in the ApplicationInfo will be set to those of the caller, not of the defining package.
37  *
38  * {@code mDefiningUid} contains the uid of the application that defines the component we want to
39  * start; this can be different from the packageName and uid in the ApplicationInfo that we're
40  * creating the process with, in case the service is a
41  * {@link android.content.Context#BIND_EXTERNAL_SERVICE} service. In that case, the packageName
42  * and uid in the ApplicationInfo will be set to those of the caller, not of the defining package.
43  *
44  * {@code mIsTopApp} will be passed to {@link android.os.Process#start}. So Zygote will initialize
45  * the process with high priority.
46  */
47 
48 public final class HostingRecord {
49     private static final int REGULAR_ZYGOTE = 0;
50     private static final int WEBVIEW_ZYGOTE = 1;
51     private static final int APP_ZYGOTE = 2;
52 
53     private final String mHostingType;
54     private final String mHostingName;
55     private final int mHostingZygote;
56     private final String mDefiningPackageName;
57     private final int mDefiningUid;
58     private final boolean mIsTopApp;
59 
HostingRecord(String hostingType)60     public HostingRecord(String hostingType) {
61         this(hostingType, null /* hostingName */, REGULAR_ZYGOTE, null /* definingPackageName */,
62                 -1 /* mDefiningUid */, false /* isTopApp */);
63     }
64 
HostingRecord(String hostingType, ComponentName hostingName)65     public HostingRecord(String hostingType, ComponentName hostingName) {
66         this(hostingType, hostingName, REGULAR_ZYGOTE);
67     }
68 
HostingRecord(String hostingType, ComponentName hostingName, boolean isTopApp)69     public HostingRecord(String hostingType, ComponentName hostingName, boolean isTopApp) {
70         this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE,
71                 null /* definingPackageName */, -1 /* mDefiningUid */, isTopApp /* isTopApp */);
72     }
73 
HostingRecord(String hostingType, String hostingName)74     public HostingRecord(String hostingType, String hostingName) {
75         this(hostingType, hostingName, REGULAR_ZYGOTE);
76     }
77 
HostingRecord(String hostingType, ComponentName hostingName, int hostingZygote)78     private HostingRecord(String hostingType, ComponentName hostingName, int hostingZygote) {
79         this(hostingType, hostingName.toShortString(), hostingZygote);
80     }
81 
HostingRecord(String hostingType, String hostingName, int hostingZygote)82     private HostingRecord(String hostingType, String hostingName, int hostingZygote) {
83         this(hostingType, hostingName, hostingZygote, null /* definingPackageName */,
84                 -1 /* mDefiningUid */, false /* isTopApp */);
85     }
86 
HostingRecord(String hostingType, String hostingName, int hostingZygote, String definingPackageName, int definingUid, boolean isTopApp)87     private HostingRecord(String hostingType, String hostingName, int hostingZygote,
88             String definingPackageName, int definingUid, boolean isTopApp) {
89         mHostingType = hostingType;
90         mHostingName = hostingName;
91         mHostingZygote = hostingZygote;
92         mDefiningPackageName = definingPackageName;
93         mDefiningUid = definingUid;
94         mIsTopApp = isTopApp;
95     }
96 
getType()97     public String getType() {
98         return mHostingType;
99     }
100 
getName()101     public String getName() {
102         return mHostingName;
103     }
104 
isTopApp()105     public boolean isTopApp() {
106         return mIsTopApp;
107     }
108 
109     /**
110      * Returns the UID of the package defining the component we want to start. Only valid
111      * when {@link #usesAppZygote()} returns true.
112      *
113      * @return the UID of the hosting application
114      */
getDefiningUid()115     public int getDefiningUid() {
116         return mDefiningUid;
117     }
118 
119     /**
120      * Returns the packageName of the package defining the component we want to start. Only valid
121      * when {@link #usesAppZygote()} returns true.
122      *
123      * @return the packageName of the hosting application
124      */
getDefiningPackageName()125     public String getDefiningPackageName() {
126         return mDefiningPackageName;
127     }
128 
129     /**
130      * Creates a HostingRecord for a process that must spawn from the webview zygote
131      * @param hostingName name of the component to be hosted in this process
132      * @return The constructed HostingRecord
133      */
byWebviewZygote(ComponentName hostingName)134     public static HostingRecord byWebviewZygote(ComponentName hostingName) {
135         return new HostingRecord("", hostingName.toShortString(), WEBVIEW_ZYGOTE);
136     }
137 
138     /**
139      * Creates a HostingRecord for a process that must spawn from the application zygote
140      * @param hostingName name of the component to be hosted in this process
141      * @param definingPackageName name of the package defining the service
142      * @param definingUid uid of the package defining the service
143      * @return The constructed HostingRecord
144      */
byAppZygote(ComponentName hostingName, String definingPackageName, int definingUid)145     public static HostingRecord byAppZygote(ComponentName hostingName, String definingPackageName,
146             int definingUid) {
147         return new HostingRecord("", hostingName.toShortString(), APP_ZYGOTE,
148                 definingPackageName, definingUid, false /* isTopApp */);
149     }
150 
151     /**
152      * @return whether the process should spawn from the application zygote
153      */
usesAppZygote()154     public boolean usesAppZygote() {
155         return mHostingZygote == APP_ZYGOTE;
156     }
157 
158     /**
159      * @return whether the process should spawn from the webview zygote
160      */
usesWebviewZygote()161     public boolean usesWebviewZygote() {
162         return mHostingZygote == WEBVIEW_ZYGOTE;
163     }
164 }
165