diff options
8 files changed, 97 insertions, 31 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index afdd43423c72..a2f9bdd2370d 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2358,18 +2358,23 @@ public class DevicePolicyManager { * <p>The calling device admin must be a device or profile owner. If it is not, * a {@link SecurityException} will be thrown. * + * <p>The calling device admin can verify the value it has set by calling + * {@link #getRequiredStrongAuthTimeout(ComponentName)} and passing in its instance. + * * <p>This method can be called on the {@link DevicePolicyManager} instance returned by * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent * profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param timeoutMs The new timeout, after which the user will have to unlock with strong - * authentication method. If the timeout is lower than 1 hour (minimum) or higher than - * 72 hours (default and maximum) an {@link IllegalArgumentException} is thrown. + * authentication method. A value of 0 means the admin is not participating in + * controlling the timeout. + * The minimum and maximum timeouts are platform-defined and are typically 1 hour and + * 72 hours, respectively. Though discouraged, the admin may choose to require strong + * auth at all times using {@link #KEYGUARD_DISABLE_FINGERPRINT} and/or + * {@link #KEYGUARD_DISABLE_TRUST_AGENTS}. * * @throws SecurityException if {@code admin} is not a device or profile owner. - * @throws IllegalArgumentException if the timeout is lower than 1 hour (minimum) or higher than - * 72 hours (default and maximum) * * @hide */ @@ -2395,7 +2400,7 @@ public class DevicePolicyManager { * * @param admin The name of the admin component to check, or {@code null} to aggregate * accross all participating admins. - * @return The timeout or default timeout if not configured + * @return The timeout or 0 if not configured for the provided admin. * * @hide */ diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index 3ba81c8689b9..bad632555c42 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -649,10 +649,11 @@ public abstract class BackupAgent extends ContextWrapper { File file = scanQueue.remove(0); String filePath; try { - // Ignore symlinks outright + // Ignore things that aren't "real" files or dirs StructStat stat = Os.lstat(file.getPath()); - if (OsConstants.S_ISLNK(stat.st_mode)) { - if (DEBUG) Log.i(TAG, "Symlink (skipping)!: " + file); + if (!OsConstants.S_ISREG(stat.st_mode) + && !OsConstants.S_ISDIR(stat.st_mode)) { + if (DEBUG) Log.i(TAG, "Not a file/dir (skipping)!: " + file); continue; } diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 5e00dc1a4fa3..6f24f763d6a6 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -1557,16 +1557,13 @@ public class ExifInterface { * <p> * This method is only supported for JPEG files. * </p> - * - * @throws UnsupportedOperationException If this method is called with unsupported files. */ public void saveAttributes() throws IOException { if (!mIsSupportedFile || mIsRaw) { - throw new UnsupportedOperationException( - "ExifInterface only supports saving attributes on JPEG formats."); + throw new IOException("ExifInterface only supports saving attributes on JPEG formats."); } if (mIsInputStream || (mSeekableFileDescriptor == null && mFilename == null)) { - throw new UnsupportedOperationException( + throw new IOException( "ExifInterface does not support saving attributes for the current input."); } diff --git a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java index 177ba0d20154..d87bc11a8495 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java +++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java @@ -42,12 +42,6 @@ public class IconUtils { public static Drawable loadMimeIcon( Context context, String mimeType, String authority, String docId, int mode) { if (Document.MIME_TYPE_DIR.equals(mimeType)) { - // TODO: eventually move these hacky assets into that package - if ("com.android.providers.media.documents".equals(authority) - && docId.startsWith("album")) { - return context.getDrawable(R.drawable.ic_doc_album); - } - if (mode == State.MODE_GRID) { return context.getDrawable(R.drawable.ic_grid_folder); } else { diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsLoader.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsLoader.java index cebc9b05679e..557a2f6abc9f 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RecentsLoader.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsLoader.java @@ -157,6 +157,9 @@ public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> { throw new RuntimeException(e); } catch (ExecutionException e) { // We already logged on other side + } catch (Exception e) { + Log.e(TAG, "Failed to query Recents for authority: " + task.authority + + ". Skip this authority in Recents.", e); } } else { allDone = false; diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java index 0a2960f8ffe0..94b8277f4edd 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java @@ -107,7 +107,13 @@ public class Model { mSortOrder = result.sortOrder; doc = result.doc; - updateModelData(); + try { + updateModelData(); + } catch (Exception e) { + Log.e(TAG, "Error while accessing cursors", e); + notifyUpdateListeners(e); + return; + } final Bundle extras = mCursor.getExtras(); if (extras != null) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 2eceb0b0a52e..92aa1b98238f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -611,7 +611,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0; long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK; - long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; + long strongAuthUnlockTimeout = 0; // admin doesn't participate by default static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0; int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE; @@ -4248,10 +4248,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } Preconditions.checkNotNull(who, "ComponentName is null"); - Preconditions.checkArgument(timeoutMs >= MINIMUM_STRONG_AUTH_TIMEOUT_MS, - "Timeout must not be lower than the minimum strong auth timeout."); - Preconditions.checkArgument(timeoutMs <= DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS, - "Timeout must not be higher than the default strong auth timeout."); + Preconditions.checkArgument(timeoutMs >= 0, "Timeout must not be a negative number."); + // timeoutMs with value 0 means that the admin doesn't participate + // timeoutMs is clamped to the interval in case the internal constants change in the future + if (timeoutMs != 0 && timeoutMs < MINIMUM_STRONG_AUTH_TIMEOUT_MS) { + timeoutMs = MINIMUM_STRONG_AUTH_TIMEOUT_MS; + } + if (timeoutMs > DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) { + timeoutMs = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; + } final int userHandle = mInjector.userHandleGetCallingUserId(); synchronized (this) { @@ -4267,7 +4272,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { /** * Return a single admin's strong auth unlock timeout or minimum value (strictest) of all * admins if who is null. - * Returns default timeout if not configured. + * Returns 0 if not configured for the provided admin. */ @Override public long getRequiredStrongAuthTimeout(ComponentName who, int userId, boolean parent) { @@ -4278,9 +4283,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { if (who != null) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userId, parent); - return admin != null ? Math.max(admin.strongAuthUnlockTimeout, - MINIMUM_STRONG_AUTH_TIMEOUT_MS) - : DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; + return admin != null ? admin.strongAuthUnlockTimeout : 0; } // Return the strictest policy across all participating admins. @@ -4288,8 +4291,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; for (int i = 0; i < admins.size(); i++) { - strongAuthUnlockTimeout = Math.min(admins.get(i).strongAuthUnlockTimeout, - strongAuthUnlockTimeout); + final long timeout = admins.get(i).strongAuthUnlockTimeout; + if (timeout != 0) { // take only participating admins into account + strongAuthUnlockTimeout = Math.min(timeout, strongAuthUnlockTimeout); + } } return Math.max(strongAuthUnlockTimeout, MINIMUM_STRONG_AUTH_TIMEOUT_MS); } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 2d96bff29bd7..11ec7ac64eda 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -1909,6 +1909,61 @@ public class DevicePolicyManagerTest extends DpmTestBase { verifyScreenTimeoutCall(Integer.MAX_VALUE, false); } + public void testSetRequiredStrongAuthTimeout_DeviceOwner() throws Exception { + mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + setupDeviceOwner(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + + final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = 1 * 60 * 60 * 1000; // 1h + final long ONE_MINUTE = 60 * 1000; + + // aggregation should be the default if unset by any admin + assertEquals(dpm.getRequiredStrongAuthTimeout(null), + DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); + + // admin not participating by default + assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); + + //clamping from the top + dpm.setRequiredStrongAuthTimeout(admin1, + DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); + assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), + DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); + assertEquals(dpm.getRequiredStrongAuthTimeout(null), + DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); + + // 0 means default + dpm.setRequiredStrongAuthTimeout(admin1, 0); + assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); + assertEquals(dpm.getRequiredStrongAuthTimeout(null), + DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); + + // clamping from the bottom + dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS - ONE_MINUTE); + assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS); + assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS); + + // value within range + dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); + assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS + + ONE_MINUTE); + assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS + + ONE_MINUTE); + + // reset to default + dpm.setRequiredStrongAuthTimeout(admin1, 0); + assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); + assertEquals(dpm.getRequiredStrongAuthTimeout(null), + DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); + + // negative value + try { + dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE); + fail("Didn't throw IllegalArgumentException"); + } catch (IllegalArgumentException iae) { + } + } + private void verifyScreenTimeoutCall(Integer expectedTimeout, boolean shouldStayOnWhilePluggedInBeCleared) { if (expectedTimeout == null) { |