Provide lockdown of date/time device owners.

Fixed two minor issues with the screencapture as well.
Updated documentation and added enforceCrossUserPermission.

Bug:16948504
Change-Id: I9a645dcf480a4a044879ba481bce964d06fe5153
diff --git a/api/current.txt b/api/current.txt
index 85a3fc5..fbab23a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5419,6 +5419,7 @@
     method public java.lang.String[] getAccountTypesWithManagementDisabled();
     method public java.util.List<android.content.ComponentName> getActiveAdmins();
     method public android.os.Bundle getApplicationRestrictions(android.content.ComponentName, java.lang.String);
+    method public boolean getAutoTimeRequired();
     method public boolean getCameraDisabled(android.content.ComponentName);
     method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
     method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
@@ -5464,6 +5465,7 @@
     method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
     method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
     method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
+    method public void setAutoTimeRequired(android.content.ComponentName, boolean);
     method public void setCameraDisabled(android.content.ComponentName, boolean);
     method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
     method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 41bbb87..aa21167 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1885,7 +1885,7 @@
      * security exception will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param disabled Whether or not screen capture should be disabled.
+     * @param disabled Whether screen capture is disabled or not.
      */
     public void setScreenCaptureDisabled(ComponentName admin, boolean disabled) {
         if (mService != null) {
@@ -1920,6 +1920,42 @@
     }
 
     /**
+     * Called by a device owner to set whether auto time is required. If auto time is
+     * required the user cannot set the date and time, but has to use network date and time.
+     *
+     * <p>Note: if auto time is required the user can still manually set the time zone.
+     *
+     * <p>The calling device admin must be a device owner. If it is not, a security exception will
+     * be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param required Whether auto time is set required or not.
+     */
+    public void setAutoTimeRequired(ComponentName admin, boolean required) {
+        if (mService != null) {
+            try {
+                mService.setAutoTimeRequired(admin, UserHandle.myUserId(), required);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * @return true if auto time is required.
+     */
+    public boolean getAutoTimeRequired() {
+        if (mService != null) {
+            try {
+                return mService.getAutoTimeRequired();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
      * Called by an application that is administering the device to disable keyguard customizations,
      * such as widgets. After setting this, keyguard features will be disabled according to the
      * provided feature list.
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 1e17bb6..23f36fb 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -186,4 +186,7 @@
     boolean addCrossProfileWidgetProvider(in ComponentName admin, String packageName);
     boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName);
     List<String> getCrossProfileWidgetProviders(in ComponentName admin);
+
+    void setAutoTimeRequired(in ComponentName who, int userHandle, boolean required);
+    boolean getAutoTimeRequired();
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7baa258..9856f5b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -287,6 +287,7 @@
         private static final String TAG_DISABLE_CALLER_ID = "disable-caller-id";
         private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture";
         private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
+        private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
         private static final String TAG_ACCOUNT_TYPE = "account-type";
         private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES
                 = "permitted-accessiblity-services";
@@ -365,6 +366,7 @@
         boolean disableCamera = false;
         boolean disableCallerId = false;
         boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
+        boolean requireAutoTime = false; // Can only be set by a device owner.
 
         Set<String> accountTypesWithManagementDisabled = new HashSet<String>();
 
@@ -501,6 +503,11 @@
                 out.attribute(null, ATTR_VALUE, Boolean.toString(disableScreenCapture));
                 out.endTag(null, TAG_DISABLE_SCREEN_CAPTURE);
             }
+            if (requireAutoTime) {
+                out.startTag(null, TAG_REQUIRE_AUTO_TIME);
+                out.attribute(null, ATTR_VALUE, Boolean.toString(requireAutoTime));
+                out.endTag(null, TAG_REQUIRE_AUTO_TIME);
+            }
             if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
                 out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES);
                 out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures));
@@ -634,6 +641,9 @@
                 } else if (TAG_DISABLE_SCREEN_CAPTURE.equals(tag)) {
                     disableScreenCapture = Boolean.parseBoolean(
                             parser.getAttributeValue(null, ATTR_VALUE));
+                } else if (TAG_REQUIRE_AUTO_TIME.equals(tag)) {
+                    requireAutoTime= Boolean.parseBoolean(
+                            parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
                     disabledKeyguardFeatures = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
@@ -818,6 +828,8 @@
                     pw.println(disableCallerId);
             pw.print(prefix); pw.print("disableScreenCapture=");
                     pw.println(disableScreenCapture);
+            pw.print(prefix); pw.print("requireAutoTime=");
+                    pw.println(requireAutoTime);
             pw.print(prefix); pw.print("disabledKeyguardFeatures=");
                     pw.println(disabledKeyguardFeatures);
             pw.print(prefix); pw.print("crossProfileWidgetProviders=");
@@ -3291,6 +3303,7 @@
         if (!mHasFeature) {
             return;
         }
+        enforceCrossUserPermission(userHandle);
         synchronized (this) {
             if (who == null) {
                 throw new NullPointerException("ComponentName is null");
@@ -3343,6 +3356,51 @@
     }
 
     /**
+     * Set whether auto time is required by the specified admin (must be device owner).
+     */
+    public void setAutoTimeRequired(ComponentName who, int userHandle, boolean required) {
+        if (!mHasFeature) {
+            return;
+        }
+        enforceCrossUserPermission(userHandle);
+        synchronized (this) {
+            if (who == null) {
+                throw new NullPointerException("ComponentName is null");
+            }
+            ActiveAdmin admin = getActiveAdminForCallerLocked(who,
+                    DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+            if (admin.requireAutoTime != required) {
+                admin.requireAutoTime = required;
+                saveSettingsLocked(userHandle);
+            }
+        }
+
+        // Turn AUTO_TIME on in settings if it is required
+        if (required) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                Settings.Global.putInt(mContext.getContentResolver(),
+                        Settings.Global.AUTO_TIME, 1 /* AUTO_TIME on */);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    /**
+     * Returns whether or not auto time is required by the device owner.
+     */
+    public boolean getAutoTimeRequired() {
+        if (!mHasFeature) {
+            return false;
+        }
+        synchronized (this) {
+            ActiveAdmin deviceOwner = getDeviceOwnerAdmin();
+            return (deviceOwner != null) ? deviceOwner.requireAutoTime : false;
+        }
+    }
+
+    /**
      * The system property used to share the state of the camera. The native camera service
      * is expected to read this property and act accordingly.
      */
@@ -3522,6 +3580,24 @@
         return null;
     }
 
+    // Returns the active device owner or null if there is no device owner.
+    private ActiveAdmin getDeviceOwnerAdmin() {
+        String deviceOwnerPackageName = getDeviceOwner();
+        if (deviceOwnerPackageName == null) {
+            return null;
+        }
+
+        DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
+        final int n = policy.mAdminList.size();
+        for (int i = 0; i < n; i++) {
+            ActiveAdmin admin = policy.mAdminList.get(i);
+            if (deviceOwnerPackageName.equals(admin.info.getPackageName())) {
+                return admin;
+            }
+        }
+        return null;
+    }
+
     @Override
     public void clearDeviceOwner(String packageName) {
         if (packageName == null) {