Loading services/java/com/android/server/pm/Installer.java +6 −1 Original line number Original line Diff line number Diff line Loading @@ -342,7 +342,8 @@ public final class Installer { return execute(builder.toString()); return execute(builder.toString()); } } public int idmap(String targetApkPath, String overlayApkPath, String redirectionsPath, int uid) { public int idmap(String targetApkPath, String overlayApkPath, String redirectionsPath, int uid, int targetHash, int overlayHash) { StringBuilder builder = new StringBuilder("idmap"); StringBuilder builder = new StringBuilder("idmap"); builder.append(' '); builder.append(' '); builder.append(targetApkPath); builder.append(targetApkPath); Loading @@ -350,6 +351,10 @@ public final class Installer { builder.append(overlayApkPath); builder.append(overlayApkPath); builder.append(' '); builder.append(' '); builder.append(uid); builder.append(uid); builder.append(' '); builder.append(targetHash); builder.append(' '); builder.append(overlayHash); if (redirectionsPath != null) { if (redirectionsPath != null) { builder.append(' '); builder.append(' '); builder.append(redirectionsPath); builder.append(redirectionsPath); Loading services/java/com/android/server/pm/PackageManagerService.java +53 −12 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static libcore.io.OsConstants.S_IXGRP; import static libcore.io.OsConstants.S_IROTH; import static libcore.io.OsConstants.S_IROTH; import static libcore.io.OsConstants.S_IXOTH; import static libcore.io.OsConstants.S_IXOTH; import android.util.Pair; import com.android.internal.app.IMediaContainerService; import com.android.internal.app.IMediaContainerService; import com.android.internal.app.ResolverActivity; import com.android.internal.app.ResolverActivity; import com.android.internal.content.NativeLibraryHelper; import com.android.internal.content.NativeLibraryHelper; Loading Loading @@ -156,6 +157,8 @@ import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ByteOrder; import java.nio.IntBuffer; import java.nio.IntBuffer; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.CertificateException; Loading Loading @@ -294,6 +297,8 @@ public class PackageManagerService extends IPackageManager.Stub { // Where package redirections are stored for legacy themes // Where package redirections are stored for legacy themes private static final String REDIRECTIONS_PATH = "/data/app/redirections"; private static final String REDIRECTIONS_PATH = "/data/app/redirections"; private static final long PACKAGE_HASH_EXPIRATION = 3*60*1000; // 3 minutes final HandlerThread mHandlerThread = new HandlerThread("PackageManager", final HandlerThread mHandlerThread = new HandlerThread("PackageManager", Process.THREAD_PRIORITY_BACKGROUND); Process.THREAD_PRIORITY_BACKGROUND); final PackageHandler mHandler; final PackageHandler mHandler; Loading Loading @@ -487,6 +492,9 @@ public class PackageManagerService extends IPackageManager.Stub { private IconPackHelper mIconPackHelper; private IconPackHelper mIconPackHelper; private Map<String, Pair<Integer, Long>> mPackageHashes = new HashMap<String, Pair<Integer, Long>>(); // Set of pending broadcasts for aggregating enable/disable of components. // Set of pending broadcasts for aggregating enable/disable of components. static class PendingPackageBroadcasts { static class PendingPackageBroadcasts { // for each user id, a map of <package name -> components within that package> // for each user id, a map of <package name -> components within that package> Loading Loading @@ -3663,7 +3671,8 @@ public class PackageManagerService extends IPackageManager.Stub { return false; return false; } } final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, redirectionsPath, sharedGid) != 0) { if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, redirectionsPath, sharedGid, getPackageHashCode(pkg), getPackageHashCode(opkg)) != 0) { Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath); Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath); return false; return false; } } Loading Loading @@ -5571,8 +5580,8 @@ public class PackageManagerService extends IPackageManager.Stub { } } /** /** * Compares the last modified time of the target and overlay to those stored * Compares the 32 bit hash of the target and overlay to those stored * in the idmap and returns true if either time differs * in the idmap and returns true if either hash differs * @param targetPkg * @param targetPkg * @param overlayPkg * @param overlayPkg * @return * @return Loading @@ -5582,23 +5591,22 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.Package overlayPkg) { PackageParser.Package overlayPkg) { if (targetPkg == null || overlayPkg == null) return false; if (targetPkg == null || overlayPkg == null) return false; int targetHash = getPackageHashCode(targetPkg); int overlayHash = getPackageHashCode(overlayPkg); File idmap = new File(getIdmapPath(targetPkg, overlayPkg)); File idmap = new File(getIdmapPath(targetPkg, overlayPkg)); if (!idmap.exists()) if (!idmap.exists()) return true; return true; int[] mtimes; int[] hashes; try { try { mtimes = getIdmapTimes(idmap); hashes = getIdmapHashes(idmap); } catch (IOException e) { } catch (IOException e) { return true; return true; } } File f = new File(targetPkg.mPath); if ((int)(f.lastModified() / 1000) != mtimes[0]) { return true; } f = new File(overlayPkg.mPath); if (targetHash == 0 || overlayHash == 0 || if ((int)(f.lastModified() / 1000) != mtimes[1]) { targetHash != hashes[0] || overlayHash != hashes[1]) { return true; return true; } } return false; return false; Loading @@ -5610,7 +5618,7 @@ public class PackageManagerService extends IPackageManager.Stub { * @return * @return * @throws IOException * @throws IOException */ */ private int[] getIdmapTimes(File idmap) throws IOException { private int[] getIdmapHashes(File idmap) throws IOException { int[] times = new int[2]; int[] times = new int[2]; ByteBuffer bb = ByteBuffer.allocate(20); ByteBuffer bb = ByteBuffer.allocate(20); bb.order(ByteOrder.LITTLE_ENDIAN); bb.order(ByteOrder.LITTLE_ENDIAN); Loading @@ -5624,6 +5632,39 @@ public class PackageManagerService extends IPackageManager.Stub { return times; return times; } } /** * Get a 32 bit hashcode for the given package. * @param pkg * @return */ private int getPackageHashCode(PackageParser.Package pkg) { Pair<Integer, Long> p = mPackageHashes.get(pkg.packageName); if (p != null && (System.currentTimeMillis() - p.second < PACKAGE_HASH_EXPIRATION)) { return p.first; } if (p != null) { mPackageHashes.remove(p); } byte[] md5 = getFileMd5Sum(pkg.mPath); if (md5 == null) return 0; p = new Pair(Arrays.hashCode(md5), System.currentTimeMillis()); mPackageHashes.put(pkg.packageName, p); return p.first; } private byte[] getFileMd5Sum(String path) { try { MessageDigest md = MessageDigest.getInstance("MD5"); DigestInputStream dis = new DigestInputStream(new FileInputStream(path), md); dis.close(); return md.digest(); } catch (Exception e) { } return null; } private void setUpCustomResolverActivity(PackageParser.Package pkg) { private void setUpCustomResolverActivity(PackageParser.Package pkg) { synchronized (mPackages) { synchronized (mPackages) { mResolverReplaced = true; mResolverReplaced = true; Loading Loading
services/java/com/android/server/pm/Installer.java +6 −1 Original line number Original line Diff line number Diff line Loading @@ -342,7 +342,8 @@ public final class Installer { return execute(builder.toString()); return execute(builder.toString()); } } public int idmap(String targetApkPath, String overlayApkPath, String redirectionsPath, int uid) { public int idmap(String targetApkPath, String overlayApkPath, String redirectionsPath, int uid, int targetHash, int overlayHash) { StringBuilder builder = new StringBuilder("idmap"); StringBuilder builder = new StringBuilder("idmap"); builder.append(' '); builder.append(' '); builder.append(targetApkPath); builder.append(targetApkPath); Loading @@ -350,6 +351,10 @@ public final class Installer { builder.append(overlayApkPath); builder.append(overlayApkPath); builder.append(' '); builder.append(' '); builder.append(uid); builder.append(uid); builder.append(' '); builder.append(targetHash); builder.append(' '); builder.append(overlayHash); if (redirectionsPath != null) { if (redirectionsPath != null) { builder.append(' '); builder.append(' '); builder.append(redirectionsPath); builder.append(redirectionsPath); Loading
services/java/com/android/server/pm/PackageManagerService.java +53 −12 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static libcore.io.OsConstants.S_IXGRP; import static libcore.io.OsConstants.S_IROTH; import static libcore.io.OsConstants.S_IROTH; import static libcore.io.OsConstants.S_IXOTH; import static libcore.io.OsConstants.S_IXOTH; import android.util.Pair; import com.android.internal.app.IMediaContainerService; import com.android.internal.app.IMediaContainerService; import com.android.internal.app.ResolverActivity; import com.android.internal.app.ResolverActivity; import com.android.internal.content.NativeLibraryHelper; import com.android.internal.content.NativeLibraryHelper; Loading Loading @@ -156,6 +157,8 @@ import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ByteOrder; import java.nio.IntBuffer; import java.nio.IntBuffer; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.CertificateException; Loading Loading @@ -294,6 +297,8 @@ public class PackageManagerService extends IPackageManager.Stub { // Where package redirections are stored for legacy themes // Where package redirections are stored for legacy themes private static final String REDIRECTIONS_PATH = "/data/app/redirections"; private static final String REDIRECTIONS_PATH = "/data/app/redirections"; private static final long PACKAGE_HASH_EXPIRATION = 3*60*1000; // 3 minutes final HandlerThread mHandlerThread = new HandlerThread("PackageManager", final HandlerThread mHandlerThread = new HandlerThread("PackageManager", Process.THREAD_PRIORITY_BACKGROUND); Process.THREAD_PRIORITY_BACKGROUND); final PackageHandler mHandler; final PackageHandler mHandler; Loading Loading @@ -487,6 +492,9 @@ public class PackageManagerService extends IPackageManager.Stub { private IconPackHelper mIconPackHelper; private IconPackHelper mIconPackHelper; private Map<String, Pair<Integer, Long>> mPackageHashes = new HashMap<String, Pair<Integer, Long>>(); // Set of pending broadcasts for aggregating enable/disable of components. // Set of pending broadcasts for aggregating enable/disable of components. static class PendingPackageBroadcasts { static class PendingPackageBroadcasts { // for each user id, a map of <package name -> components within that package> // for each user id, a map of <package name -> components within that package> Loading Loading @@ -3663,7 +3671,8 @@ public class PackageManagerService extends IPackageManager.Stub { return false; return false; } } final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, redirectionsPath, sharedGid) != 0) { if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, redirectionsPath, sharedGid, getPackageHashCode(pkg), getPackageHashCode(opkg)) != 0) { Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath); Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath); return false; return false; } } Loading Loading @@ -5571,8 +5580,8 @@ public class PackageManagerService extends IPackageManager.Stub { } } /** /** * Compares the last modified time of the target and overlay to those stored * Compares the 32 bit hash of the target and overlay to those stored * in the idmap and returns true if either time differs * in the idmap and returns true if either hash differs * @param targetPkg * @param targetPkg * @param overlayPkg * @param overlayPkg * @return * @return Loading @@ -5582,23 +5591,22 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.Package overlayPkg) { PackageParser.Package overlayPkg) { if (targetPkg == null || overlayPkg == null) return false; if (targetPkg == null || overlayPkg == null) return false; int targetHash = getPackageHashCode(targetPkg); int overlayHash = getPackageHashCode(overlayPkg); File idmap = new File(getIdmapPath(targetPkg, overlayPkg)); File idmap = new File(getIdmapPath(targetPkg, overlayPkg)); if (!idmap.exists()) if (!idmap.exists()) return true; return true; int[] mtimes; int[] hashes; try { try { mtimes = getIdmapTimes(idmap); hashes = getIdmapHashes(idmap); } catch (IOException e) { } catch (IOException e) { return true; return true; } } File f = new File(targetPkg.mPath); if ((int)(f.lastModified() / 1000) != mtimes[0]) { return true; } f = new File(overlayPkg.mPath); if (targetHash == 0 || overlayHash == 0 || if ((int)(f.lastModified() / 1000) != mtimes[1]) { targetHash != hashes[0] || overlayHash != hashes[1]) { return true; return true; } } return false; return false; Loading @@ -5610,7 +5618,7 @@ public class PackageManagerService extends IPackageManager.Stub { * @return * @return * @throws IOException * @throws IOException */ */ private int[] getIdmapTimes(File idmap) throws IOException { private int[] getIdmapHashes(File idmap) throws IOException { int[] times = new int[2]; int[] times = new int[2]; ByteBuffer bb = ByteBuffer.allocate(20); ByteBuffer bb = ByteBuffer.allocate(20); bb.order(ByteOrder.LITTLE_ENDIAN); bb.order(ByteOrder.LITTLE_ENDIAN); Loading @@ -5624,6 +5632,39 @@ public class PackageManagerService extends IPackageManager.Stub { return times; return times; } } /** * Get a 32 bit hashcode for the given package. * @param pkg * @return */ private int getPackageHashCode(PackageParser.Package pkg) { Pair<Integer, Long> p = mPackageHashes.get(pkg.packageName); if (p != null && (System.currentTimeMillis() - p.second < PACKAGE_HASH_EXPIRATION)) { return p.first; } if (p != null) { mPackageHashes.remove(p); } byte[] md5 = getFileMd5Sum(pkg.mPath); if (md5 == null) return 0; p = new Pair(Arrays.hashCode(md5), System.currentTimeMillis()); mPackageHashes.put(pkg.packageName, p); return p.first; } private byte[] getFileMd5Sum(String path) { try { MessageDigest md = MessageDigest.getInstance("MD5"); DigestInputStream dis = new DigestInputStream(new FileInputStream(path), md); dis.close(); return md.digest(); } catch (Exception e) { } return null; } private void setUpCustomResolverActivity(PackageParser.Package pkg) { private void setUpCustomResolverActivity(PackageParser.Package pkg) { synchronized (mPackages) { synchronized (mPackages) { mResolverReplaced = true; mResolverReplaced = true; Loading