blob: 432d7f335ebc3d8e0edfd1b08d7fbdb2f99eb824 [file] [log] [blame]
Kenny Rootcf0b38c2011-03-22 14:17:59 -07001/*
2 * Copyright (C) 2011 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
17package com.android.server.pm;
18
Winsone0756292020-01-31 12:21:54 -080019import android.annotation.NonNull;
Taras Antoshchuka7d9c732019-10-29 13:46:19 +010020import android.annotation.Nullable;
Christopher Tate628946a2013-10-18 18:11:05 -070021import android.content.pm.ApplicationInfo;
Jeff Sharkeyc5967e92016-01-07 18:50:29 -070022import android.content.pm.PackageManager;
Netta P426cbef2017-02-10 14:38:39 -080023import android.content.pm.UserInfo;
24import android.service.pm.PackageProto;
Taras Antoshchuka7d9c732019-10-29 13:46:19 +010025import android.util.ArrayMap;
26import android.util.ArraySet;
Netta P426cbef2017-02-10 14:38:39 -080027import android.util.proto.ProtoOutputStream;
Kenny Rootcf0b38c2011-03-22 14:17:59 -070028
Winson Chiu8e865ec2020-04-01 18:20:51 +000029import com.android.internal.annotations.VisibleForTesting;
Winsone23ae202020-01-24 11:56:44 -080030import com.android.server.pm.parsing.pkg.AndroidPackage;
Todd Kennedy82b08422017-09-28 13:32:05 -070031import com.android.server.pm.permission.PermissionsState;
Winsone0756292020-01-31 12:21:54 -080032import com.android.server.pm.pkg.PackageStateUnserialized;
Todd Kennedy82b08422017-09-28 13:32:05 -070033
Kenny Rootcf0b38c2011-03-22 14:17:59 -070034import java.io.File;
Taras Antoshchuka7d9c732019-10-29 13:46:19 +010035import java.util.ArrayList;
36import java.util.Collections;
Svet Ganov354cd3c2015-12-17 11:35:04 -080037import java.util.List;
Taras Antoshchuka7d9c732019-10-29 13:46:19 +010038import java.util.Map;
39import java.util.Set;
Kenny Rootcf0b38c2011-03-22 14:17:59 -070040
41/**
42 * Settings data for a particular package we know about.
43 */
Winsone0756292020-01-31 12:21:54 -080044public class PackageSetting extends PackageSettingBase {
Amith Yamasani13593602012-03-22 16:16:17 -070045 int appId;
Winson14ff7172019-10-23 10:42:27 -070046
Patrick Baumann74860922020-04-01 14:10:04 -070047 @Nullable
Winson14ff7172019-10-23 10:42:27 -070048 public AndroidPackage pkg;
Todd Kennedy3cd658e2016-08-16 15:00:31 -070049 /**
50 * WARNING. The object reference is important. We perform integer equality and NOT
51 * object equality to check whether shared user settings are the same.
52 */
Kenny Rootcf0b38c2011-03-22 14:17:59 -070053 SharedUserSetting sharedUser;
Todd Kennedy788c8422016-08-10 10:52:34 -070054 /**
55 * Temporary holding space for the shared user ID. While parsing package settings, the
Todd Kennedy3cd658e2016-08-16 15:00:31 -070056 * shared users tag may come after the packages. In this case, we must delay linking the
Todd Kennedy788c8422016-08-10 10:52:34 -070057 * shared user setting with the package setting. The shared user ID lets us link the
58 * two objects.
59 */
60 private int sharedUserId;
Kenny Rootcf0b38c2011-03-22 14:17:59 -070061
Taras Antoshchuka7d9c732019-10-29 13:46:19 +010062 /**
63 * Maps mime group name to the set of Mime types in a group. Mime groups declared
64 * by app are populated with empty sets at construction.
65 * Mime groups can not be created/removed at runtime, thus keys in this map should not change
66 */
67 @Nullable
68 Map<String, ArraySet<String>> mimeGroups;
69
Winsone0756292020-01-31 12:21:54 -080070 @NonNull
71 private PackageStateUnserialized pkgState = new PackageStateUnserialized();
72
Winson Chiu8e865ec2020-04-01 18:20:51 +000073 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
74 public PackageSetting(String name, String realName, File codePath, File resourcePath,
Narayan Kamathff110bd2014-07-04 18:30:45 +010075 String legacyNativeLibraryPathString, String primaryCpuAbiString,
Narayan Kamath4903f642014-08-11 13:33:45 +010076 String secondaryCpuAbiString, String cpuAbiOverrideString,
Winson14ff7172019-10-23 10:42:27 -070077 long pVersionCode, int pkgFlags, int privateFlags,
78 int sharedUserId, String[] usesStaticLibraries,
Taras Antoshchuka7d9c732019-10-29 13:46:19 +010079 long[] usesStaticLibrariesVersions, Map<String, ArraySet<String>> mimeGroups) {
Narayan Kamathff110bd2014-07-04 18:30:45 +010080 super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString,
Narayan Kamath4903f642014-08-11 13:33:45 +010081 primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
Winson14ff7172019-10-23 10:42:27 -070082 pVersionCode, pkgFlags, privateFlags,
Svet Ganov67882122016-12-11 16:36:34 -080083 usesStaticLibraries, usesStaticLibrariesVersions);
Todd Kennedy788c8422016-08-10 10:52:34 -070084 this.sharedUserId = sharedUserId;
Taras Antoshchuka7d9c732019-10-29 13:46:19 +010085 copyMimeGroups(mimeGroups);
Kenny Rootcf0b38c2011-03-22 14:17:59 -070086 }
87
88 /**
89 * New instance of PackageSetting replicating the original settings.
90 * Note that it keeps the same PackageParser.Package instance.
91 */
92 PackageSetting(PackageSetting orig) {
Todd Kennedy3cd658e2016-08-16 15:00:31 -070093 super(orig, orig.realName);
94 doCopy(orig);
95 }
96
97 /**
98 * New instance of PackageSetting replicating the original settings, but, allows specifying
99 * a real package name.
100 * Note that it keeps the same PackageParser.Package instance.
101 */
102 PackageSetting(PackageSetting orig, String realPkgName) {
103 super(orig, realPkgName);
Todd Kennedy788c8422016-08-10 10:52:34 -0700104 doCopy(orig);
105 }
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700106
Todd Kennedy788c8422016-08-10 10:52:34 -0700107 public int getSharedUserId() {
108 if (sharedUser != null) {
109 return sharedUser.userId;
110 }
111 return sharedUserId;
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700112 }
113
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700114 public SharedUserSetting getSharedUser() {
115 return sharedUser;
116 }
117
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700118 @Override
119 public String toString() {
120 return "PackageSetting{"
121 + Integer.toHexString(System.identityHashCode(this))
Amith Yamasani13593602012-03-22 16:16:17 -0700122 + " " + name + "/" + appId + "}";
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700123 }
Jeff Sharkey02e4d16e2013-08-12 20:31:36 -0700124
Todd Kennedy788c8422016-08-10 10:52:34 -0700125 public void copyFrom(PackageSetting orig) {
126 super.copyFrom(orig);
127 doCopy(orig);
128 }
129
130 private void doCopy(PackageSetting orig) {
131 appId = orig.appId;
132 pkg = orig.pkg;
133 sharedUser = orig.sharedUser;
134 sharedUserId = orig.sharedUserId;
Taras Antoshchuka7d9c732019-10-29 13:46:19 +0100135 copyMimeGroups(orig.mimeGroups);
136 }
137
138 private void copyMimeGroups(@Nullable Map<String, ArraySet<String>> newMimeGroups) {
139 if (newMimeGroups == null) {
140 mimeGroups = null;
141 return;
142 }
143
144 mimeGroups = new ArrayMap<>(newMimeGroups.size());
145 for (String mimeGroup : newMimeGroups.keySet()) {
146 ArraySet<String> mimeTypes = newMimeGroups.get(mimeGroup);
147
148 if (mimeTypes != null) {
149 mimeGroups.put(mimeGroup, new ArraySet<>(mimeTypes));
150 } else {
151 mimeGroups.put(mimeGroup, new ArraySet<>());
152 }
153 }
154 }
155
156 /**
157 * Updates declared MIME groups, removing no longer declared groups
158 * and keeping previous state of MIME groups
159 */
160 void updateMimeGroups(@Nullable Set<String> newMimeGroupNames) {
161 if (newMimeGroupNames == null) {
162 mimeGroups = null;
163 return;
164 }
165
166 if (mimeGroups == null) {
167 // set mimeGroups to empty map to avoid repeated null-checks in the next loop
168 mimeGroups = Collections.emptyMap();
169 }
170
171 ArrayMap<String, ArraySet<String>> updatedMimeGroups =
172 new ArrayMap<>(newMimeGroupNames.size());
173
174 for (String mimeGroup : newMimeGroupNames) {
175 if (mimeGroups.containsKey(mimeGroup)) {
176 updatedMimeGroups.put(mimeGroup, mimeGroups.get(mimeGroup));
177 } else {
178 updatedMimeGroups.put(mimeGroup, new ArraySet<>());
179 }
180 }
181 mimeGroups = updatedMimeGroups;
Todd Kennedy788c8422016-08-10 10:52:34 -0700182 }
183
Todd Kennedy91a39d12017-09-27 12:37:04 -0700184 @Override
Svetoslavc6d1c342015-02-26 14:44:43 -0800185 public PermissionsState getPermissionsState() {
186 return (sharedUser != null)
187 ? sharedUser.getPermissionsState()
188 : super.getPermissionsState();
Jeff Sharkey02e4d16e2013-08-12 20:31:36 -0700189 }
Christopher Tate628946a2013-10-18 18:11:05 -0700190
Todd Kennedy0eb97382017-10-03 16:57:22 -0700191 public int getAppId() {
192 return appId;
193 }
194
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700195 public void setInstallPermissionsFixed(boolean fixed) {
196 installPermissionsFixed = fixed;
197 }
198
199 public boolean areInstallPermissionsFixed() {
200 return installPermissionsFixed;
201 }
202
Winson14ff7172019-10-23 10:42:27 -0700203 // TODO(b/135203078): Remove these in favor of reading from the package directly
Christopher Tate628946a2013-10-18 18:11:05 -0700204 public boolean isPrivileged() {
Alex Klyubinb9f8a522015-02-03 11:12:59 -0800205 return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
Christopher Tate628946a2013-10-18 18:11:05 -0700206 }
Fyodor Kupoloveeea67b2015-02-23 17:14:45 -0800207
Svet Ganov087dce22017-09-07 15:42:16 -0700208 public boolean isOem() {
209 return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
210 }
211
Jiyong Park002fdbd2017-02-13 20:50:31 +0900212 public boolean isVendor() {
213 return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
214 }
215
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900216 public boolean isProduct() {
217 return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
218 }
219
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900220 public boolean isSystemExt() {
221 return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
Dario Freni2bef1762018-06-01 14:02:08 +0100222 }
223
MÃ¥rten Kongstad48c24cf2019-02-25 10:54:09 +0100224 public boolean isOdm() {
225 return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0;
226 }
227
Svet Ganov12a692a2015-03-28 19:34:15 -0700228 public boolean isSystem() {
229 return (pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
230 }
Svetoslavd2cf3ae2015-04-02 16:51:55 -0700231
Todd Kennedy91a39d12017-09-27 12:37:04 -0700232 @Override
Svetoslavd2cf3ae2015-04-02 16:51:55 -0700233 public boolean isSharedUser() {
234 return sharedUser != null;
235 }
Jeff Sharkeyc5967e92016-01-07 18:50:29 -0700236
237 public boolean isMatch(int flags) {
238 if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
239 return isSystem();
240 }
241 return true;
242 }
Netta P426cbef2017-02-10 14:38:39 -0800243
Taras Antoshchuka7d9c732019-10-29 13:46:19 +0100244 public boolean setMimeGroup(String mimeGroup, List<String> mimeTypes) {
245 ArraySet<String> oldMimeTypes = getMimeGroupInternal(mimeGroup);
246 if (oldMimeTypes == null) {
Taras Antoshchuk8a600242020-03-17 22:56:54 +0100247 throw new IllegalArgumentException("Unknown MIME group " + mimeGroup
248 + " for package " + name);
Taras Antoshchuka7d9c732019-10-29 13:46:19 +0100249 }
250
251 ArraySet<String> newMimeTypes = new ArraySet<>(mimeTypes);
252 boolean hasChanges = !newMimeTypes.equals(oldMimeTypes);
253 mimeGroups.put(mimeGroup, newMimeTypes);
254 return hasChanges;
255 }
256
Taras Antoshchuka7d9c732019-10-29 13:46:19 +0100257 public List<String> getMimeGroup(String mimeGroup) {
258 ArraySet<String> mimeTypes = getMimeGroupInternal(mimeGroup);
259 if (mimeTypes == null) {
Taras Antoshchuk8a600242020-03-17 22:56:54 +0100260 throw new IllegalArgumentException("Unknown MIME group " + mimeGroup
261 + " for package " + name);
Taras Antoshchuka7d9c732019-10-29 13:46:19 +0100262 }
263 return new ArrayList<>(mimeTypes);
264 }
265
266 private ArraySet<String> getMimeGroupInternal(String mimeGroup) {
267 return mimeGroups != null ? mimeGroups.get(mimeGroup) : null;
268 }
269
Jeffrey Huangcb782852019-12-05 11:28:11 -0800270 public void dumpDebug(ProtoOutputStream proto, long fieldId, List<UserInfo> users) {
Netta P426cbef2017-02-10 14:38:39 -0800271 final long packageToken = proto.start(fieldId);
272 proto.write(PackageProto.NAME, (realName != null ? realName : name));
273 proto.write(PackageProto.UID, appId);
274 proto.write(PackageProto.VERSION_CODE, versionCode);
Netta P426cbef2017-02-10 14:38:39 -0800275 proto.write(PackageProto.INSTALL_TIME_MS, firstInstallTime);
276 proto.write(PackageProto.UPDATE_TIME_MS, lastUpdateTime);
Alan Stokes819fea22019-10-16 16:54:09 +0100277 proto.write(PackageProto.INSTALLER_NAME, installSource.installerPackageName);
Netta P426cbef2017-02-10 14:38:39 -0800278
279 if (pkg != null) {
Winson14ff7172019-10-23 10:42:27 -0700280 proto.write(PackageProto.VERSION_STRING, pkg.getVersionName());
Joe Onorato01fdbc12019-04-29 16:07:01 -0700281
Netta P426cbef2017-02-10 14:38:39 -0800282 long splitToken = proto.start(PackageProto.SPLITS);
283 proto.write(PackageProto.SplitProto.NAME, "base");
Winson14ff7172019-10-23 10:42:27 -0700284 proto.write(PackageProto.SplitProto.REVISION_CODE, pkg.getBaseRevisionCode());
Netta P426cbef2017-02-10 14:38:39 -0800285 proto.end(splitToken);
Joe Onorato01fdbc12019-04-29 16:07:01 -0700286
Winson14ff7172019-10-23 10:42:27 -0700287 if (pkg.getSplitNames() != null) {
288 for (int i = 0; i < pkg.getSplitNames().length; i++) {
Netta P426cbef2017-02-10 14:38:39 -0800289 splitToken = proto.start(PackageProto.SPLITS);
Winson14ff7172019-10-23 10:42:27 -0700290 proto.write(PackageProto.SplitProto.NAME, pkg.getSplitNames()[i]);
291 proto.write(PackageProto.SplitProto.REVISION_CODE,
292 pkg.getSplitRevisionCodes()[i]);
Netta P426cbef2017-02-10 14:38:39 -0800293 proto.end(splitToken);
294 }
295 }
Alan Stokes69d2abf2019-10-10 11:02:38 +0100296
297 long sourceToken = proto.start(PackageProto.INSTALL_SOURCE);
298 proto.write(PackageProto.InstallSourceProto.INITIATING_PACKAGE_NAME,
299 installSource.initiatingPackageName);
Alan Stokes5ed85372019-11-06 09:32:49 +0000300 proto.write(PackageProto.InstallSourceProto.ORIGINATING_PACKAGE_NAME,
301 installSource.originatingPackageName);
Alan Stokes69d2abf2019-10-10 11:02:38 +0100302 proto.end(sourceToken);
Netta P426cbef2017-02-10 14:38:39 -0800303 }
304 writeUsersInfoToProto(proto, PackageProto.USERS);
305 proto.end(packageToken);
306 }
Patrick4ccae942018-07-17 09:15:55 -0700307
308 /** Updates all fields in the current setting from another. */
309 public void updateFrom(PackageSetting other) {
310 super.updateFrom(other);
311 appId = other.appId;
312 pkg = other.pkg;
313 sharedUserId = other.sharedUserId;
314 sharedUser = other.sharedUser;
Taras Antoshchuka7d9c732019-10-29 13:46:19 +0100315
316 Set<String> mimeGroupNames = other.mimeGroups != null ? other.mimeGroups.keySet() : null;
317 updateMimeGroups(mimeGroupNames);
Winson10bb8702020-03-05 18:58:09 -0800318
319 getPkgState().updateFrom(other.getPkgState());
Patrick4ccae942018-07-17 09:15:55 -0700320 }
Winsone0756292020-01-31 12:21:54 -0800321
322 @NonNull
323 public PackageStateUnserialized getPkgState() {
324 return pkgState;
325 }
Jeff Sharkey02e4d16e2013-08-12 20:31:36 -0700326}