OSDN Git Service

framework: houdini hook and native activity hook rebase on KK
[android-x86/frameworks-base.git] / services / java / com / android / server / pm / PackageManagerService.java
index dc63ca2..8c3f383 100755 (executable)
@@ -138,6 +138,7 @@ import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FilenameFilter;
 import java.io.IOException;
+import java.io.ObjectOutputStream;
 import java.io.PrintWriter;
 import java.security.NoSuchAlgorithmException;
 import java.security.PublicKey;
@@ -189,6 +190,8 @@ public class PackageManagerService extends IPackageManager.Stub {
     private static final boolean DEBUG_PACKAGE_SCANNING = false;
     private static final boolean DEBUG_APP_DIR_OBSERVER = false;
     private static final boolean DEBUG_VERIFY = false;
+    private static final boolean ENABLE_HOUDINI = Build.CPU_ABI.equals("x86") &&
+            (Build.CPU_ABI2.length()!=0);
 
     private static final int RADIO_UID = Process.PHONE_UID;
     private static final int LOG_UID = Process.LOG_UID;
@@ -507,6 +510,11 @@ public class PackageManagerService extends IPackageManager.Stub {
     // or internal storage.
     private IMediaContainerService mContainerService = null;
 
+    // Packages that have been installed with library matching 2nd ABI.
+    final HashMap<Integer, String> mPackagesMatchABI2 = new HashMap<Integer,String>();
+    // Packages that have been installed with library matching 2nd ABI and matching neon app list
+    final HashMap<Integer, String> mPackagesMatchABI2Neon = new HashMap<Integer,String>();
+
     static final int SEND_PENDING_BROADCAST = 1;
     static final int MCS_BOUND = 3;
     static final int END_COPY = 4;
@@ -3976,6 +3984,53 @@ public class PackageManagerService extends IPackageManager.Stub {
         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
     }
 
+    private void writeAppwithABI2Internal(String fileName, HashMap<Integer, String> map) {
+        File outputFile;
+        FileOutputStream out = null;
+        File appDataDir = new File("/data/data");
+
+        try {
+            File tempFile = File.createTempFile("tmp", "tmp", appDataDir);
+            String tempFilePath = tempFile.getPath();
+            outputFile = new File(fileName);
+            if (FileUtils.setPermissions(tempFilePath,
+                    FileUtils.S_IRUSR | FileUtils.S_IWUSR |
+                    FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1) != 0
+                    || !tempFile.renameTo(outputFile)) {
+                tempFile.delete();
+            }
+            out = new FileOutputStream(outputFile);
+            Iterator<HashMap.Entry<Integer, String>>
+            it = map.entrySet().iterator();
+            while (it.hasNext()) {
+                HashMap.Entry<Integer, String> ent = it.next();
+                int userID = ent.getKey().intValue();
+                out.write(userID & 0xff);
+                out.write((userID>>8)  & 0xff);
+                out.write((userID>>16) & 0xff);
+                out.write((userID>>24) & 0xff);
+                Slog.i(TAG, "Data written:"+ userID);
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "File Access Error: Not Able to write Data into " + fileName);
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                    Slog.i(TAG, "Data written into " + fileName);
+                }
+            } catch (IOException e) {}
+        }
+    }
+
+    private void writeAppwithABI2() {
+        writeAppwithABI2Internal(new String("/data/data/.appwithABI2"), mPackagesMatchABI2);
+    }
+
+    private void writeAppwithABI2Neon() {
+        writeAppwithABI2Internal(new String("/data/data/.appwithABI2neon"), mPackagesMatchABI2Neon);
+    }
+
     private File getDataPathForPackage(String packageName, int userId) {
         /*
          * Until we fully support multiple users, return the directory we
@@ -4303,6 +4358,25 @@ public class PackageManagerService extends IPackageManager.Stub {
                 Slog.w(TAG, "Package " + pkg.packageName
                         + " was transferred to another, but its .apk remains");
             }
+
+            if (ENABLE_HOUDINI) {
+                PackageSetting p = mSettings.mPackages.get(pkg.packageName);
+                if ((p != null) && (!p.codePath.equals(destCodeFile))) {
+
+                   // Already existing package. Make sure not upgrade to black list
+                    int result = NativeLibraryHelper.listNativeBinariesLI(scanFile);
+
+                    if (result == PackageManager.INSTALL_ABI2_SUCCEEDED) {
+                        ICheckExt check = new CheckExt();
+                        if(check.doCheck(pkg.packageName, new String("filter"))) {
+                            Slog.i(TAG, "Reject application in black list::" + pkg.packageName);
+                            mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
+                            return null;
+                        }
+                    }
+
+                }
+            }
             
             // Just create the setting, don't add it yet. For already existing packages
             // the PkgSetting exists already and doesn't have to be created.
@@ -4608,10 +4682,21 @@ public class PackageManagerService extends IPackageManager.Stub {
                         }
 
                         try {
-                            if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
-                                Slog.e(TAG, "Unable to copy native libraries");
-                                mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
-                                return null;
+                            int copyRet = copyNativeLibrariesForInternalApp(scanFile,
+                                    nativeLibraryDir);
+                            if (ENABLE_HOUDINI) {
+                                if (copyRet != PackageManager.INSTALL_SUCCEEDED
+                                        && copyRet != PackageManager.INSTALL_ABI2_SUCCEEDED) {
+                                    Slog.e(TAG, "Unable to copy native libraries");
+                                    mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+                                    return null;
+                                }
+                            } else {
+                                if (copyRet != 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);
@@ -4620,6 +4705,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                         }
                     }
 
+
                     if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
                     final int[] userIds = sUserManager.getUserIds();
                     synchronized (mInstallLock) {
@@ -4634,6 +4720,40 @@ public class PackageManagerService extends IPackageManager.Stub {
                         }
                     }
                 }
+
+                // Check the apk to see whether it contains ABI2 library.
+                int result = NativeLibraryHelper.listNativeBinariesLI(scanFile);
+                if (result == PackageManager.INSTALL_SUCCEEDED) {
+                    if (ENABLE_HOUDINI && mPackagesMatchABI2.containsKey(pkg.applicationInfo.uid)) {
+                        Slog.i(TAG, "Replace package with primary ABI Library");
+                        mPackagesMatchABI2.remove(pkg.applicationInfo.uid);
+                        writeAppwithABI2();
+                        if (mPackagesMatchABI2Neon.containsKey(pkg.applicationInfo.uid)) {
+                            mPackagesMatchABI2Neon.remove(pkg.applicationInfo.uid);
+                            writeAppwithABI2Neon();
+                        }
+                    }
+                } else if (ENABLE_HOUDINI && result == PackageManager.INSTALL_ABI2_SUCCEEDED
+                        && !mPackagesMatchABI2.containsKey(pkg.applicationInfo.uid)) {
+                    ICheckExt check = new CheckExt();
+                    if (check.doCheck(pkgName, new String("filter"))) {
+                        Slog.i(TAG, "Package with second ABI is in black list: "
+                                + pkg.applicationInfo.uid + pkg.applicationInfo.processName);
+                        mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
+                        return null;
+                    }
+                    Slog.i(TAG, "Package installed with second ABI Library: "
+                            + pkg.applicationInfo.uid + pkg.applicationInfo.processName);
+                    mPackagesMatchABI2.put(pkg.applicationInfo.uid,
+                            pkg.applicationInfo.processName);
+                    writeAppwithABI2();
+                    if (check.doCheck(pkgName, new String("neon"))) {
+                        mPackagesMatchABI2Neon.put(pkg.applicationInfo.uid,
+                                pkg.applicationInfo.processName);
+                        writeAppwithABI2Neon();
+                    }
+                }
+
             } catch (IOException ioe) {
                 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
             }
@@ -5176,6 +5296,18 @@ public class PackageManagerService extends IPackageManager.Stub {
             final PackageParser.Package pkg = ps.pkg;
             if (pkg != null) {
                 cleanPackageDataStructuresLILPw(pkg, chatty);
+
+                Integer pkgUidInt = new Integer(pkg.applicationInfo.uid);
+                if (ENABLE_HOUDINI && mPackagesMatchABI2.containsKey(pkgUidInt)) {
+                    Slog.i(TAG, "Uninstall package with second ABI Library");
+                    mPackagesMatchABI2.remove(pkgUidInt);
+                    writeAppwithABI2();
+                    if (mPackagesMatchABI2Neon.containsKey(pkgUidInt)) {
+                        mPackagesMatchABI2Neon.remove(pkgUidInt);
+                        writeAppwithABI2Neon();
+                    }
+                }
+
             }
         }
     }
@@ -5193,6 +5325,18 @@ public class PackageManagerService extends IPackageManager.Stub {
                 mAppDirs.remove(pkg.mPath);
             }
             cleanPackageDataStructuresLILPw(pkg, chatty);
+
+            if (ENABLE_HOUDINI && mPackagesMatchABI2.containsKey(new
+                    Integer(pkg.applicationInfo.uid))) {
+                Slog.i(TAG, "Uninstall package with second ABI Library");
+                mPackagesMatchABI2.remove(new Integer(pkg.applicationInfo.uid));
+                writeAppwithABI2();
+                if (mPackagesMatchABI2Neon.containsKey(new Integer(pkg.applicationInfo.uid))) {
+                    mPackagesMatchABI2Neon.remove(new Integer(pkg.applicationInfo.uid));
+                    writeAppwithABI2Neon();
+                }
+            }
+
         }
     }
 
@@ -8030,8 +8174,15 @@ public class PackageManagerService extends IPackageManager.Stub {
             }
             try {
                 int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
-                if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
-                    return copyRet;
+                if (ENABLE_HOUDINI) {
+                    if (copyRet != PackageManager.INSTALL_SUCCEEDED
+                            && copyRet != PackageManager.INSTALL_ABI2_SUCCEEDED) {
+                        return copyRet;
+                    }
+                } else {
+                    if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
+                        return copyRet;
+                    }
                 }
             } catch (IOException e) {
                 Slog.e(TAG, "Copying native libraries failed", e);