1 /* 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 17 package com.android.server.pm; 18 19 import android.annotation.Nullable; 20 import android.content.Context; 21 import android.content.pm.PackageStats; 22 import android.os.Build; 23 import android.util.Slog; 24 25 import com.android.internal.os.InstallerConnection; 26 import com.android.internal.os.InstallerConnection.InstallerException; 27 import com.android.server.SystemService; 28 29 import dalvik.system.VMRuntime; 30 31 import java.util.Arrays; 32 33 public final class Installer extends SystemService { 34 private static final String TAG = "Installer"; 35 36 /* *************************************************************************** 37 * IMPORTANT: These values are passed to native code. Keep them in sync with 38 * frameworks/native/cmds/installd/installd.h 39 * **************************************************************************/ 40 /** Application should be visible to everyone */ 41 public static final int DEXOPT_PUBLIC = 1 << 1; 42 /** Application wants to run in VM safe mode */ 43 public static final int DEXOPT_SAFEMODE = 1 << 2; 44 /** Application wants to allow debugging of its code */ 45 public static final int DEXOPT_DEBUGGABLE = 1 << 3; 46 /** The system boot has finished */ 47 public static final int DEXOPT_BOOTCOMPLETE = 1 << 4; 48 /** Hint that the dexopt type is profile-guided. */ 49 public static final int DEXOPT_PROFILE_GUIDED = 1 << 5; 50 /** This is an OTA update dexopt */ 51 public static final int DEXOPT_OTA = 1 << 6; 52 53 // NOTE: keep in sync with installd 54 public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8; 55 public static final int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 9; 56 57 private final InstallerConnection mInstaller; 58 Installer(Context context)59 public Installer(Context context) { 60 super(context); 61 mInstaller = new InstallerConnection(); 62 } 63 64 /** 65 * Yell loudly if someone tries making future calls while holding a lock on 66 * the given object. 67 */ setWarnIfHeld(Object warnIfHeld)68 public void setWarnIfHeld(Object warnIfHeld) { 69 mInstaller.setWarnIfHeld(warnIfHeld); 70 } 71 72 @Override onStart()73 public void onStart() { 74 Slog.i(TAG, "Waiting for installd to be ready."); 75 mInstaller.waitForConnection(); 76 } 77 createAppData(String uuid, String pkgname, int userid, int flags, int appid, String seinfo, int targetSdkVersion)78 public void createAppData(String uuid, String pkgname, int userid, int flags, int appid, 79 String seinfo, int targetSdkVersion) throws InstallerException { 80 mInstaller.execute("create_app_data", uuid, pkgname, userid, flags, appid, seinfo, 81 targetSdkVersion); 82 } 83 restoreconAppData(String uuid, String pkgname, int userid, int flags, int appid, String seinfo)84 public void restoreconAppData(String uuid, String pkgname, int userid, int flags, int appid, 85 String seinfo) throws InstallerException { 86 mInstaller.execute("restorecon_app_data", uuid, pkgname, userid, flags, appid, 87 seinfo); 88 } 89 migrateAppData(String uuid, String pkgname, int userid, int flags)90 public void migrateAppData(String uuid, String pkgname, int userid, int flags) 91 throws InstallerException { 92 mInstaller.execute("migrate_app_data", uuid, pkgname, userid, flags); 93 } 94 clearAppData(String uuid, String pkgname, int userid, int flags, long ceDataInode)95 public void clearAppData(String uuid, String pkgname, int userid, int flags, long ceDataInode) 96 throws InstallerException { 97 mInstaller.execute("clear_app_data", uuid, pkgname, userid, flags, ceDataInode); 98 } 99 destroyAppData(String uuid, String pkgname, int userid, int flags, long ceDataInode)100 public void destroyAppData(String uuid, String pkgname, int userid, int flags, long ceDataInode) 101 throws InstallerException { 102 mInstaller.execute("destroy_app_data", uuid, pkgname, userid, flags, ceDataInode); 103 } 104 moveCompleteApp(String from_uuid, String to_uuid, String package_name, String data_app_name, int appid, String seinfo, int targetSdkVersion)105 public void moveCompleteApp(String from_uuid, String to_uuid, String package_name, 106 String data_app_name, int appid, String seinfo, int targetSdkVersion) 107 throws InstallerException { 108 mInstaller.execute("move_complete_app", from_uuid, to_uuid, package_name, 109 data_app_name, appid, seinfo, targetSdkVersion); 110 } 111 getAppSize(String uuid, String pkgname, int userid, int flags, long ceDataInode, String codePath, PackageStats stats)112 public void getAppSize(String uuid, String pkgname, int userid, int flags, long ceDataInode, 113 String codePath, PackageStats stats) throws InstallerException { 114 final String[] res = mInstaller.execute("get_app_size", uuid, pkgname, userid, flags, 115 ceDataInode, codePath); 116 try { 117 stats.codeSize += Long.parseLong(res[1]); 118 stats.dataSize += Long.parseLong(res[2]); 119 stats.cacheSize += Long.parseLong(res[3]); 120 } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { 121 throw new InstallerException("Invalid size result: " + Arrays.toString(res)); 122 } 123 } 124 getAppDataInode(String uuid, String pkgname, int userid, int flags)125 public long getAppDataInode(String uuid, String pkgname, int userid, int flags) 126 throws InstallerException { 127 final String[] res = mInstaller.execute("get_app_data_inode", uuid, pkgname, userid, flags); 128 try { 129 return Long.parseLong(res[1]); 130 } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { 131 throw new InstallerException("Invalid inode result: " + Arrays.toString(res)); 132 } 133 } 134 dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries)135 public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, 136 int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries) 137 throws InstallerException { 138 assertValidInstructionSet(instructionSet); 139 mInstaller.dexopt(apkPath, uid, instructionSet, dexoptNeeded, dexFlags, 140 compilerFilter, volumeUuid, sharedLibraries); 141 } 142 dexopt(String apkPath, int uid, String pkgName, String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries)143 public void dexopt(String apkPath, int uid, String pkgName, String instructionSet, 144 int dexoptNeeded, @Nullable String outputPath, int dexFlags, 145 String compilerFilter, String volumeUuid, String sharedLibraries) 146 throws InstallerException { 147 assertValidInstructionSet(instructionSet); 148 mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, 149 outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries); 150 } 151 mergeProfiles(int uid, String pkgName)152 public boolean mergeProfiles(int uid, String pkgName) throws InstallerException { 153 return mInstaller.mergeProfiles(uid, pkgName); 154 } 155 dumpProfiles(String gid, String packageName, String codePaths)156 public boolean dumpProfiles(String gid, String packageName, String codePaths) 157 throws InstallerException { 158 return mInstaller.dumpProfiles(gid, packageName, codePaths); 159 } 160 idmap(String targetApkPath, String overlayApkPath, int uid)161 public void idmap(String targetApkPath, String overlayApkPath, int uid) 162 throws InstallerException { 163 mInstaller.execute("idmap", targetApkPath, overlayApkPath, uid); 164 } 165 rmdex(String codePath, String instructionSet)166 public void rmdex(String codePath, String instructionSet) throws InstallerException { 167 assertValidInstructionSet(instructionSet); 168 mInstaller.execute("rmdex", codePath, instructionSet); 169 } 170 rmPackageDir(String packageDir)171 public void rmPackageDir(String packageDir) throws InstallerException { 172 mInstaller.execute("rmpackagedir", packageDir); 173 } 174 clearAppProfiles(String pkgName)175 public void clearAppProfiles(String pkgName) throws InstallerException { 176 mInstaller.execute("clear_app_profiles", pkgName); 177 } 178 destroyAppProfiles(String pkgName)179 public void destroyAppProfiles(String pkgName) throws InstallerException { 180 mInstaller.execute("destroy_app_profiles", pkgName); 181 } 182 createUserData(String uuid, int userId, int userSerial, int flags)183 public void createUserData(String uuid, int userId, int userSerial, int flags) 184 throws InstallerException { 185 mInstaller.execute("create_user_data", uuid, userId, userSerial, flags); 186 } 187 destroyUserData(String uuid, int userId, int flags)188 public void destroyUserData(String uuid, int userId, int flags) throws InstallerException { 189 mInstaller.execute("destroy_user_data", uuid, userId, flags); 190 } 191 markBootComplete(String instructionSet)192 public void markBootComplete(String instructionSet) throws InstallerException { 193 assertValidInstructionSet(instructionSet); 194 mInstaller.execute("markbootcomplete", instructionSet); 195 } 196 freeCache(String uuid, long freeStorageSize)197 public void freeCache(String uuid, long freeStorageSize) throws InstallerException { 198 mInstaller.execute("freecache", uuid, freeStorageSize); 199 } 200 201 /** 202 * Links the 32 bit native library directory in an application's data 203 * directory to the real location for backward compatibility. Note that no 204 * such symlink is created for 64 bit shared libraries. 205 */ linkNativeLibraryDirectory(String uuid, String dataPath, String nativeLibPath32, int userId)206 public void linkNativeLibraryDirectory(String uuid, String dataPath, String nativeLibPath32, 207 int userId) throws InstallerException { 208 mInstaller.execute("linklib", uuid, dataPath, nativeLibPath32, userId); 209 } 210 createOatDir(String oatDir, String dexInstructionSet)211 public void createOatDir(String oatDir, String dexInstructionSet) 212 throws InstallerException { 213 mInstaller.execute("createoatdir", oatDir, dexInstructionSet); 214 } 215 linkFile(String relativePath, String fromBase, String toBase)216 public void linkFile(String relativePath, String fromBase, String toBase) 217 throws InstallerException { 218 mInstaller.execute("linkfile", relativePath, fromBase, toBase); 219 } 220 moveAb(String apkPath, String instructionSet, String outputPath)221 public void moveAb(String apkPath, String instructionSet, String outputPath) 222 throws InstallerException { 223 mInstaller.execute("move_ab", apkPath, instructionSet, outputPath); 224 } 225 assertValidInstructionSet(String instructionSet)226 private static void assertValidInstructionSet(String instructionSet) 227 throws InstallerException { 228 for (String abi : Build.SUPPORTED_ABIS) { 229 if (VMRuntime.getInstructionSet(abi).equals(instructionSet)) { 230 return; 231 } 232 } 233 throw new InstallerException("Invalid instruction set: " + instructionSet); 234 } 235 } 236