Fix 2579461
Move install location values to secure settings.
Diable attribute for UI. Set default value to auto.
Add command line interface to set install location via pm.

Change-Id: I80e97b3d24845adad7102f40dcbe238f00efa406
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 659d70f..9b8b0ac 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -16,6 +16,8 @@
 
 package com.android.commands.pm;
 
+import com.android.internal.content.PackageHelper;
+
 import android.content.ComponentName;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.FeatureInfo;
@@ -33,6 +35,7 @@
 import android.net.Uri;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.provider.Settings;
 
 import java.io.File;
 import java.lang.reflect.Field;
@@ -107,6 +110,16 @@
             return;
         }
 
+        if ("setInstallLocation".equals(op)) {
+            runSetInstallLocation();
+            return;
+        }
+
+        if ("getInstallLocation".equals(op)) {
+            runGetInstallLocation();
+            return;
+        }
+
         try {
             if (args.length == 1) {
                 if (args[0].equalsIgnoreCase("-l")) {
@@ -575,6 +588,51 @@
         return Integer.toString(result);
     }
 
+    private void runSetInstallLocation() {
+        int loc;
+
+        String arg = nextArg();
+        if (arg == null) {
+            System.err.println("Error: no install location specified.");
+            showUsage();
+            return;
+        }
+        try {
+            loc = Integer.parseInt(arg);
+        } catch (NumberFormatException e) {
+            System.err.println("Error: install location has to be a number.");
+            showUsage();
+            return;
+        }
+        try {
+            if (!mPm.setInstallLocation(loc)) {
+                System.err.println("Error: install location has to be a number.");
+                showUsage();
+            }
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(PM_NOT_RUNNING_ERR);
+        }
+    }
+
+    private void runGetInstallLocation() {
+        try {
+            int loc = mPm.getInstallLocation();
+            String locStr = "invalid";
+            if (loc == PackageHelper.APP_INSTALL_AUTO) {
+                locStr = "auto";
+            } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
+                locStr = "internal";
+            } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
+                locStr = "external";
+            }
+            System.out.println(loc + "[" + locStr + "]");
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(PM_NOT_RUNNING_ERR);
+        }
+    }
+
     private void runInstall() {
         int installFlags = 0;
         String installerPackageName = null;
@@ -832,6 +890,7 @@
         System.err.println("       pm uninstall [-k] PACKAGE");
         System.err.println("       pm enable PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable PACKAGE_OR_COMPONENT");
+        System.err.println("       pm setInstallLocation [0/auto] [1/internal] [2/external]");
         System.err.println("");
         System.err.println("The list packages command prints all packages.  Options:");
         System.err.println("  -f: see their associated file.");
@@ -867,10 +926,17 @@
         System.err.println("  -k: keep the data and cache directories around.");
         System.err.println("after the package removal.");
         System.err.println("");
-        System.err.println("The mountsd command simulates mounting/unmounting sdcard.Options:");
-        System.err.println("  -m: true or false.");
-        System.err.println("");
         System.err.println("The enable and disable commands change the enabled state of");
         System.err.println("a given package or component (written as \"package/class\").");
+        System.err.println("");
+        System.err.println("The getInstallLocation command gets the current install location");
+        System.err.println("  0 [auto]: Let system decide the best location");
+        System.err.println("  1 [internal]: Install on internal device storage");
+        System.err.println("  2 [external]: Install on external media");
+        System.err.println("");
+        System.err.println("The setInstallLocation command changes the default install location");
+        System.err.println("  0 [auto]: Let system decide the best location");
+        System.err.println("  1 [internal]: Install on internal device storage");
+        System.err.println("  2 [external]: Install on external media");
     }
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index f90ef63..9939478 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -316,4 +316,7 @@
     void movePackage(String packageName, IPackageMoveObserver observer, int flags);
     
     boolean addPermissionAsync(in PermissionInfo info);
+
+    boolean setInstallLocation(int loc);
+    int getInstallLocation();
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b8e5747..c07ac31 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1611,21 +1611,6 @@
         public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";
 
         /**
-         * Let user pick default install location.
-         * @hide
-         */
-        public static final String SET_INSTALL_LOCATION = "set_install_location";
-
-        /**
-         * Default install location value.
-         * 0 = auto, let system decide
-         * 1 = internal
-         * 2 = sdcard
-         * @hide
-         */
-        public static final String DEFAULT_INSTALL_LOCATION = "default_install_location";
-
-        /**
          * Show pointer location on screen?
          * 0 = no
          * 1 = yes
@@ -3295,6 +3280,21 @@
          * @hide
          */
         public static final String UI_NIGHT_MODE = "ui_night_mode";
