Home | History | Annotate | Download | only in pm
      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 
     59     public Installer(Context context) {
     60         super(context);
     61         mInstaller = new InstallerConnection();
     62     }
     63 
     64     // Package-private installer that accepts a custom InstallerConnection. Used for
     65     // OtaDexoptService.
     66     Installer(Context context, InstallerConnection connection) {
     67         super(context);
     68         mInstaller = connection;
     69     }
     70 
     71     /**
     72      * Yell loudly if someone tries making future calls while holding a lock on
     73      * the given object.
     74      */
     75     public void setWarnIfHeld(Object warnIfHeld) {
     76         mInstaller.setWarnIfHeld(warnIfHeld);
     77     }
     78 
     79     @Override
     80     public void onStart() {
     81         Slog.i(TAG, "Waiting for installd to be ready.");
     82         mInstaller.waitForConnection();
     83     }
     84 
     85     public void createAppData(String uuid, String pkgname, int userid, int flags, int appid,
     86             String seinfo, int targetSdkVersion) throws InstallerException {
     87         mInstaller.execute("create_app_data", uuid, pkgname, userid, flags, appid, seinfo,
     88             targetSdkVersion);
     89     }
     90 
     91     public void restoreconAppData(String uuid, String pkgname, int userid, int flags, int appid,
     92             String seinfo) throws InstallerException {
     93         mInstaller.execute("restorecon_app_data", uuid, pkgname, userid, flags, appid,
     94                 seinfo);
     95     }
     96 
     97     public void migrateAppData(String uuid, String pkgname, int userid, int flags)
     98             throws InstallerException {
     99         mInstaller.execute("migrate_app_data", uuid, pkgname, userid, flags);
    100     }
    101 
    102     public void clearAppData(String uuid, String pkgname, int userid, int flags, long ceDataInode)
    103             throws InstallerException {
    104         mInstaller.execute("clear_app_data", uuid, pkgname, userid, flags, ceDataInode);
    105     }
    106 
    107     public void destroyAppData(String uuid, String pkgname, int userid, int flags, long ceDataInode)
    108             throws InstallerException {
    109         mInstaller.execute("destroy_app_data", uuid, pkgname, userid, flags, ceDataInode);
    110     }
    111 
    112     public void moveCompleteApp(String from_uuid, String to_uuid, String package_name,
    113             String data_app_name, int appid, String seinfo, int targetSdkVersion)
    114             throws InstallerException {
    115         mInstaller.execute("move_complete_app", from_uuid, to_uuid, package_name,
    116                 data_app_name, appid, seinfo, targetSdkVersion);
    117     }
    118 
    119     public void getAppSize(String uuid, String pkgname, int userid, int flags, long ceDataInode,
    120             String codePath, PackageStats stats) throws InstallerException {
    121         final String[] res = mInstaller.execute("get_app_size", uuid, pkgname, userid, flags,
    122                 ceDataInode, codePath);
    123         try {
    124             stats.codeSize += Long.parseLong(res[1]);
    125             stats.dataSize += Long.parseLong(res[2]);
    126             stats.cacheSize += Long.parseLong(res[3]);
    127         } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
    128             throw new InstallerException("Invalid size result: " + Arrays.toString(res));
    129         }
    130     }
    131 
    132     public long getAppDataInode(String uuid, String pkgname, int userid, int flags)
    133             throws InstallerException {
    134         final String[] res = mInstaller.execute("get_app_data_inode", uuid, pkgname, userid, flags);
    135         try {
    136             return Long.parseLong(res[1]);
    137         } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
    138             throw new InstallerException("Invalid inode result: " + Arrays.toString(res));
    139         }
    140     }
    141 
    142     public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
    143             int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries)
    144             throws InstallerException {
    145         assertValidInstructionSet(instructionSet);
    146         mInstaller.dexopt(apkPath, uid, instructionSet, dexoptNeeded, dexFlags,
    147                 compilerFilter, volumeUuid, sharedLibraries);
    148     }
    149 
    150     public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
    151             int dexoptNeeded, @Nullable String outputPath, int dexFlags,
    152             String compilerFilter, String volumeUuid, String sharedLibraries)
    153             throws InstallerException {
    154         assertValidInstructionSet(instructionSet);
    155         mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded,
    156                 outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries);
    157     }
    158 
    159     public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
    160         return mInstaller.mergeProfiles(uid, pkgName);
    161     }
    162 
    163     public boolean dumpProfiles(String gid, String packageName, String codePaths)
    164             throws InstallerException {
    165         return mInstaller.dumpProfiles(gid, packageName, codePaths);
    166     }
    167 
    168     public void idmap(String targetApkPath, String overlayApkPath, int uid)
    169             throws InstallerException {
    170         mInstaller.execute("idmap", targetApkPath, overlayApkPath, uid);
    171     }
    172 
    173     public void rmdex(String codePath, String instructionSet) throws InstallerException {
    174         assertValidInstructionSet(instructionSet);
    175         mInstaller.execute("rmdex", codePath, instructionSet);
    176     }
    177 
    178     public void rmPackageDir(String packageDir) throws InstallerException {
    179         mInstaller.execute("rmpackagedir", packageDir);
    180     }
    181 
    182     public void clearAppProfiles(String pkgName) throws InstallerException {
    183         mInstaller.execute("clear_app_profiles", pkgName);
    184     }
    185 
    186     public void destroyAppProfiles(String pkgName) throws InstallerException {
    187         mInstaller.execute("destroy_app_profiles", pkgName);
    188     }
    189 
    190     public void createUserData(String uuid, int userId, int userSerial, int flags)
    191             throws InstallerException {
    192         mInstaller.execute("create_user_data", uuid, userId, userSerial, flags);
    193     }
    194 
    195     public void destroyUserData(String uuid, int userId, int flags) throws InstallerException {
    196         mInstaller.execute("destroy_user_data", uuid, userId, flags);
    197     }
    198 
    199     public void markBootComplete(String instructionSet) throws InstallerException {
    200         assertValidInstructionSet(instructionSet);
    201         mInstaller.execute("markbootcomplete", instructionSet);
    202     }
    203 
    204     public void freeCache(String uuid, long freeStorageSize) throws InstallerException {
    205         mInstaller.execute("freecache", uuid, freeStorageSize);
    206     }
    207 
    208     /**
    209      * Links the 32 bit native library directory in an application's data
    210      * directory to the real location for backward compatibility. Note that no
    211      * such symlink is created for 64 bit shared libraries.
    212      */
    213     public void linkNativeLibraryDirectory(String uuid, String dataPath, String nativeLibPath32,
    214             int userId) throws InstallerException {
    215         mInstaller.execute("linklib", uuid, dataPath, nativeLibPath32, userId);
    216     }
    217 
    218     public void createOatDir(String oatDir, String dexInstructionSet)
    219             throws InstallerException {
    220         mInstaller.execute("createoatdir", oatDir, dexInstructionSet);
    221     }
    222 
    223     public void linkFile(String relativePath, String fromBase, String toBase)
    224             throws InstallerException {
    225         mInstaller.execute("linkfile", relativePath, fromBase, toBase);
    226     }
    227 
    228     public void moveAb(String apkPath, String instructionSet, String outputPath)
    229             throws InstallerException {
    230         mInstaller.execute("move_ab", apkPath, instructionSet, outputPath);
    231     }
    232 
    233     public void deleteOdex(String apkPath, String instructionSet, String outputPath)
    234             throws InstallerException {
    235         mInstaller.execute("delete_odex", apkPath, instructionSet, outputPath);
    236     }
    237 
    238     private static void assertValidInstructionSet(String instructionSet)
    239             throws InstallerException {
    240         for (String abi : Build.SUPPORTED_ABIS) {
    241             if (VMRuntime.getInstructionSet(abi).equals(instructionSet)) {
    242                 return;
    243             }
    244         }
    245         throw new InstallerException("Invalid instruction set: " + instructionSet);
    246     }
    247 }
    248