Add a method enable encryption.

This is for testing and needs to be cleaned up.

Change-Id: I71cd5412f7096dc13d9ab61229ee9846c6f0006a
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 23ed31f..b9d4711 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -603,6 +603,23 @@
                 }
                 return _result;
             }
+
+            public int encryptStorage(String password) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(password);
+                    mRemote.transact(Stub.TRANSACTION_encryptStorage, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
         }
 
         private static final String DESCRIPTOR = "IMountService";
@@ -661,6 +678,8 @@
 
         static final int TRANSACTION_decryptStorage = IBinder.FIRST_CALL_TRANSACTION + 26;
 
+        static final int TRANSACTION_encryptStorage = IBinder.FIRST_CALL_TRANSACTION + 27;
+
         /**
          * Cast an IBinder object into an IMountService interface, generating a
          * proxy if needed.
@@ -950,6 +969,14 @@
                     reply.writeInt(result);
                     return true;
                 }
+                case TRANSACTION_encryptStorage: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String password = data.readString();
+                    int result = encryptStorage(password);
+                    reply.writeNoException();
+                    reply.writeInt(result);
+                    return true;
+                }
             }
             return super.onTransact(code, data, reply, flags);
         }
@@ -1114,4 +1141,9 @@
      * Decrypts any encrypted volumes.
      */
     public int decryptStorage(String password) throws RemoteException;
+
+    /**
+     * Encrypts storage.
+     */
+    public int encryptStorage(String password) throws RemoteException;
 }
diff --git a/include/storage/IMountService.h b/include/storage/IMountService.h
index 68ccd95..472d8e5 100644
--- a/include/storage/IMountService.h
+++ b/include/storage/IMountService.h
@@ -67,6 +67,7 @@
     virtual bool isObbMounted(const String16& filename) = 0;
     virtual bool getMountedObbPath(const String16& filename, String16& path) = 0;
     virtual int32_t decryptStorage(const String16& password) = 0;
+    virtual int32_t encryptStorage(const String16& password) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index a7ab824..7fbf67a 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -49,6 +49,7 @@
     TRANSACTION_getMountedObbPath,
     TRANSACTION_isExternalStorageEmulated,
     TRANSACTION_decryptStorage,
+    TRANSACTION_encryptStorage,
 };
 
 class BpMountService: public BpInterface<IMountService>
@@ -505,7 +506,7 @@
         path = reply.readString16();
         return true;
     }
-    
+
     int32_t decryptStorage(const String16& password)
     {
         Parcel data, reply;
@@ -522,6 +523,23 @@
         }
         return reply.readInt32();
     }
+
+    int32_t encryptStorage(const String16& password)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(password);
+        if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) {
+            LOGD("encryptStorage could not contact remote\n");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("encryptStorage caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
 };
 
 IMPLEMENT_META_INTERFACE(MountService, "IMountService");
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index bf81457..d6804f9 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1653,6 +1653,29 @@
         return 0;
     }
 
+    public int encryptStorage(String password) {
+        if (password == null) {
+            throw new IllegalArgumentException("password cannot be null");
+        }
+
+        // TODO: Enforce a permission
+
+        waitForReady();
+
+        if (DEBUG_EVENTS) {
+            Slog.i(TAG, "decrypting storage...");
+        }
+
+        try {
+            mConnector.doCommand(String.format("cryptfs enablecrypto wipe %s", password));
+        } catch (NativeDaemonConnectorException e) {
+            // Encryption failed
+            return e.getCode();
+        }
+
+        return 0;
+    }
+
     private void addObbStateLocked(ObbState obbState) throws RemoteException {
         final IBinder binder = obbState.getBinder();
         List<ObbState> obbStates = mObbMounts.get(binder);