Encrypted File Systems Project. Installer modifications.
Started to modify isntaller for data redirection to a secure location.
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 5ed2d35..9f01c61 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -122,6 +122,8 @@
 
     private static final boolean GET_CERTIFICATES = true;
 
+    private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
+
     private static final int REMOVE_EVENTS =
         FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
     private static final int ADD_EVENTS =
@@ -160,6 +162,10 @@
     // This is where all application persistent data goes.
     final File mAppDataDir;
 
+    // If Encrypted File System feature is enabled, all application persistent data
+    // should go here instead.
+    final File mSecureAppDataDir;
+
     // This is the object monitoring the framework dir.
     final FileObserver mFrameworkInstallObserver;
 
@@ -422,6 +428,7 @@
             
             File dataDir = Environment.getDataDirectory();
             mAppDataDir = new File(dataDir, "data");
+            mSecureAppDataDir = new File(dataDir, "secure/data");
             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
 
             if (mInstaller == null) {
@@ -431,6 +438,7 @@
                 File miscDir = new File(dataDir, "misc");
                 miscDir.mkdirs();
                 mAppDataDir.mkdirs();
+                mSecureAppDataDir.mkdirs();
                 mDrmAppPrivateInstallDir.mkdirs();
             }
 
@@ -573,7 +581,7 @@
                 mAppInstallDir.mkdirs(); // scanDirLI() assumes this dir exists
             }
             //look for any incomplete package installations
-            ArrayList<String> deletePkgsList = mSettings.getListOfIncompleteInstallPackages();
+            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackages();
             //clean up list
             for(int i = 0; i < deletePkgsList.size(); i++) {
                 //clean up here
@@ -628,20 +636,20 @@
         }
     }
 
-    void cleanupInstallFailedPackage(String packageName) {
+    void cleanupInstallFailedPackage(PackageSetting pkgSettings) {
         if (mInstaller != null) {
-            int retCode = mInstaller.remove(packageName);
+            boolean useSecureFS = useEncryptedFilesystemForPackage(pkgSettings.pkg);
+            int retCode = mInstaller.remove(pkgSettings.name, useSecureFS);
             if (retCode < 0) {
                 Log.w(TAG, "Couldn't remove app data directory for package: "
-                           + packageName + ", retcode=" + retCode);
+                           + pkgSettings.name + ", retcode=" + retCode);
             }
         } else {
             //for emulator
-            PackageParser.Package pkg = mPackages.get(packageName);
-            File dataDir = new File(pkg.applicationInfo.dataDir);
+            File dataDir = new File(pkgSettings.pkg.applicationInfo.dataDir);
             dataDir.delete();
         }
-        mSettings.removePackageLP(packageName);
+        mSettings.removePackageLP(pkgSettings.name);
     }
 
     void readPermissions() {
@@ -2155,6 +2163,11 @@
         
         return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
     }
