Search in sources :

Example 51 with Signature

use of android.content.pm.Signature in project phonegap-facebook-plugin by Wizcorp.

the class Settings method getApplicationSignature.

public static String getApplicationSignature(Context context) {
    if (context == null) {
        return null;
    }
    PackageManager packageManager = context.getPackageManager();
    if (packageManager == null) {
        return null;
    }
    String packageName = context.getPackageName();
    PackageInfo pInfo;
    try {
        pInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
    } catch (PackageManager.NameNotFoundException e) {
        return null;
    }
    Signature[] signatures = pInfo.signatures;
    if (signatures == null || signatures.length == 0) {
        return null;
    }
    MessageDigest md;
    try {
        md = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e) {
        return null;
    }
    md.update(pInfo.signatures[0].toByteArray());
    return Base64.encodeToString(md.digest(), Base64.URL_SAFE | Base64.NO_PADDING);
}
Also used : PackageManager(android.content.pm.PackageManager) PackageInfo(android.content.pm.PackageInfo) Signature(android.content.pm.Signature) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) MessageDigest(java.security.MessageDigest)

Example 52 with Signature

use of android.content.pm.Signature in project weiciyuan by qii.

the class SsoHandler method validateAppSignatureForIntent.

private boolean validateAppSignatureForIntent(Activity activity, Intent intent) {
    ResolveInfo resolveInfo = activity.getPackageManager().resolveActivity(intent, 0);
    if (resolveInfo == null) {
        return false;
    }
    String packageName = resolveInfo.activityInfo.packageName;
    try {
        PackageInfo packageInfo = activity.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
        for (Signature signature : packageInfo.signatures) {
            if (WEIBO_SIGNATURE.equals(signature.toCharsString())) {
                return true;
            }
        }
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
    return false;
}
Also used : ResolveInfo(android.content.pm.ResolveInfo) PackageManager(android.content.pm.PackageManager) PackageInfo(android.content.pm.PackageInfo) Signature(android.content.pm.Signature)

Example 53 with Signature

use of android.content.pm.Signature in project android_frameworks_base by ParanoidAndroid.

the class PackageManagerBackupAgent method onRestore.

// "Restore" here is a misnomer.  What we're really doing is reading back the
// set of app signatures associated with each backed-up app in this restore
// image.  We'll use those later to determine what we can legitimately restore.
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException {
    List<ApplicationInfo> restoredApps = new ArrayList<ApplicationInfo>();
    HashMap<String, Metadata> sigMap = new HashMap<String, Metadata>();
    if (DEBUG)
        Slog.v(TAG, "onRestore()");
    int storedSystemVersion = -1;
    while (data.readNextHeader()) {
        String key = data.getKey();
        int dataSize = data.getDataSize();
        if (DEBUG)
            Slog.v(TAG, "   got key=" + key + " dataSize=" + dataSize);
        // generic setup to parse any entity data
        byte[] inputBytes = new byte[dataSize];
        data.readEntityData(inputBytes, 0, dataSize);
        ByteArrayInputStream inputBuffer = new ByteArrayInputStream(inputBytes);
        DataInputStream inputBufferStream = new DataInputStream(inputBuffer);
        if (key.equals(GLOBAL_METADATA_KEY)) {
            int storedSdkVersion = inputBufferStream.readInt();
            if (DEBUG)
                Slog.v(TAG, "   storedSystemVersion = " + storedSystemVersion);
            if (storedSystemVersion > Build.VERSION.SDK_INT) {
                // returning before setting the sig map means we rejected the restore set
                Slog.w(TAG, "Restore set was from a later version of Android; not restoring");
                return;
            }
            mStoredSdkVersion = storedSdkVersion;
            mStoredIncrementalVersion = inputBufferStream.readUTF();
            mHasMetadata = true;
            if (DEBUG) {
                Slog.i(TAG, "Restore set version " + storedSystemVersion + " is compatible with OS version " + Build.VERSION.SDK_INT + " (" + mStoredIncrementalVersion + " vs " + Build.VERSION.INCREMENTAL + ")");
            }
        } else {
            // it's a file metadata record
            int versionCode = inputBufferStream.readInt();
            Signature[] sigs = readSignatureArray(inputBufferStream);
            if (DEBUG) {
                Slog.i(TAG, "   read metadata for " + key + " dataSize=" + dataSize + " versionCode=" + versionCode + " sigs=" + sigs);
            }
            if (sigs == null || sigs.length == 0) {
                Slog.w(TAG, "Not restoring package " + key + " since it appears to have no signatures.");
                continue;
            }
            ApplicationInfo app = new ApplicationInfo();
            app.packageName = key;
            restoredApps.add(app);
            sigMap.put(key, new Metadata(versionCode, sigs));
        }
    }
    // On successful completion, cache the signature map for the Backup Manager to use
    mRestoredSignatures = sigMap;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ApplicationInfo(android.content.pm.ApplicationInfo) DataInputStream(java.io.DataInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) Signature(android.content.pm.Signature)

Example 54 with Signature

use of android.content.pm.Signature in project android_frameworks_base by ParanoidAndroid.

the class ServiceWatcher method getSignatureSets.

public static ArrayList<HashSet<Signature>> getSignatureSets(Context context, List<String> initialPackageNames) {
    PackageManager pm = context.getPackageManager();
    ArrayList<HashSet<Signature>> sigSets = new ArrayList<HashSet<Signature>>();
    for (int i = 0, size = initialPackageNames.size(); i < size; i++) {
        String pkg = initialPackageNames.get(i);
        try {
            HashSet<Signature> set = new HashSet<Signature>();
            Signature[] sigs = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures;
            set.addAll(Arrays.asList(sigs));
            sigSets.add(set);
        } catch (NameNotFoundException e) {
            Log.w("ServiceWatcher", pkg + " not found");
        }
    }
    return sigSets;
}
Also used : PackageManager(android.content.pm.PackageManager) NameNotFoundException(android.content.pm.PackageManager.NameNotFoundException) Signature(android.content.pm.Signature) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 55 with Signature

use of android.content.pm.Signature in project android_frameworks_base by ParanoidAndroid.

the class PackageManagerService method scanPackageLI.

private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, long currentTime, UserHandle user) {
    File scanFile = new File(pkg.mScanPath);
    if (scanFile == null || pkg.applicationInfo.sourceDir == null || pkg.applicationInfo.publicSourceDir == null) {
        // Bail out. The resource and code paths haven't been set.
        Slog.w(TAG, " Code and resource paths haven't been set correctly");
        mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
        return null;
    }
    mScanningPath = scanFile;
    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
    }
    if (pkg.packageName.equals("android")) {
        synchronized (mPackages) {
            if (mAndroidApplication != null) {
                Slog.w(TAG, "*************************************************");
                Slog.w(TAG, "Core android package being redefined.  Skipping.");
                Slog.w(TAG, " file=" + mScanningPath);
                Slog.w(TAG, "*************************************************");
                mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
                return null;
            }
            // Set up information for our fall-back user intent resolution
            // activity.
            mPlatformPackage = pkg;
            pkg.mVersionCode = mSdkVersion;
            mAndroidApplication = pkg.applicationInfo;
            mResolveActivity.applicationInfo = mAndroidApplication;
            mResolveActivity.name = ResolverActivity.class.getName();
            mResolveActivity.packageName = mAndroidApplication.packageName;
            mResolveActivity.processName = "system:ui";
            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
            mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
            mResolveActivity.exported = true;
            mResolveActivity.enabled = true;
            mResolveInfo.activityInfo = mResolveActivity;
            mResolveInfo.priority = 0;
            mResolveInfo.preferredOrder = 0;
            mResolveInfo.match = 0;
            mResolveComponentName = new ComponentName(mAndroidApplication.packageName, mResolveActivity.name);
        }
    }
    if (DEBUG_PACKAGE_SCANNING) {
        if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
            Log.d(TAG, "Scanning package " + pkg.packageName);
    }
    if (mPackages.containsKey(pkg.packageName) || mSharedLibraries.containsKey(pkg.packageName)) {
        Slog.w(TAG, "Application package " + pkg.packageName + " already installed.  Skipping duplicate.");
        mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
        return null;
    }
    if (!pkg.applicationInfo.sourceDir.startsWith(Environment.getRootDirectory().getPath()) && !pkg.applicationInfo.sourceDir.startsWith("/vendor")) {
        Object obj = mSettings.getUserIdLPr(1000);
        Signature[] s1 = null;
        if (obj instanceof SharedUserSetting) {
            s1 = ((SharedUserSetting) obj).signatures.mSignatures;
        }
        if ((compareSignatures(pkg.mSignatures, s1) == PackageManager.SIGNATURE_MATCH)) {
            Slog.w(TAG, "Cannot install platform packages to user storage");
            mLastScanError = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
            return null;
        }
    }
    // Initialize package source and resource directories
    File destCodeFile = new File(pkg.applicationInfo.sourceDir);
    File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
    SharedUserSetting suid = null;
    PackageSetting pkgSetting = null;
    if (!isSystemApp(pkg)) {
        // Only system apps can use these features.
        pkg.mOriginalPackages = null;
        pkg.mRealPackage = null;
        pkg.mAdoptPermissions = null;
    }
    // writer
    synchronized (mPackages) {
        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
            // library paths after the scan is done.
            if (!updateSharedLibrariesLPw(pkg, null)) {
                return null;
            }
        }
        if (pkg.mSharedUserId != null) {
            suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, pkg.applicationInfo.flags, true);
            if (suid == null) {
                Slog.w(TAG, "Creating application package " + pkg.packageName + " for shared user failed");
                mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
                return null;
            }
            if (DEBUG_PACKAGE_SCANNING) {
                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
                    Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId + "): packages=" + suid.packages);
            }
        }
        // Check if we are renaming from an original package name.
        PackageSetting origPackage = null;
        String realName = null;
        if (pkg.mOriginalPackages != null) {
            // This package may need to be renamed to a previously
            // installed name.  Let's check on that...
            final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
            if (pkg.mOriginalPackages.contains(renamed)) {
                // This package had originally been installed as the
                // original name, and we have already taken care of
                // transitioning to the new one.  Just update the new
                // one to continue using the old name.
                realName = pkg.mRealPackage;
                if (!pkg.packageName.equals(renamed)) {
                    // Callers into this function may have already taken
                    // care of renaming the package; only do it here if
                    // it is not already done.
                    pkg.setPackageName(renamed);
                }
            } else {
                for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; i--) {
                    if ((origPackage = mSettings.peekPackageLPr(pkg.mOriginalPackages.get(i))) != null) {
                        // original name...  should we use it?
                        if (!verifyPackageUpdateLPr(origPackage, pkg)) {
                            // New package is not compatible with original.
                            origPackage = null;
                            continue;
                        } else if (origPackage.sharedUser != null) {
                            // Make sure uid is compatible between packages.
                            if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
                                Slog.w(TAG, "Unable to migrate data from " + origPackage.name + " to " + pkg.packageName + ": old uid " + origPackage.sharedUser.name + " differs from " + pkg.mSharedUserId);
                                origPackage = null;
                                continue;
                            }
                        } else {
                            if (DEBUG_UPGRADE)
                                Log.v(TAG, "Renaming new package " + pkg.packageName + " to old name " + origPackage.name);
                        }
                        break;
                    }
                }
            }
        }
        if (mTransferedPackages.contains(pkg.packageName)) {
            Slog.w(TAG, "Package " + pkg.packageName + " was transferred to another, but its .apk remains");
        }
        // Just create the setting, don't add it yet. For already existing packages
        // the PkgSetting exists already and doesn't have to be created.
        pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.flags, user, false);
        if (pkgSetting == null) {
            Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
            mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
            return null;
        }
        if (pkgSetting.origPackage != null) {
            // If we are first transitioning from an original package,
            // fix up the new package's name now.  We need to do this after
            // looking up the package under its new name, so getPackageLP
            // can take care of fiddling things correctly.
            pkg.setPackageName(origPackage.name);
            // File a report about this.
            String msg = "New package " + pkgSetting.realName + " renamed to replace old package " + pkgSetting.name;
            reportSettingsProblem(Log.WARN, msg);
            // Make a note of it.
            mTransferedPackages.add(origPackage.name);
            // No longer need to retain this.
            pkgSetting.origPackage = null;
        }
        if (realName != null) {
            // Make a note of it.
            mTransferedPackages.add(pkg.packageName);
        }
        if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
        }
        if (mFoundPolicyFile) {
            SELinuxMMAC.assignSeinfoValue(pkg);
        }
        pkg.applicationInfo.uid = pkgSetting.appId;
        pkg.mExtras = pkgSetting;
        if (!verifySignaturesLP(pkgSetting, pkg)) {
            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
                return null;
            }
            // The signature has changed, but this package is in the system
            // image...  let's recover!
            pkgSetting.signatures.mSignatures = pkg.mSignatures;
            // that unreasonable.
            if (pkgSetting.sharedUser != null) {
                if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
                    Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
                    mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
                    return null;
                }
            }
            // File a report about this.
            String msg = "System package " + pkg.packageName + " signature changed; retaining data.";
            reportSettingsProblem(Log.WARN, msg);
        }
        // things that are installed.
        if ((scanMode & SCAN_NEW_INSTALL) != 0) {
            final int N = pkg.providers.size();
            int i;
            for (i = 0; i < N; i++) {
                PackageParser.Provider p = pkg.providers.get(i);
                if (p.info.authority != null) {
                    String[] names = p.info.authority.split(";");
                    for (int j = 0; j < names.length; j++) {
                        if (mProviders.containsKey(names[j])) {
                            PackageParser.Provider other = mProviders.get(names[j]);
                            Slog.w(TAG, "Can't install because provider name " + names[j] + " (in package " + pkg.applicationInfo.packageName + ") is already used by " + ((other != null && other.getComponentName() != null) ? other.getComponentName().getPackageName() : "?"));
                            mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
                            return null;
                        }
                    }
                }
            }
        }
        if (pkg.mAdoptPermissions != null) {
            // another package.
            for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
                final String origName = pkg.mAdoptPermissions.get(i);
                final PackageSetting orig = mSettings.peekPackageLPr(origName);
                if (orig != null) {
                    if (verifyPackageUpdateLPr(orig, pkg)) {
                        Slog.i(TAG, "Adopting permissions from " + origName + " to " + pkg.packageName);
                        mSettings.transferPermissionsLPw(origName, pkg.packageName);
                    }
                }
            }
        }
    }
    final String pkgName = pkg.packageName;
    final long scanFileTime = scanFile.lastModified();
    final boolean forceDex = (scanMode & SCAN_FORCE_DEX) != 0;
    pkg.applicationInfo.processName = fixProcessName(pkg.applicationInfo.packageName, pkg.applicationInfo.processName, pkg.applicationInfo.uid);
    File dataPath;
    if (mPlatformPackage == pkg) {
        // The system package is special.
        dataPath = new File(Environment.getDataDirectory(), "system");
        pkg.applicationInfo.dataDir = dataPath.getPath();
    } else {
        // This is a normal package, need to make its data directory.
        dataPath = getDataPathForPackage(pkg.packageName, 0);
        boolean uidError = false;
        if (dataPath.exists()) {
            int currentUid = 0;
            try {
                StructStat stat = Libcore.os.stat(dataPath.getPath());
                currentUid = stat.st_uid;
            } catch (ErrnoException e) {
                Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
            }
            // If we have mismatched owners for the data path, we have a problem.
            if (currentUid != pkg.applicationInfo.uid) {
                boolean recovered = false;
                if (currentUid == 0) {
                    // The directory somehow became owned by root.  Wow.
                    // This is probably because the system was stopped while
                    // installd was in the middle of messing with its libs
                    // directory.  Ask installd to fix that.
                    int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid, pkg.applicationInfo.uid);
                    if (ret >= 0) {
                        recovered = true;
                        String msg = "Package " + pkg.packageName + " unexpectedly changed to uid 0; recovered to " + +pkg.applicationInfo.uid;
                        reportSettingsProblem(Log.WARN, msg);
                    }
                }
                if (!recovered && ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0 || (scanMode & SCAN_BOOTING) != 0)) {
                    // If this is a system app, we can at least delete its
                    // current data so the application will still work.
                    int ret = removeDataDirsLI(pkgName);
                    if (ret >= 0) {
                        // TODO: Kill the processes first
                        // Old data gone!
                        String prefix = (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0 ? "System package " : "Third party package ";
                        String msg = prefix + pkg.packageName + " has changed from uid: " + currentUid + " to " + pkg.applicationInfo.uid + "; old data erased";
                        reportSettingsProblem(Log.WARN, msg);
                        recovered = true;
                        // And now re-install the app.
                        ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, pkg.applicationInfo.seinfo);
                        if (ret == -1) {
                            // Ack should not happen!
                            msg = prefix + pkg.packageName + " could not have data directory re-created after delete.";
                            reportSettingsProblem(Log.WARN, msg);
                            mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
                            return null;
                        }
                    }
                    if (!recovered) {
                        mHasSystemUidErrors = true;
                    }
                } else if (!recovered) {
                    // If we allow this install to proceed, we will be broken.
                    // Abort, abort!
                    mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
                    return null;
                }
                if (!recovered) {
                    pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" + pkg.applicationInfo.uid + "/fs_" + currentUid;
                    pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
                    String msg = "Package " + pkg.packageName + " has mismatched uid: " + currentUid + " on disk, " + pkg.applicationInfo.uid + " in settings";
                    // writer
                    synchronized (mPackages) {
                        mSettings.mReadMessages.append(msg);
                        mSettings.mReadMessages.append('\n');
                        uidError = true;
                        if (!pkgSetting.uidError) {
                            reportSettingsProblem(Log.ERROR, msg);
                        }
                    }
                }
            }
            pkg.applicationInfo.dataDir = dataPath.getPath();
        } else {
            if (DEBUG_PACKAGE_SCANNING) {
                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
                    Log.v(TAG, "Want this data dir: " + dataPath);
            }
            //invoke installer to do the actual installation
            int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, pkg.applicationInfo.seinfo);
            if (ret < 0) {
                // Error from installer
                mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
                return null;
            }
            if (dataPath.exists()) {
                pkg.applicationInfo.dataDir = dataPath.getPath();
            } else {
                Slog.w(TAG, "Unable to create data directory: " + dataPath);
                pkg.applicationInfo.dataDir = null;
            }
        }
        /*
             * Set the data dir to the default "/data/data/<package name>/lib"
             * if we got here without anyone telling us different (e.g., apps
             * stored on SD card have their native libraries stored in the ASEC
             * container with the APK).
             *
             * This happens during an upgrade from a package settings file that
             * doesn't have a native library path attribute at all.
             */
        if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
            if (pkgSetting.nativeLibraryPathString == null) {
                setInternalAppNativeLibraryPath(pkg, pkgSetting);
            } else {
                pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
            }
        }
        pkgSetting.uidError = uidError;
    }
    String path = scanFile.getPath();
    /* Note: We don't want to unpack the native binaries for
         *        system applications, unless they have been updated
         *        (the binaries are already under /system/lib).
         *        Also, don't unpack libs for apps on the external card
         *        since they should have their libraries in the ASEC
         *        container already.
         *
         *        In other words, we're going to unpack the binaries
         *        only for non-system apps and system app upgrades.
         */
    if (pkg.applicationInfo.nativeLibraryDir != null) {
        try {
            File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
            final String dataPathString = dataPath.getCanonicalPath();
            if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
                /*
                     * Upgrading from a previous version of the OS sometimes
                     * leaves native libraries in the /data/data/<app>/lib
                     * directory for system apps even when they shouldn't be.
                     * Recent changes in the JNI library search path
                     * necessitates we remove those to match previous behavior.
                     */
                if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
                    Log.i(TAG, "removed obsolete native libraries for system package " + path);
                }
            } else {
                if (!isForwardLocked(pkg) && !isExternal(pkg)) {
                    /*
                         * Update native library dir if it starts with
                         * /data/data
                         */
                    if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
                        setInternalAppNativeLibraryPath(pkg, pkgSetting);
                        nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
                    }
                    try {
                        if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
                            Slog.e(TAG, "Unable to copy native libraries");
                            mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                            return null;
                        }
                    } catch (IOException e) {
                        Slog.e(TAG, "Unable to copy native libraries", e);
                        mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                        return null;
                    }
                }
                if (DEBUG_INSTALL)
                    Slog.i(TAG, "Linking native library dir for " + path);
                final int[] userIds = sUserManager.getUserIds();
                synchronized (mInstallLock) {
                    for (int userId : userIds) {
                        if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, pkg.applicationInfo.nativeLibraryDir, userId) < 0) {
                            Slog.w(TAG, "Failed linking native library dir (user=" + userId + ")");
                            mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                            return null;
                        }
                    }
                }
            }
        } catch (IOException ioe) {
            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
        }
    }
    pkg.mScanPath = path;
    if ((scanMode & SCAN_NO_DEX) == 0) {
        if (performDexOptLI(pkg, forceDex, (scanMode & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
            mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
            return null;
        }
    }
    if (mFactoryTest && pkg.requestedPermissions.contains(android.Manifest.permission.FACTORY_TEST)) {
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
    }
    ArrayList<PackageParser.Package> clientLibPkgs = null;
    // writer
    synchronized (mPackages) {
        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
            // Only system apps can add new shared libraries.
            if (pkg.libraryNames != null) {
                for (int i = 0; i < pkg.libraryNames.size(); i++) {
                    String name = pkg.libraryNames.get(i);
                    boolean allowed = false;
                    if (isUpdatedSystemApp(pkg)) {
                        // New library entries can only be added through the
                        // system image.  This is important to get rid of a lot
                        // of nasty edge cases: for example if we allowed a non-
                        // system update of the app to add a library, then uninstalling
                        // the update would make the library go away, and assumptions
                        // we made such as through app install filtering would now
                        // have allowed apps on the device which aren't compatible
                        // with it.  Better to just have the restriction here, be
                        // conservative, and create many fewer cases that can negatively
                        // impact the user experience.
                        final PackageSetting sysPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
                        if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
                            for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
                                if (name.equals(sysPs.pkg.libraryNames.get(j))) {
                                    allowed = true;
                                    allowed = true;
                                    break;
                                }
                            }
                        }
                    } else {
                        allowed = true;
                    }
                    if (allowed) {
                        if (!mSharedLibraries.containsKey(name)) {
                            mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
                        } else if (!name.equals(pkg.packageName)) {
                            Slog.w(TAG, "Package " + pkg.packageName + " library " + name + " already exists; skipping");
                        }
                    } else {
                        Slog.w(TAG, "Package " + pkg.packageName + " declares lib " + name + " that is not declared on system image; skipping");
                    }
                }
                if ((scanMode & SCAN_BOOTING) == 0) {
                    // If we are not booting, we need to update any applications
                    // that are clients of our shared library.  If we are booting,
                    // this will all be done once the scan is complete.
                    clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
                }
            }
        }
    }
    // result in some apps being broken.
    if (clientLibPkgs != null) {
        if ((scanMode & SCAN_NO_DEX) == 0) {
            for (int i = 0; i < clientLibPkgs.size(); i++) {
                PackageParser.Package clientPkg = clientLibPkgs.get(i);
                if (performDexOptLI(clientPkg, forceDex, (scanMode & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
                    mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
                    return null;
                }
            }
        }
    }
    // version of the application while the new one gets installed.
    if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
        killApplication(pkg.applicationInfo.packageName, pkg.applicationInfo.uid);
    }
    // Also need to kill any apps that are dependent on the library.
    if (clientLibPkgs != null) {
        for (int i = 0; i < clientLibPkgs.size(); i++) {
            PackageParser.Package clientPkg = clientLibPkgs.get(i);
            killApplication(clientPkg.applicationInfo.packageName, clientPkg.applicationInfo.uid);
        }
    }
    // writer
    synchronized (mPackages) {
        // We don't expect installation to fail beyond this point,
        if ((scanMode & SCAN_MONITOR) != 0) {
            mAppDirs.put(pkg.mPath, pkg);
        }
        // Add the new setting to mSettings
        mSettings.insertPackageSettingLPw(pkgSetting, pkg);
        // Add the new setting to mPackages
        mPackages.put(pkg.applicationInfo.packageName, pkg);
        // Make sure we don't accidentally delete its data.
        final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
        while (iter.hasNext()) {
            PackageCleanItem item = iter.next();
            if (pkgName.equals(item.packageName)) {
                iter.remove();
            }
        }
        // Take care of first install / last update times.
        if (currentTime != 0) {
            if (pkgSetting.firstInstallTime == 0) {
                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
            } else if ((scanMode & SCAN_UPDATE_TIME) != 0) {
                pkgSetting.lastUpdateTime = currentTime;
            }
        } else if (pkgSetting.firstInstallTime == 0) {
            // We need *something*.  Take time time stamp of the file.
            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
            if (scanFileTime != pkgSetting.timeStamp) {
                // A package on the system image has changed; consider this
                // to be an update.
                pkgSetting.lastUpdateTime = scanFileTime;
            }
        }
        int N = pkg.providers.size();
        StringBuilder r = null;
        int i;
        for (i = 0; i < N; i++) {
            PackageParser.Provider p = pkg.providers.get(i);
            p.info.processName = fixProcessName(pkg.applicationInfo.processName, p.info.processName, pkg.applicationInfo.uid);
            mProvidersByComponent.put(new ComponentName(p.info.packageName, p.info.name), p);
            p.syncable = p.info.isSyncable;
            if (p.info.authority != null) {
                String[] names = p.info.authority.split(";");
                p.info.authority = null;
                for (int j = 0; j < names.length; j++) {
                    if (j == 1 && p.syncable) {
                        // We only want the first authority for a provider to possibly be
                        // syncable, so if we already added this provider using a different
                        // authority clear the syncable flag. We copy the provider before
                        // changing it because the mProviders object contains a reference
                        // to a provider that we don't want to change.
                        // Only do this for the second authority since the resulting provider
                        // object can be the same for all future authorities for this provider.
                        p = new PackageParser.Provider(p);
                        p.syncable = false;
                    }
                    if (!mProviders.containsKey(names[j])) {
                        mProviders.put(names[j], p);
                        if (p.info.authority == null) {
                            p.info.authority = names[j];
                        } else {
                            p.info.authority = p.info.authority + ";" + names[j];
                        }
                        if (DEBUG_PACKAGE_SCANNING) {
                            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
                                Log.d(TAG, "Registered content provider: " + names[j] + ", className = " + p.info.name + ", isSyncable = " + p.info.isSyncable);
                        }
                    } else {
                        PackageParser.Provider other = mProviders.get(names[j]);
                        Slog.w(TAG, "Skipping provider name " + names[j] + " (in package " + pkg.applicationInfo.packageName + "): name already used by " + ((other != null && other.getComponentName() != null) ? other.getComponentName().getPackageName() : "?"));
                    }
                }
            }
            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
                if (r == null) {
                    r = new StringBuilder(256);
                } else {
                    r.append(' ');
                }
                r.append(p.info.name);
            }
        }
        if (r != null) {
            if (DEBUG_PACKAGE_SCANNING)
                Log.d(TAG, "  Providers: " + r);
        }
        N = pkg.services.size();
        r = null;
        for (i = 0; i < N; i++) {
            PackageParser.Service s = pkg.services.get(i);
            s.info.processName = fixProcessName(pkg.applicationInfo.processName, s.info.processName, pkg.applicationInfo.uid);
            mServices.addService(s);
            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
                if (r == null) {
                    r = new StringBuilder(256);
                } else {
                    r.append(' ');
                }
                r.append(s.info.name);
            }
        }
        if (r != null) {
            if (DEBUG_PACKAGE_SCANNING)
                Log.d(TAG, "  Services: " + r);
        }
        N = pkg.receivers.size();
        r = null;
        for (i = 0; i < N; i++) {
            PackageParser.Activity a = pkg.receivers.get(i);
            a.info.processName = fixProcessName(pkg.applicationInfo.processName, a.info.processName, pkg.applicationInfo.uid);
            mReceivers.addActivity(a, "receiver");
            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
                if (r == null) {
                    r = new StringBuilder(256);
                } else {
                    r.append(' ');
                }
                r.append(a.info.name);
            }
        }
        if (r != null) {
            if (DEBUG_PACKAGE_SCANNING)
                Log.d(TAG, "  Receivers: " + r);
        }
        N = pkg.activities.size();
        r = null;
        for (i = 0; i < N; i++) {
            PackageParser.Activity a = pkg.activities.get(i);
            a.info.processName = fixProcessName(pkg.applicationInfo.processName, a.info.processName, pkg.applicationInfo.uid);
            mActivities.addActivity(a, "activity");
            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
                if (r == null) {
                    r = new StringBuilder(256);
                } else {
                    r.append(' ');
                }
                r.append(a.info.name);
            }
        }
        if (r != null) {
            if (DEBUG_PACKAGE_SCANNING)
                Log.d(TAG, "  Activities: " + r);
        }
        N = pkg.permissionGroups.size();
        r = null;
        for (i = 0; i < N; i++) {
            PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
            PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
            if (cur == null) {
                mPermissionGroups.put(pg.info.name, pg);
                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
                    if (r == null) {
                        r = new StringBuilder(256);
                    } else {
                        r.append(' ');
                    }
                    r.append(pg.info.name);
                }
            } else {
                Slog.w(TAG, "Permission group " + pg.info.name + " from package " + pg.info.packageName + " ignored: original from " + cur.info.packageName);
                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
                    if (r == null) {
                        r = new StringBuilder(256);
                    } else {
                        r.append(' ');
                    }
                    r.append("DUP:");
                    r.append(pg.info.name);
                }
            }
        }
        if (r != null) {
            if (DEBUG_PACKAGE_SCANNING)
                Log.d(TAG, "  Permission Groups: " + r);
        }
        N = pkg.permissions.size();
        r = null;
        for (i = 0; i < N; i++) {
            PackageParser.Permission p = pkg.permissions.get(i);
            HashMap<String, BasePermission> permissionMap = p.tree ? mSettings.mPermissionTrees : mSettings.mPermissions;
            p.group = mPermissionGroups.get(p.info.group);
            if (p.info.group == null || p.group != null) {
                BasePermission bp = permissionMap.get(p.info.name);
                if (bp == null) {
                    bp = new BasePermission(p.info.name, p.info.packageName, BasePermission.TYPE_NORMAL);
                    permissionMap.put(p.info.name, bp);
                }
                if (bp.perm == null) {
                    if (bp.sourcePackage == null || bp.sourcePackage.equals(p.info.packageName)) {
                        BasePermission tree = findPermissionTreeLP(p.info.name);
                        if (tree == null || tree.sourcePackage.equals(p.info.packageName)) {
                            bp.packageSetting = pkgSetting;
                            bp.perm = p;
                            bp.uid = pkg.applicationInfo.uid;
                            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
                                if (r == null) {
                                    r = new StringBuilder(256);
                                } else {
                                    r.append(' ');
                                }
                                r.append(p.info.name);
                            }
                        } else {
                            Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " ignored: base tree " + tree.name + " is from package " + tree.sourcePackage);
                        }
                    } else {
                        Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " ignored: original from " + bp.sourcePackage);
                    }
                } else if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
                    if (r == null) {
                        r = new StringBuilder(256);
                    } else {
                        r.append(' ');
                    }
                    r.append("DUP:");
                    r.append(p.info.name);
                }
                if (bp.perm == p) {
                    bp.protectionLevel = p.info.protectionLevel;
                }
            } else {
                Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " ignored: no group " + p.group);
            }
        }
        if (r != null) {
            if (DEBUG_PACKAGE_SCANNING)
                Log.d(TAG, "  Permissions: " + r);
        }
        N = pkg.instrumentation.size();
        r = null;
        for (i = 0; i < N; i++) {
            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
            a.info.packageName = pkg.applicationInfo.packageName;
            a.info.sourceDir = pkg.applicationInfo.sourceDir;
            a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
            a.info.dataDir = pkg.applicationInfo.dataDir;
            a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
            mInstrumentation.put(a.getComponentName(), a);
            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
                if (r == null) {
                    r = new StringBuilder(256);
                } else {
                    r.append(' ');
                }
                r.append(a.info.name);
            }
        }
        if (r != null) {
            if (DEBUG_PACKAGE_SCANNING)
                Log.d(TAG, "  Instrumentation: " + r);
        }
        if (pkg.protectedBroadcasts != null) {
            N = pkg.protectedBroadcasts.size();
            for (i = 0; i < N; i++) {
                mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
            }
        }
        pkgSetting.setTimeStamp(scanFileTime);
    }
    return pkg;
}
Also used : ComponentName(android.content.ComponentName) StructStat(libcore.io.StructStat) ResolverActivity(com.android.internal.app.ResolverActivity) IOException(java.io.IOException) ErrnoException(libcore.io.ErrnoException) PackageParser(android.content.pm.PackageParser) PackageCleanItem(android.content.pm.PackageCleanItem) Signature(android.content.pm.Signature) File(java.io.File) ZipFile(java.util.zip.ZipFile)

Aggregations

Signature (android.content.pm.Signature)97 PackageManager (android.content.pm.PackageManager)34 NameNotFoundException (android.content.pm.PackageManager.NameNotFoundException)31 PackageInfo (android.content.pm.PackageInfo)26 ArrayList (java.util.ArrayList)16 MessageDigest (java.security.MessageDigest)13 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)13 ArraySet (android.util.ArraySet)11 IOException (java.io.IOException)8 PublicKey (java.security.PublicKey)8 File (java.io.File)7 Intent (android.content.Intent)6 CertificateException (java.security.cert.CertificateException)6 HashSet (java.util.HashSet)6 ResolveInfo (android.content.pm.ResolveInfo)5 INetworkManagementEventObserver (android.net.INetworkManagementEventObserver)5 IActivityManager (android.app.IActivityManager)4 INotificationManager (android.app.INotificationManager)4 IProcessObserver (android.app.IProcessObserver)4 PackageParser (android.content.pm.PackageParser)4