blob: 694669c0912514ec10083cab92e564ec47e3ed18 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 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
Kenny Rootcf0b38c2011-03-22 14:17:59 -070017package com.android.server.pm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Jeff Brownb880d882014-02-10 19:47:07 -080019import android.content.Context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.content.pm.PackageStats;
Narayan Kamath29564cd2014-08-07 10:57:40 +010021import android.os.Build;
Joe Onorato8a9b2202010-02-26 18:56:32 -080022import android.util.Slog;
Narayan Kamath6c4b9de2014-08-08 12:44:12 +010023import dalvik.system.VMRuntime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
Narayan Kamath29564cd2014-08-07 10:57:40 +010025import com.android.internal.os.InstallerConnection;
26import com.android.server.SystemService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027
Jeff Brown6f357d32014-01-15 20:40:55 -080028public final class Installer extends SystemService {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029 private static final String TAG = "Installer";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
Narayan Kamath29564cd2014-08-07 10:57:40 +010031 private final InstallerConnection mInstaller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032
Jeff Brownb880d882014-02-10 19:47:07 -080033 public Installer(Context context) {
34 super(context);
Narayan Kamath29564cd2014-08-07 10:57:40 +010035 mInstaller = new InstallerConnection();
Jeff Brownb880d882014-02-10 19:47:07 -080036 }
37
Jeff Brown6f357d32014-01-15 20:40:55 -080038 @Override
39 public void onStart() {
40 Slog.i(TAG, "Waiting for installd to be ready.");
41 ping();
42 }
43
Robert Craig0f40dc92013-03-25 06:33:03 -040044 public int install(String name, int uid, int gid, String seinfo) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 StringBuilder builder = new StringBuilder("install");
46 builder.append(' ');
47 builder.append(name);
48 builder.append(' ');
49 builder.append(uid);
50 builder.append(' ');
51 builder.append(gid);
Robert Craig0f40dc92013-03-25 06:33:03 -040052 builder.append(' ');
53 builder.append(seinfo != null ? seinfo : "!");
Narayan Kamath29564cd2014-08-07 10:57:40 +010054 return mInstaller.execute(builder.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 }
56
Alex Lighta25dc2b2014-08-05 14:25:43 -070057 public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName,
58 String instructionSet) {
Narayan Kamath6c4b9de2014-08-08 12:44:12 +010059 if (!isValidInstructionSet(instructionSet)) {
60 Slog.e(TAG, "Invalid instruction set: " + instructionSet);
61 return -1;
62 }
63
Calin Juravlefeb19302014-08-21 19:00:15 +010064 return mInstaller.patchoat(apkPath, uid, isPublic, pkgName, instructionSet);
Alex Lighta25dc2b2014-08-05 14:25:43 -070065 }
66
67 public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
Narayan Kamath6c4b9de2014-08-08 12:44:12 +010068 if (!isValidInstructionSet(instructionSet)) {
69 Slog.e(TAG, "Invalid instruction set: " + instructionSet);
70 return -1;
71 }
72
Narayan Kamath29564cd2014-08-07 10:57:40 +010073 return mInstaller.patchoat(apkPath, uid, isPublic, instructionSet);
Alex Lighta25dc2b2014-08-05 14:25:43 -070074 }
75
Narayan Kamath0349e8c2014-05-01 11:41:20 +010076 public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
Narayan Kamath6c4b9de2014-08-08 12:44:12 +010077 if (!isValidInstructionSet(instructionSet)) {
78 Slog.e(TAG, "Invalid instruction set: " + instructionSet);
79 return -1;
80 }
81
Narayan Kamath29564cd2014-08-07 10:57:40 +010082 return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet);
Dave Allison0efbd9a2014-01-30 14:19:51 -080083 }
84
Narayan Kamath0349e8c2014-05-01 11:41:20 +010085 public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
Calin Juravlefeb19302014-08-21 19:00:15 +010086 String instructionSet, boolean vmSafeMode) {
Narayan Kamath6c4b9de2014-08-08 12:44:12 +010087 if (!isValidInstructionSet(instructionSet)) {
88 Slog.e(TAG, "Invalid instruction set: " + instructionSet);
89 return -1;
90 }
91
Calin Juravlefeb19302014-08-21 19:00:15 +010092 return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, instructionSet, vmSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 }
94
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +010095 public int idmap(String targetApkPath, String overlayApkPath, int uid) {
96 StringBuilder builder = new StringBuilder("idmap");
97 builder.append(' ');
98 builder.append(targetApkPath);
99 builder.append(' ');
100 builder.append(overlayApkPath);
101 builder.append(' ');
102 builder.append(uid);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100103 return mInstaller.execute(builder.toString());
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +0100104 }
105
Narayan Kamath0349e8c2014-05-01 11:41:20 +0100106 public int movedex(String srcPath, String dstPath, String instructionSet) {
Narayan Kamath6c4b9de2014-08-08 12:44:12 +0100107 if (!isValidInstructionSet(instructionSet)) {
108 Slog.e(TAG, "Invalid instruction set: " + instructionSet);
109 return -1;
110 }
111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 StringBuilder builder = new StringBuilder("movedex");
113 builder.append(' ');
114 builder.append(srcPath);
115 builder.append(' ');
116 builder.append(dstPath);
Narayan Kamath0349e8c2014-05-01 11:41:20 +0100117 builder.append(' ');
118 builder.append(instructionSet);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100119 return mInstaller.execute(builder.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 }
121
Narayan Kamath0349e8c2014-05-01 11:41:20 +0100122 public int rmdex(String codePath, String instructionSet) {
Narayan Kamath6c4b9de2014-08-08 12:44:12 +0100123 if (!isValidInstructionSet(instructionSet)) {
124 Slog.e(TAG, "Invalid instruction set: " + instructionSet);
125 return -1;
126 }
127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 StringBuilder builder = new StringBuilder("rmdex");
129 builder.append(' ');
130 builder.append(codePath);
Narayan Kamath0349e8c2014-05-01 11:41:20 +0100131 builder.append(' ');
132 builder.append(instructionSet);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100133 return mInstaller.execute(builder.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 }
135
Amith Yamasani0b285492011-04-14 17:35:23 -0700136 public int remove(String name, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 StringBuilder builder = new StringBuilder("remove");
138 builder.append(' ');
139 builder.append(name);
Amith Yamasani0b285492011-04-14 17:35:23 -0700140 builder.append(' ');
141 builder.append(userId);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100142 return mInstaller.execute(builder.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 }
144
Kenny Root35ab3ad2011-02-02 16:42:14 -0800145 public int rename(String oldname, String newname) {
Dianne Hackbornb858dfd2010-02-02 10:49:14 -0800146 StringBuilder builder = new StringBuilder("rename");
147 builder.append(' ');
148 builder.append(oldname);
149 builder.append(' ');
150 builder.append(newname);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100151 return mInstaller.execute(builder.toString());
Dianne Hackbornb858dfd2010-02-02 10:49:14 -0800152 }
153
Dave Burke383fa182012-10-23 23:12:19 -0700154 public int fixUid(String name, int uid, int gid) {
Dianne Hackbornd0c5f512012-06-07 16:53:59 -0700155 StringBuilder builder = new StringBuilder("fixuid");
156 builder.append(' ');
157 builder.append(name);
158 builder.append(' ');
159 builder.append(uid);
160 builder.append(' ');
Dave Burke383fa182012-10-23 23:12:19 -0700161 builder.append(gid);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100162 return mInstaller.execute(builder.toString());
Dianne Hackbornd0c5f512012-06-07 16:53:59 -0700163 }
164
Amith Yamasani54289b82012-10-01 10:39:14 -0700165 public int deleteCacheFiles(String name, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 StringBuilder builder = new StringBuilder("rmcache");
167 builder.append(' ');
168 builder.append(name);
Amith Yamasani54289b82012-10-01 10:39:14 -0700169 builder.append(' ');
170 builder.append(userId);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100171 return mInstaller.execute(builder.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 }
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700173
Jeff Sharkey4ed745d2014-07-15 20:39:15 -0700174 public int deleteCodeCacheFiles(String name, int userId) {
175 StringBuilder builder = new StringBuilder("rmcodecache");
176 builder.append(' ');
177 builder.append(name);
178 builder.append(' ');
179 builder.append(userId);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100180 return mInstaller.execute(builder.toString());
Jeff Sharkey4ed745d2014-07-15 20:39:15 -0700181 }
182
Robert Craig8643dc62013-07-29 09:06:51 -0400183 public int createUserData(String name, int uid, int userId, String seinfo) {
Amith Yamasani0b285492011-04-14 17:35:23 -0700184 StringBuilder builder = new StringBuilder("mkuserdata");
185 builder.append(' ');
186 builder.append(name);
187 builder.append(' ');
188 builder.append(uid);
189 builder.append(' ');
190 builder.append(userId);
Robert Craig8643dc62013-07-29 09:06:51 -0400191 builder.append(' ');
192 builder.append(seinfo != null ? seinfo : "!");
Narayan Kamath29564cd2014-08-07 10:57:40 +0100193 return mInstaller.execute(builder.toString());
Amith Yamasani0b285492011-04-14 17:35:23 -0700194 }
195
Robin Lee06505d22014-07-09 17:43:56 +0000196 public int createUserConfig(int userId) {
197 StringBuilder builder = new StringBuilder("mkuserconfig");
198 builder.append(' ');
199 builder.append(userId);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100200 return mInstaller.execute(builder.toString());
Robin Lee06505d22014-07-09 17:43:56 +0000201 }
202
Amith Yamasani0b285492011-04-14 17:35:23 -0700203 public int removeUserDataDirs(int userId) {
204 StringBuilder builder = new StringBuilder("rmuser");
205 builder.append(' ');
206 builder.append(userId);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100207 return mInstaller.execute(builder.toString());
Amith Yamasani0b285492011-04-14 17:35:23 -0700208 }
209
210 public int clearUserData(String name, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 StringBuilder builder = new StringBuilder("rmuserdata");
212 builder.append(' ');
213 builder.append(name);
Amith Yamasani0b285492011-04-14 17:35:23 -0700214 builder.append(' ');
215 builder.append(userId);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100216 return mInstaller.execute(builder.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 }
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 public boolean ping() {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100220 if (mInstaller.execute("ping") < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 return false;
222 } else {
223 return true;
224 }
225 }
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700226
Narayan Kamath152d5cd2014-06-24 12:19:10 +0000227 public int pruneDexCache(String cacheSubDir) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100228 return mInstaller.execute("prunedexcache " + cacheSubDir);
Narayan Kamath5406f592014-06-16 13:54:10 +0000229 }
230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 public int freeCache(long freeStorageSize) {
232 StringBuilder builder = new StringBuilder("freecache");
233 builder.append(' ');
234 builder.append(String.valueOf(freeStorageSize));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100235 return mInstaller.execute(builder.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 }
237
Dianne Hackbornecc8d6f2013-05-01 18:54:11 -0700238 public int getSizeInfo(String pkgName, int persona, String apkPath, String libDirPath,
Narayan Kamathff110bd2014-07-04 18:30:45 +0100239 String fwdLockApkPath, String asecPath, String[] instructionSets, PackageStats pStats) {
Narayan Kamath6c4b9de2014-08-08 12:44:12 +0100240 for (String instructionSet : instructionSets) {
241 if (!isValidInstructionSet(instructionSet)) {
242 Slog.e(TAG, "Invalid instruction set: " + instructionSet);
243 return -1;
244 }
245 }
246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 StringBuilder builder = new StringBuilder("getsize");
248 builder.append(' ');
249 builder.append(pkgName);
250 builder.append(' ');
Dianne Hackborn0c380492012-08-20 17:23:30 -0700251 builder.append(persona);
252 builder.append(' ');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 builder.append(apkPath);
254 builder.append(' ');
Narayan Kamathff110bd2014-07-04 18:30:45 +0100255 // TODO: Extend getSizeInfo to look at the full subdirectory tree,
256 // not just the first level.
Dianne Hackbornecc8d6f2013-05-01 18:54:11 -0700257 builder.append(libDirPath != null ? libDirPath : "!");
258 builder.append(' ');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 builder.append(fwdLockApkPath != null ? fwdLockApkPath : "!");
Dianne Hackborn292f8bc2011-06-27 16:27:41 -0700260 builder.append(' ');
261 builder.append(asecPath != null ? asecPath : "!");
Narayan Kamath0349e8c2014-05-01 11:41:20 +0100262 builder.append(' ');
Narayan Kamathff110bd2014-07-04 18:30:45 +0100263 // TODO: Extend getSizeInfo to look at *all* instrution sets, not
264 // just the primary.
265 builder.append(instructionSets[0]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266
Narayan Kamath29564cd2014-08-07 10:57:40 +0100267 String s = mInstaller.transact(builder.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 String res[] = s.split(" ");
269
Dianne Hackborn292f8bc2011-06-27 16:27:41 -0700270 if ((res == null) || (res.length != 5)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 return -1;
272 }
273 try {
274 pStats.codeSize = Long.parseLong(res[1]);
275 pStats.dataSize = Long.parseLong(res[2]);
276 pStats.cacheSize = Long.parseLong(res[3]);
Dianne Hackborn292f8bc2011-06-27 16:27:41 -0700277 pStats.externalCodeSize = Long.parseLong(res[4]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 return Integer.parseInt(res[0]);
279 } catch (NumberFormatException e) {
280 return -1;
281 }
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700282 }
Dianne Hackbornb858dfd2010-02-02 10:49:14 -0800283
284 public int moveFiles() {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100285 return mInstaller.execute("movefiles");
Dianne Hackbornb858dfd2010-02-02 10:49:14 -0800286 }
Kenny Root6a6b0072010-10-07 16:46:10 -0700287
Kenny Rootddbe50d2012-09-06 13:18:37 -0700288 /**
Narayan Kamathff110bd2014-07-04 18:30:45 +0100289 * Links the 32 bit native library directory in an application's data directory to the
290 * real location for backward compatibility. Note that no such symlink is created for
291 * 64 bit shared libraries.
Kenny Rootddbe50d2012-09-06 13:18:37 -0700292 *
Kenny Rootddbe50d2012-09-06 13:18:37 -0700293 * @return -1 on error
294 */
Narayan Kamathff110bd2014-07-04 18:30:45 +0100295 public int linkNativeLibraryDirectory(String dataPath, String nativeLibPath32, int userId) {
Kenny Root6a6b0072010-10-07 16:46:10 -0700296 if (dataPath == null) {
Kenny Root9bbd70a2012-09-10 11:13:36 -0700297 Slog.e(TAG, "linkNativeLibraryDirectory dataPath is null");
Kenny Root6a6b0072010-10-07 16:46:10 -0700298 return -1;
Narayan Kamathff110bd2014-07-04 18:30:45 +0100299 } else if (nativeLibPath32 == null) {
Kenny Root9bbd70a2012-09-10 11:13:36 -0700300 Slog.e(TAG, "linkNativeLibraryDirectory nativeLibPath is null");
Kenny Root6a6b0072010-10-07 16:46:10 -0700301 return -1;
302 }
303
304 StringBuilder builder = new StringBuilder("linklib ");
305 builder.append(dataPath);
306 builder.append(' ');
Narayan Kamathff110bd2014-07-04 18:30:45 +0100307 builder.append(nativeLibPath32);
Kenny Roota3e90792012-10-18 10:58:36 -0700308 builder.append(' ');
309 builder.append(userId);
Kenny Root6a6b0072010-10-07 16:46:10 -0700310
Narayan Kamath29564cd2014-08-07 10:57:40 +0100311 return mInstaller.execute(builder.toString());
Kenny Root6a6b0072010-10-07 16:46:10 -0700312 }
Robert Craig43853432014-03-04 11:57:23 -0500313
Nick Kralevichce30fca852014-03-31 20:20:41 +0000314 public boolean restoreconData(String pkgName, String seinfo, int uid) {
315 StringBuilder builder = new StringBuilder("restorecondata");
316 builder.append(' ');
317 builder.append(pkgName);
318 builder.append(' ');
319 builder.append(seinfo != null ? seinfo : "!");
320 builder.append(' ');
321 builder.append(uid);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100322 return (mInstaller.execute(builder.toString()) == 0);
Robert Craig43853432014-03-04 11:57:23 -0500323 }
Narayan Kamath6c4b9de2014-08-08 12:44:12 +0100324
325 /**
326 * Returns true iff. {@code instructionSet} is a valid instruction set.
327 */
328 private static boolean isValidInstructionSet(String instructionSet) {
329 if (instructionSet == null) {
330 return false;
331 }
332
333 for (String abi : Build.SUPPORTED_ABIS) {
334 if (instructionSet.equals(VMRuntime.getInstructionSet(abi))) {
335 return true;
336 }
337 }
338
339 return false;
340 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341}