+
+        /**
+         * Let user pick default install location.
+         * @hide
+         */
+        public static final String SET_INSTALL_LOCATION = "set_install_location";
+
+        /**
+         * Default install location value.
+         * 0 = auto, let system decide
+         * 1 = internal
+         * 2 = sdcard
+         * @hide
+         */
+        public static final String DEFAULT_INSTALL_LOCATION = "default_install_location";
         
         /**
          * @hide
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 152f02e..7fa64ca 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -328,14 +328,14 @@
         boolean checkSd = false;
         int setLoc = 0;
         try {
-            setLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION);
+            setLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.SET_INSTALL_LOCATION);
         } catch (SettingNotFoundException e) {
             failStr(e);
         }
         if (setLoc == 1) {
             int userPref = APP_INSTALL_AUTO;
             try {
-                userPref = Settings.System.getInt(mContext.getContentResolver(), Settings.System.DEFAULT_INSTALL_LOCATION);
+                userPref = Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.DEFAULT_INSTALL_LOCATION);
             } catch (SettingNotFoundException e) {
                 failStr(e);
             }
@@ -1302,8 +1302,8 @@
         boolean userSetting = false;
         int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO;
         try {
-            userSetting = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION) != 0;
-            origDefaultLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.System.DEFAULT_INSTALL_LOCATION);
+            userSetting = Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.SET_INSTALL_LOCATION) != 0;
+            origDefaultLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.DEFAULT_INSTALL_LOCATION);
         } catch (SettingNotFoundException e1) {
         }
         return origDefaultLoc;
@@ -1311,7 +1311,7 @@
 
     private void setInstallLoc(int loc) {
         Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.DEFAULT_INSTALL_LOCATION, loc);
+                Settings.Secure.DEFAULT_INSTALL_LOCATION, loc);
     }
     /*
      * Tests for moving apps between internal and external storage
@@ -1963,7 +1963,7 @@
     */
    private boolean getUserSettingSetInstallLocation() {
        try {
-           return Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION) != 0;
+           return Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.SET_INSTALL_LOCATION) != 0;
            
        } catch (SettingNotFoundException e1) {
        }
@@ -1972,7 +1972,7 @@
 
    private void setUserSettingSetInstallLocation(boolean value) {
        Settings.System.putInt(mContext.getContentResolver(),
-               Settings.System.SET_INSTALL_LOCATION, value ? 1 : 0);
+               Settings.Secure.SET_INSTALL_LOCATION, value ? 1 : 0);
    }
    private void setUserX(boolean enable, int userSetting, int iloc) {
        boolean origUserSetting = getUserSettingSetInstallLocation();
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 14c8806..57f9ce7 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -339,25 +339,19 @@
                 checkBoth = true;
                 break check_inner;
             }
-            // Check if user option is enabled
-            boolean setInstallLoc = Settings.System.getInt(getApplicationContext()
+            // Pick user preference
+            int installPreference = Settings.System.getInt(getApplicationContext()
                     .getContentResolver(),
-                    Settings.System.SET_INSTALL_LOCATION, 0) != 0;
-            if (setInstallLoc) {
-                // Pick user preference
-                int installPreference = Settings.System.getInt(getApplicationContext()
-                        .getContentResolver(),
-                        Settings.System.DEFAULT_INSTALL_LOCATION,
-                        PackageHelper.APP_INSTALL_AUTO);
-                if (installPreference == PackageHelper.APP_INSTALL_INTERNAL) {
-                    checkInt = true;
-                    checkBoth = true;
-                    break check_inner;
-                } else if (installPreference == PackageHelper.APP_INSTALL_EXTERNAL) {
-                    checkExt = true;
-                    checkBoth = true;
-                    break check_inner;
-                }
+                    Settings.Secure.DEFAULT_INSTALL_LOCATION,
+                    PackageHelper.APP_INSTALL_AUTO);
+            if (installPreference == PackageHelper.APP_INSTALL_INTERNAL) {
+                checkInt = true;
+                checkBoth = true;
+                break check_inner;
+            } else if (installPreference == PackageHelper.APP_INSTALL_EXTERNAL) {
+                checkExt = true;
+                checkBoth = true;
+                break check_inner;
             }
             // Fall back to default policy if nothing else is specified.
             checkInt = true;
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 34302c4..185d72a9 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -56,10 +56,6 @@
     <bool name="def_mount_ums_autostart">false</bool>
     <bool name="def_mount_ums_prompt">true</bool>
     <bool name="def_mount_ums_notify_enabled">true</bool>
-    <!-- Enable User preference for setting install location -->
-    <bool name="set_install_location">true</bool>
-    <!-- Default install location if user preference for setting install location is turned on. -->
-    <integer name="def_install_location">2</integer>
 
     <!-- user interface sound effects -->
     <integer name="def_power_sounds_enabled">1</integer>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index d0e9dd9..0c0bf93 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -39,6 +39,8 @@
 import android.util.Config;
 import android.util.Log;
 import android.util.Xml;
+
+import com.android.internal.content.PackageHelper;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
@@ -61,7 +63,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 55;
+    private static final int DATABASE_VERSION = 56;
 
     private Context mContext;
 
@@ -608,21 +610,8 @@
 
        if (upgradeVersion == 50) {
            /*
-            * New settings for set install location UI.
+            * Install location no longer initiated here.
             */
-           db.beginTransaction();
-           SQLiteStatement stmt = null;
-           try {
-                stmt = db.compileStatement("INSERT INTO system(name,value)"
-                        + " VALUES(?,?);");
-                loadBooleanSetting(stmt, Settings.System.SET_INSTALL_LOCATION,
-                        R.bool.set_install_location);
-                db.setTransactionSuccessful();
-            } finally {
-                db.endTransaction();
-                if (stmt != null) stmt.close();
-            }
-
            upgradeVersion = 51;
        }
 
@@ -663,21 +652,8 @@
         
         if (upgradeVersion == 53) {
             /*
-             * New settings for set install location UI.
+             * New settings for set install location UI no longer initiated here.
              */
-            db.beginTransaction();
-            SQLiteStatement stmt = null;
-            try {
-                 stmt = db.compileStatement("INSERT INTO system(name,value)"
-                         + " VALUES(?,?);");
-                 loadIntegerSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
-                         R.integer.def_install_location);
-                 db.setTransactionSuccessful();
-             } finally {
-                 db.endTransaction();
-                 if (stmt != null) stmt.close();
-             }
-
             upgradeVersion = 54;
         }
 
