Hide "Changes made by your organization's admin" when empty
The admin of a manged device can take a number actions that will be listed in the "Changes made by your organization's admin" section of Settings. If the admin has not taken any such actions, the section will be empty and should be hidden. This is accomplished by having a PreferenceController for the section that observes the state of the PreferenceControllers inside it. Bug: 35912953 Test: m RunSettingsRoboTests Change-Id: Ia95754493ee6c5a19b4aa9731fd56fd558e61849
This commit is contained in:
@@ -50,15 +50,15 @@ public abstract class AdminGrantedPermissionsPreferenceControllerBase
|
||||
true /* async */,
|
||||
(num) -> {
|
||||
if (num == 0) {
|
||||
preference.setVisible(false);
|
||||
mHasApps = false;
|
||||
} else {
|
||||
preference.setVisible(true);
|
||||
preference.setSummary(mContext.getResources().getQuantityString(
|
||||
R.plurals.enterprise_privacy_number_packages_lower_bound,
|
||||
num, num));
|
||||
mHasApps = true;
|
||||
}
|
||||
preference.setVisible(mHasApps);
|
||||
notifyOnAvailabilityUpdate(mHasApps);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ public abstract class AdminGrantedPermissionsPreferenceControllerBase
|
||||
mFeatureProvider.calculateNumberOfAppsWithAdminGrantedPermissions(mPermissions,
|
||||
false /* async */, (num) -> haveAppsWithAdminGrantedPermissions[0] = num > 0);
|
||||
mHasApps = haveAppsWithAdminGrantedPermissions[0];
|
||||
notifyOnAvailabilityUpdate(mHasApps);
|
||||
return mHasApps;
|
||||
}
|
||||
|
||||
|
@@ -42,7 +42,9 @@ public class AlwaysOnVpnCurrentUserPreferenceController
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mFeatureProvider.isAlwaysOnVpnSetInCurrentUser();
|
||||
final boolean available = mFeatureProvider.isAlwaysOnVpnSetInCurrentUser();
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -33,7 +33,9 @@ public class AlwaysOnVpnManagedProfilePreferenceController
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mFeatureProvider.isAlwaysOnVpnSetInManagedProfile();
|
||||
final boolean available = mFeatureProvider.isAlwaysOnVpnSetInManagedProfile();
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -44,8 +44,11 @@ public class CaCertsPreferenceController extends DynamicAvailabilityPreferenceCo
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mFeatureProvider.getNumberOfOwnerInstalledCaCertsForCurrentUserAndManagedProfile()
|
||||
> 0;
|
||||
final boolean available =
|
||||
mFeatureProvider.getNumberOfOwnerInstalledCaCertsForCurrentUserAndManagedProfile()
|
||||
> 0;
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -42,14 +42,18 @@ public class EnterpriseInstalledPackagesPreferenceController
|
||||
public void updateState(Preference preference) {
|
||||
mFeatureProvider.calculateNumberOfPolicyInstalledApps(true /* async */,
|
||||
(num) -> {
|
||||
final boolean available;
|
||||
if (num == 0) {
|
||||
preference.setVisible(false);
|
||||
available = false;
|
||||
} else {
|
||||
preference.setVisible(true);
|
||||
available = true;
|
||||
preference.setSummary(mContext.getResources().getQuantityString(
|
||||
R.plurals.enterprise_privacy_number_packages_lower_bound, num,
|
||||
num));
|
||||
|
||||
}
|
||||
preference.setVisible(available);
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -68,7 +72,9 @@ public class EnterpriseInstalledPackagesPreferenceController
|
||||
final Boolean[] haveEnterpriseInstalledPackages = { null };
|
||||
mFeatureProvider.calculateNumberOfPolicyInstalledApps(false /* async */,
|
||||
(num) -> haveEnterpriseInstalledPackages[0] = num > 0);
|
||||
return haveEnterpriseInstalledPackages[0];
|
||||
final boolean available = haveEnterpriseInstalledPackages[0];
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -45,7 +45,9 @@ public class EnterprisePrivacyPreferenceController extends DynamicAvailabilityPr
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mFeatureProvider.hasDeviceOwner();
|
||||
final boolean available = mFeatureProvider.hasDeviceOwner();
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -61,23 +61,32 @@ public class EnterprisePrivacySettings extends DashboardFragment {
|
||||
controllers.add(new NetworkLogsPreferenceController(context));
|
||||
controllers.add(new BugReportsPreferenceController(context));
|
||||
controllers.add(new SecurityLogsPreferenceController(context));
|
||||
controllers.add(new EnterpriseInstalledPackagesPreferenceController(context, lifecycle,
|
||||
async));
|
||||
controllers.add(new AdminGrantedLocationPermissionsPreferenceController(context, lifecycle,
|
||||
async));
|
||||
controllers.add(new AdminGrantedMicrophonePermissionPreferenceController(context, lifecycle,
|
||||
async));
|
||||
controllers.add(new AdminGrantedCameraPermissionPreferenceController(context, lifecycle,
|
||||
async));
|
||||
controllers.add(new EnterpriseSetDefaultAppsPreferenceController(context, lifecycle));
|
||||
controllers.add(new AlwaysOnVpnCurrentUserPreferenceController(context, lifecycle));
|
||||
controllers.add(new AlwaysOnVpnManagedProfilePreferenceController(context, lifecycle));
|
||||
controllers.add(new GlobalHttpProxyPreferenceController(context, lifecycle));
|
||||
controllers.add(new CaCertsPreferenceController(context, lifecycle));
|
||||
final List exposureChangesCategoryControllers = new ArrayList<PreferenceController>();
|
||||
exposureChangesCategoryControllers.add(new EnterpriseInstalledPackagesPreferenceController(
|
||||
context, lifecycle, async));
|
||||
exposureChangesCategoryControllers.add(
|
||||
new AdminGrantedLocationPermissionsPreferenceController(context, lifecycle, async));
|
||||
exposureChangesCategoryControllers.add(
|
||||
new AdminGrantedMicrophonePermissionPreferenceController(context, lifecycle,
|
||||
async));
|
||||
exposureChangesCategoryControllers.add(new AdminGrantedCameraPermissionPreferenceController(
|
||||
context, lifecycle, async));
|
||||
exposureChangesCategoryControllers.add(new EnterpriseSetDefaultAppsPreferenceController(
|
||||
context, lifecycle));
|
||||
exposureChangesCategoryControllers.add(new AlwaysOnVpnCurrentUserPreferenceController(
|
||||
context, lifecycle));
|
||||
exposureChangesCategoryControllers.add(new AlwaysOnVpnManagedProfilePreferenceController(
|
||||
context, lifecycle));
|
||||
exposureChangesCategoryControllers.add(new ImePreferenceController(context, lifecycle));
|
||||
exposureChangesCategoryControllers.add(new GlobalHttpProxyPreferenceController(context,
|
||||
lifecycle));
|
||||
exposureChangesCategoryControllers.add(new CaCertsPreferenceController(context, lifecycle));
|
||||
controllers.addAll(exposureChangesCategoryControllers);
|
||||
controllers.add(new ExposureChangesCategoryPreferenceController(context, lifecycle,
|
||||
exposureChangesCategoryControllers, async));
|
||||
controllers.add(new FailedPasswordWipeCurrentUserPreferenceController(context, lifecycle));
|
||||
controllers.add(new FailedPasswordWipeManagedProfilePreferenceController(context,
|
||||
lifecycle));
|
||||
controllers.add(new ImePreferenceController(context, lifecycle));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
@@ -48,7 +49,9 @@ public class EnterpriseSetDefaultAppsPreferenceController
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return getNumberOfEnterpriseSetDefaultApps() > 0;
|
||||
final boolean available = getNumberOfEnterpriseSetDefaultApps() > 0;
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,111 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.enterprise;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import com.android.settings.core.DynamicAvailabilityPreferenceController;
|
||||
import com.android.settings.core.PreferenceAvailabilityObserver;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A controller that hides a {@link android.support.v7.preference.PreferenceGroup} when none of the
|
||||
* {@link Preference}s inside it are visible.
|
||||
*
|
||||
* TODO(b/62051162): Use {@link android.support.v7.preference.PreferenceGroup}'s native ability to
|
||||
* hide itself when all {@link Preference}s inside it are invisible when that functionality becomes
|
||||
* available. This custom controller will still be needed to remove the
|
||||
* {@link android.support.v7.preference.PreferenceGroup} from the search index as required (by
|
||||
* having {@link #isAvailable()} return {@code false} if the method returns {@code false} for all
|
||||
* {@link Preference}s in the {@link android.support.v7.preference.PreferenceGroup}).
|
||||
*/
|
||||
public class ExposureChangesCategoryPreferenceController
|
||||
extends DynamicAvailabilityPreferenceController implements PreferenceAvailabilityObserver {
|
||||
|
||||
private static final String KEY_EXPOSURE_CHANGES_CATEGORY = "exposure_changes_category";
|
||||
private final Set<String> mAvailablePrefs = new HashSet<String>();
|
||||
private Preference mPreference = null;
|
||||
private boolean mControllingUi;
|
||||
|
||||
/**
|
||||
* When {@code controllingUi} is {@code true}, some of the preferences may have their visibility
|
||||
* determined asynchronously. In this case, {@link #isAvailable()} must always return {@code
|
||||
* true} and the group should be hidden using {@link Preference#setVisible()} if all preferences
|
||||
* report that they are invisible.
|
||||
* When {@code controllingUi} is {@code false}, we are running on the search indexer thread and
|
||||
* visibility must be determined synchronously. {@link #isAvailable()} can rely on all
|
||||
* preferences having their visibility determined already and should return whether the group is
|
||||
* visible or not.
|
||||
*/
|
||||
public ExposureChangesCategoryPreferenceController(Context context, Lifecycle lifecycle,
|
||||
List<DynamicAvailabilityPreferenceController> controllers, boolean controllingUi) {
|
||||
super(context, lifecycle);
|
||||
mControllingUi = controllingUi;
|
||||
for (final DynamicAvailabilityPreferenceController controller : controllers) {
|
||||
controller.setAvailabilityObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreferenceAvailabilityUpdated(String key, boolean available) {
|
||||
if (available) {
|
||||
mAvailablePrefs.add(key);
|
||||
} else {
|
||||
mAvailablePrefs.remove(key);
|
||||
}
|
||||
available = haveAnyVisiblePreferences();
|
||||
if (mControllingUi) {
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
}
|
||||
if (mPreference != null) {
|
||||
mPreference.setVisible(available);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
mPreference = preference;
|
||||
mPreference.setVisible(haveAnyVisiblePreferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (mControllingUi) {
|
||||
// When running on the main UI thread, some preferences determine their visibility
|
||||
// asynchronously. Always return true here and determine the pref group's actual
|
||||
// visibility as the other preferences report their visibility asynchronously via
|
||||
// onPreferenceAvailabilityUpdated().
|
||||
return true;
|
||||
}
|
||||
final boolean available = haveAnyVisiblePreferences();
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_EXPOSURE_CHANGES_CATEGORY;
|
||||
}
|
||||
|
||||
private boolean haveAnyVisiblePreferences() {
|
||||
return mAvailablePrefs.size() > 0;
|
||||
}
|
||||
}
|
@@ -46,6 +46,8 @@ public abstract class FailedPasswordWipePreferenceControllerBase
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return getMaximumFailedPasswordsBeforeWipe() > 0;
|
||||
final boolean available = getMaximumFailedPasswordsBeforeWipe() > 0;
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
}
|
||||
|
@@ -32,7 +32,9 @@ public class GlobalHttpProxyPreferenceController extends DynamicAvailabilityPref
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mFeatureProvider.isGlobalHttpProxySet();
|
||||
final boolean available = mFeatureProvider.isGlobalHttpProxySet();
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -43,7 +43,9 @@ public class ImePreferenceController extends DynamicAvailabilityPreferenceContro
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mFeatureProvider.getImeLabelIfOwnerSet() != null;
|
||||
final boolean available = mFeatureProvider.getImeLabelIfOwnerSet() != null;
|
||||
notifyOnAvailabilityUpdate(available);
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user