+
+    private static boolean useEncryptedFilesystemForPackage(PackageParser.Package pkg) {
+        return Environment.isEncryptedFilesystemEnabled() &&
+                ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_NEVER_ENCRYPT) == 0);
+    }
     
     private PackageParser.Package scanPackageLI(
         File scanFile, File destCodeFile, File destResourceFile,
@@ -2364,8 +2377,9 @@
         }
 
         if (removeExisting) {
+            boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
             if (mInstaller != null) {
-                int ret = mInstaller.remove(pkgName);
+                int ret = mInstaller.remove(pkgName, useEncryptedFSDir);
                 if (ret != 0) {
                     String msg = "System package " + pkg.packageName
                             + " could not have data directory erased after signature change.";
@@ -2395,7 +2409,12 @@
             pkg.applicationInfo.dataDir = dataPath.getPath();
         } else {
             // This is a normal package, need to make its data directory.
-            dataPath = new File(mAppDataDir, pkgName);
+            boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
+            if (useEncryptedFSDir) {
+                dataPath = new File(mSecureAppDataDir, pkgName);
+            } else {
+                dataPath = new File(mAppDataDir, pkgName);
+            }
             if (dataPath.exists()) {
                 mOutPermissions[1] = 0;
                 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
@@ -2408,7 +2427,7 @@
                         // If this is a system app, we can at least delete its
                         // current data so the application will still work.
                         if (mInstaller != null) {
-                            int ret = mInstaller.remove(pkgName);
+                            int ret = mInstaller.remove(pkgName, useEncryptedFSDir);
                             if(ret >= 0) {
                                 // Old data gone!
                                 String msg = "System package " + pkg.packageName
@@ -2419,7 +2438,7 @@
                                 recovered = true;
                                 
                                 // And now re-install the app.
-                                ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
+                                ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid,
                                         pkg.applicationInfo.uid);
                                 if (ret == -1) {
                                     // Ack should not happen!
@@ -2459,7 +2478,7 @@
                     Log.v(TAG, "Want this data dir: " + dataPath);
                 //invoke installer to do the actual installation
                 if (mInstaller != null) {
-                    int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
+                    int ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid,
                             pkg.applicationInfo.uid);
                     if(ret < 0) {
                         // Error from installer
@@ -3822,7 +3841,13 @@
             PackageParser.Package pkg, boolean forwardLocked, boolean newInstall,
             String installerPackageName, PackageInstalledInfo res) {
         // Remember this for later, in case we need to rollback this install
-        boolean dataDirExists = (new File(mAppDataDir, pkgName)).exists();
+        boolean dataDirExists;
+
+        if (useEncryptedFilesystemForPackage(pkg)) {
+            dataDirExists = (new File(mSecureAppDataDir, pkgName)).exists();
+        } else {
+            dataDirExists = (new File(mAppDataDir, pkgName)).exists();
+        }
         res.name = pkgName;
         synchronized(mPackages) {
             if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(destFilePath)) {
@@ -4552,8 +4577,9 @@
             deletedPs = mSettings.mPackages.get(packageName);
         }
         if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
+            boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
             if (mInstaller != null) {
-                int retCode = mInstaller.remove(packageName);
+                int retCode = mInstaller.remove(packageName, useEncryptedFSDir);
                 if (retCode < 0) {
                     Log.w(TAG, "Couldn't remove app data or cache directory for package: "
                                + packageName + ", retcode=" + retCode);
@@ -4795,6 +4821,8 @@
                 p = ps.pkg;
             }
         }
+        boolean useEncryptedFSDir = false;
+
         if(!dataOnly) {
             //need to check this only for fully installed applications
             if (p == null) {
@@ -4806,9 +4834,10 @@
                 Log.w(TAG, "Package " + packageName + " has no applicationInfo.");
                 return false;
             }
+            useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
         }
         if (mInstaller != null) {
-            int retCode = mInstaller.clearUserData(packageName);
+            int retCode = mInstaller.clearUserData(packageName, useEncryptedFSDir);
             if (retCode < 0) {
                 Log.w(TAG, "Couldn't remove cache files for package: "
                         + packageName);
@@ -4859,8 +4888,9 @@
             Log.w(TAG, "Package " + packageName + " has no applicationInfo.");
             return false;
         }
+        boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
         if (mInstaller != null) {
-            int retCode = mInstaller.deleteCacheFiles(packageName);
+            int retCode = mInstaller.deleteCacheFiles(packageName, useEncryptedFSDir);
             if (retCode < 0) {
                 Log.w(TAG, "Couldn't remove cache files for package: "
                            + packageName);
@@ -4922,9 +4952,10 @@
             }
             publicSrcDir = isForwardLocked(p) ? applicationInfo.publicSourceDir : null;
         }
+        boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
         if (mInstaller != null) {
             int res = mInstaller.getSizeInfo(packageName, p.mPath,
-                    publicSrcDir, pStats);
+                    publicSrcDir, pStats, useEncryptedFSDir);
             if (res < 0) {
                 return false;
             } else {
@@ -6132,11 +6163,18 @@
         Settings() {
             File dataDir = Environment.getDataDirectory();
             File systemDir = new File(dataDir, "system");
+            // TODO(oam): This secure dir creation needs to be moved somewhere else (later)
+            File systemSecureDir = new File(dataDir, "secure/system");
             systemDir.mkdirs();
+            systemSecureDir.mkdirs();
             FileUtils.setPermissions(systemDir.toString(),
                     FileUtils.S_IRWXU|FileUtils.S_IRWXG
                     |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                     -1, -1);
+            FileUtils.setPermissions(systemSecureDir.toString(),
+                    FileUtils.S_IRWXU|FileUtils.S_IRWXG
+                    |FileUtils.S_IROTH|FileUtils.S_IXOTH,
+                    -1, -1);
             mSettingsFilename = new File(systemDir, "packages.xml");
             mBackupSettingsFilename = new File(systemDir, "packages-backup.xml");
         }
@@ -6807,15 +6845,15 @@
             return mReadMessages.toString();
         }
 
-        ArrayList<String> getListOfIncompleteInstallPackages() {
+        ArrayList<PackageSetting> getListOfIncompleteInstallPackages() {
             HashSet<String> kList = new HashSet<String>(mPackages.keySet());
             Iterator<String> its = kList.iterator();
-            ArrayList<String> ret = new ArrayList<String>();
+            ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
             while(its.hasNext()) {
                 String key = its.next();
                 PackageSetting ps = mPackages.get(key);
                 if(ps.getInstallStatus() == PKG_INSTALL_INCOMPLETE) {
-                    ret.add(key);
+                    ret.add(ps);
                 }
             }
             return ret;