@@ -696,6 +672,28 @@
             upgradeVersion = 55;
         }
 
+        if (upgradeVersion == 55) {
+            /* Move the install location settings. */
+            String[] settingsToMove = {
+                    Secure.SET_INSTALL_LOCATION,
+                    Secure.DEFAULT_INSTALL_LOCATION
+            };
+            moveFromSystemToSecure(db, settingsToMove);
+            db.beginTransaction();
+            SQLiteStatement stmt = null;
+            try {
+                stmt = db.compileStatement("INSERT INTO system(name,value)"
+                        + " VALUES(?,?);");
+                loadSetting(stmt, Secure.SET_INSTALL_LOCATION, 0);
+                loadSetting(stmt, Secure.DEFAULT_INSTALL_LOCATION,
+                        PackageHelper.APP_INSTALL_AUTO);
+                db.setTransactionSuccessful();
+             } finally {
+                 db.endTransaction();
+                 if (stmt != null) stmt.close();
+             }
+            upgradeVersion = 56;
+        }
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -1021,10 +1019,9 @@
     
             loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
                     R.bool.def_notification_pulse);
-            loadBooleanSetting(stmt, Settings.System.SET_INSTALL_LOCATION,
-                    R.bool.set_install_location);
-            loadIntegerSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
-                    R.integer.def_install_location);
+            loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
+            loadSetting(stmt, Settings.Secure.DEFAULT_INSTALL_LOCATION,
+                    PackageHelper.APP_INSTALL_AUTO);
     
             loadUISoundEffectsSettings(stmt);
     
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 95dbf3c..0a30816 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -31,8 +31,8 @@
 import android.app.IActivityManager;
 import android.app.admin.IDevicePolicyManager;
 import android.app.backup.IBackupManager;
-import android.content.ComponentName;
 import android.content.Context;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
@@ -83,6 +83,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.provider.Settings;
 import android.security.SystemKeyStore;
 import android.util.*;
 import android.view.Display;
@@ -9821,5 +9822,26 @@
            }
        });
    }
+
+   public boolean setInstallLocation(int loc) {
+       mContext.enforceCallingOrSelfPermission(
+               android.Manifest.permission.WRITE_SECURE_SETTINGS, null);
+       if (getInstallLocation() == loc) {
+           return true;
+       }
+       if (loc == PackageHelper.APP_INSTALL_AUTO ||
+               loc == PackageHelper.APP_INSTALL_INTERNAL ||
+               loc == PackageHelper.APP_INSTALL_EXTERNAL) {
+           android.provider.Settings.System.putInt(mContext.getContentResolver(),
+                   android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION, loc);
+           return true;
+       }
+       return false;
+   }
+
+   public int getInstallLocation() {
+       return android.provider.Settings.System.getInt(mContext.getContentResolver(),
+               android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION, PackageHelper.APP_INSTALL_AUTO);
+   }
 }