Halt managed provisioning if battery level is too low

This mirrors the behaviours of the encryption screen in Settings and
of the encryption process itself, namely that:

 - battery level should be at least 80%
 - the device should be plugged in

If any requirement is not satisfied the encrypt activity will stop
progress and show a warning until it is fixed.

@bug 15156177

Change-Id: Id2594daffed0e0d3d404eabce656c08112f4830f
diff --git a/res/layout/encrypt_device.xml b/res/layout/encrypt_device.xml
index cb0926d..fd20572 100644
--- a/res/layout/encrypt_device.xml
+++ b/res/layout/encrypt_device.xml
@@ -27,16 +27,36 @@
         android:layout_width="fill_parent"
         android:text="@string/encrypt_device_title"
         style="@style/UserConsentTitle"/>
-    <TextView
-        android:layout_width="fill_parent"
-        android:text="@string/encrypt_device_text"
-        style="@style/UserConsentMainText"/>
 
-    <!-- Padding -->
-    <View
-        android:layout_width="fill_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"/>
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:orientation="vertical">
+        <LinearLayout
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+            <TextView
+                android:layout_width="fill_parent"
+                android:text="@string/encrypt_device_text"
+                style="@style/UserConsentMainText"/>
+            <TextView
+                android:id="@+id/warning_low_charge"
+                android:layout_width="fill_parent"
+                android:text="@string/encrypt_device_low_charge_text"
+                android:textStyle="bold"
+                android:visibility="gone"
+                style="@style/UserConsentMainText"/>
+            <TextView
+                android:id="@+id/warning_unplugged"
+                android:layout_width="fill_parent"
+                android:text="@string/encrypt_device_unplugged_text"
+                android:textStyle="bold"
+                android:visibility="gone"
+                style="@style/UserConsentMainText"/>
+        </LinearLayout>
+    </ScrollView>
 
     <!-- Button bar -->
     <LinearLayout
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 65542ac..4dd29d8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -47,6 +47,10 @@
   <string name="encrypt_device_text">To continue, restart your device so it can be encrypted. This may take some time.</string>
   <string name="encrypt_device_confirm">Restart</string>
 
+  <!-- Warning strings that will be displayed when encryption cannot be started -->
+  <string name="encrypt_device_low_charge_text">Charge your battery and try again.</string>
+  <string name="encrypt_device_unplugged_text">Plug in your charger and try again.</string>
+
   <!-- Reminder notification to resume provisioning after device has been encrypted -->
   <string name="continue_provisioning_notify_title">Managed provisioning</string>
   <string name="continue_provisioning_notify_text">Continue with managed provisioning</string>
diff --git a/src/com/android/managedprovisioning/EncryptDeviceActivity.java b/src/com/android/managedprovisioning/EncryptDeviceActivity.java
index 373bb8d..4449b34 100644
--- a/src/com/android/managedprovisioning/EncryptDeviceActivity.java
+++ b/src/com/android/managedprovisioning/EncryptDeviceActivity.java
@@ -16,14 +16,17 @@
 package com.android.managedprovisioning;
 
 import android.app.Activity;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.Button;
 import android.widget.TextView;
 
+import android.os.BatteryManager;
 import android.os.IBinder;
 import android.os.ServiceManager;
 import android.os.storage.IMountService;
@@ -40,15 +43,48 @@
     protected static final String EXTRA_RESUME = "com.android.managedprovisioning.RESUME";
     protected static final String ENCRYPTION_ACTIVE_KEY = "encryptionActiveKey";
 
+    // Minimum battery charge level (in percent) to launch encryption.  If the battery charge is
+    // lower than this, encryption should not be activated.
+    private static final int MIN_BATTERY_LEVEL = 80;
+
+    private Button mEncryptButton;
+    private View mCableWarning;
+    private View mBatteryWarning;
+    private IntentFilter mIntentFilter;
+
+    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
+                final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+                final int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+                final int invalidCharger = intent.getIntExtra(
+                    BatteryManager.EXTRA_INVALID_CHARGER, 0);
+
+                final boolean levelOk = (level >= MIN_BATTERY_LEVEL);
+                final boolean pluggedOk =
+                        ((plugged & BatteryManager.BATTERY_PLUGGED_ANY) != 0) &&
+                        (invalidCharger == 0);
+
+                final boolean encryptOk = (levelOk && pluggedOk);
+                mEncryptButton.setEnabled(encryptOk);
+                mCableWarning.setVisibility(pluggedOk ? View.GONE : View.VISIBLE);
+                mBatteryWarning.setVisibility(levelOk ? View.GONE : View.VISIBLE);
+            }
+        }
+    };
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         final View contentView = getLayoutInflater().inflate(R.layout.encrypt_device, null);
-        final Button encryptButton = (Button) contentView.findViewById(R.id.accept_button);
+        mEncryptButton = (Button) contentView.findViewById(R.id.accept_button);
+        mCableWarning = contentView.findViewById(R.id.warning_unplugged);
+        mBatteryWarning = contentView.findViewById(R.id.warning_low_charge);
         setContentView(contentView);
 
-        encryptButton.setOnClickListener(new View.OnClickListener() {
+        mEncryptButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 final Bundle resumeInfo = getIntent().getBundleExtra(EXTRA_RESUME);
@@ -60,6 +96,21 @@
                 }
             }
         });
+
+        mIntentFilter = new IntentFilter();
+        mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        registerReceiver(mIntentReceiver, mIntentFilter);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        unregisterReceiver(mIntentReceiver);
     }
 
     public static boolean isDeviceEncrypted() {