Merge "Save OwnerInfo so CryptKeeper can display at boot time"
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 4180860..2ef5b66 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -713,10 +713,9 @@
             public void clearPassword() throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
-                String _result;
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_clearPassword, _data, _reply, 0);
+                    mRemote.transact(Stub.TRANSACTION_clearPassword, _data, _reply, IBinder.FLAG_ONEWAY);
                     _reply.readException();
                 } finally {
                     _reply.recycle();
@@ -724,6 +723,38 @@
                 }
             }
 
+            public void setField(String field, String data) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(field);
+                    _data.writeString(data);
+                    mRemote.transact(Stub.TRANSACTION_setField, _data, _reply, IBinder.FLAG_ONEWAY);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            public String getField(String field) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                String _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(field);
+                    mRemote.transact(Stub.TRANSACTION_getField, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readString();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
             public StorageVolume[] getVolumeList() throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
@@ -882,6 +913,10 @@
 
         static final int TRANSACTION_clearPassword = IBinder.FIRST_CALL_TRANSACTION + 37;
 
+        static final int TRANSACTION_setField = IBinder.FIRST_CALL_TRANSACTION + 38;
+
+        static final int TRANSACTION_getField = IBinder.FIRST_CALL_TRANSACTION + 39;
+
         /**
          * Cast an IBinder object into an IMountService interface, generating a
          * proxy if needed.
@@ -1255,6 +1290,22 @@
                     reply.writeNoException();
                     return true;
                 }
+                case TRANSACTION_setField: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String field = data.readString();
+                    String contents = data.readString();
+                    setField(field, contents);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_getField: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String field = data.readString();
+                    String contents = getField(field);
+                    reply.writeNoException();
+                    reply.writeString(contents);
+                    return true;
+                }
             }
             return super.onTransact(code, data, reply, flags);
         }
@@ -1504,4 +1555,18 @@
      * Securely clear password from vold
      */
     public void clearPassword() throws RemoteException;
+
+    /**
+     * Set a field in the crypto header.
+     * @param field field to set
+     * @param contents contents to set in field
+     */
+    public void setField(String field, String contents) throws RemoteException;
+
+    /**
+     * Gets a field from the crypto header.
+     * @param field field to get
+     * @return contents of field
+     */
+    public String getField(String field) throws RemoteException;
 }
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index b9bc54d..4504910 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -564,12 +564,37 @@
         }
     }
 
+    private void updateCryptoUserInfo() {
+        int userId = getCurrentOrCallingUserId();
+        if (userId != UserHandle.USER_OWNER) {
+            return;
+        }
+
+        final String ownerInfo = isOwnerInfoEnabled() ? getOwnerInfo(userId) : "";
+
+        IBinder service = ServiceManager.getService("mount");
+        if (service == null) {
+            Log.e(TAG, "Could not find the mount service to update the user info");
+            return;
+        }
+
+        IMountService mountService = IMountService.Stub.asInterface(service);
+        try {
+            Log.d(TAG, "Setting owner info");
+            mountService.setField("OwnerInfo", ownerInfo);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error changing user info", e);
+        }
+    }
+
     public void setOwnerInfo(String info, int userId) {
         setString(LOCK_SCREEN_OWNER_INFO, info, userId);
+        updateCryptoUserInfo();
     }
 
     public void setOwnerInfoEnabled(boolean enabled) {
         setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled);
+        updateCryptoUserInfo();
     }
 
     public String getOwnerInfo(int userId) {
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index c1d9fbd..b6e761c 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -158,6 +158,7 @@
         public static final int VolumeListResult               = 110;
         public static final int AsecListResult                 = 111;
         public static final int StorageUsersListResult         = 112;
+        public static final int CryptfsGetfieldResult          = 113;
 
         /*
          * 200 series - Requestion action has been successfully completed.
@@ -2251,6 +2252,49 @@
         }
     }
 
+    /**
+     * Set a field in the crypto header.
+     * @param field field to set
+     * @param contents contents to set in field
+     */
+    @Override
+    public void setField(String field, String contents) throws RemoteException {
+
+        waitForReady();
+
+        final NativeDaemonEvent event;
+        try {
+            event = mConnector.execute("cryptfs", "setfield", field, contents);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    /**
+     * Gets a field from the crypto header.
+     * @param field field to get
+     * @return contents of field
+     */
+    @Override
+    public String getField(String field) throws RemoteException {
+
+        waitForReady();
+
+        final NativeDaemonEvent event;
+        try {
+            final String[] contents = NativeDaemonEvent.filterMessageList(
+                    mConnector.executeForList("cryptfs", "getfield", field),
+                    VoldResponseCode.CryptfsGetfieldResult);
+            String result = new String();
+            for (String content : contents) {
+                result += content;
+            }
+            return result;
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
     @Override
     public String getPassword() throws RemoteException {
         if (!isReady()) {