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     /**
     65      * Yell loudly if someone tries making future calls while holding a lock on
     66      * the given object.
     67      */
     68     public void setWarnIfHeld(Object warnIfHeld) {
     69         mInstaller.setWarnIfHeld(warnIfHeld);
     70     }
     71 
     72     @Override
     73     public void onStart() {
     74         Slog.i(TAG, "Waiting for installd to be ready.");
     75         mInstaller.waitForConnection();
     76     }
     77 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    152     public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
    153         return mInstaller.mergeProfiles(uid, pkgName);
    154     }
    155 
    156     public boolean dumpProfiles(String gid, String packageName, String codePaths)
    157             throws InstallerException {
    158         return mInstaller.dumpProfiles(gid, packageName, codePaths);
    159     }
    160 
    161     public void idmap(String targetApkPath, String overlayApkPath, int uid)
    162             throws InstallerException {
    163         mInstaller.execute("idmap", targetApkPath, overlayApkPath, uid);
    164     }
    165 
    166     public void rmdex(String codePath, String instructionSet) throws InstallerException {
    167         assertValidInstructionSet(instructionSet);
    168         mInstaller.execute("rmdex", codePath, instructionSet);
    169     }
    170 
    171     public void rmPackageDir(String packageDir) throws InstallerException {
    172         mInstaller.execute("rmpackagedir", packageDir);
    173     }
    174 
    175     public void clearAppProfiles(String pkgName) throws InstallerException {
    176         mInstaller.execute("clear_app_profiles", pkgName);
    177     }
    178 
    179     public void destroyAppProfiles(String pkgName) throws InstallerException {
    180         mInstaller.execute("destroy_app_profiles", pkgName);
    181     }
    182 
    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 
    188     public void destroyUserData(String uuid, int userId, int flags) throws InstallerException {
    189         mInstaller.execute("destroy_user_data", uuid, userId, flags);
    190     }
    191 
    192     public void markBootComplete(String instructionSet) throws InstallerException {
    193         assertValidInstructionSet(instructionSet);
    194         mInstaller.execute("markbootcomplete", instructionSet);
    195     }
    196 
    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      */
    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 
    211     public void createOatDir(String oatDir, String dexInstructionSet)
    212             throws InstallerException {
    213         mInstaller.execute("createoatdir", oatDir, dexInstructionSet);
    214     }
    215 
    216     public void linkFile(String relativePath, String fromBase, String toBase)
    217             throws InstallerException {
    218         mInstaller.execute("linkfile", relativePath, fromBase, toBase);
    219     }
    220 
    221     public void moveAb(String apkPath, String instructionSet, String outputPath)
    222             throws InstallerException {
    223         mInstaller.execute("move_ab", apkPath, instructionSet, outputPath);
    224     }
    225 
    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