Populate Enterprise Privacy Settings page - batch 1

This CL adds the first batch of items to the Privacy Settings page.
These are all the items that fall into the "What types of
information can your organization see?" category and do not require
deeper Framework changes. Further batches are to come in separate
CLs.

Test: make RunSettingsRoboTests
Bug: 32692748
Change-Id: I460093bc45ed0e5baab2a5cdf9833e654d436cc9
This commit is contained in:
Bartosz Fabianowski
2016-11-18 00:09:52 +01:00
parent d12b97f9e3
commit 62b96811c1
18 changed files with 415 additions and 24 deletions

View File

@@ -19,11 +19,13 @@ import android.content.res.TypedArray;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.widget.TextView;
public class DividerPreference extends Preference {
private Boolean mAllowAbove;
private Boolean mAllowBelow;
private Boolean mMultiLine;
public DividerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -34,6 +36,9 @@ public class DividerPreference extends Preference {
if (a.hasValue(R.styleable.DividerPreference_allowDividerBelow)) {
mAllowBelow = a.getBoolean(R.styleable.DividerPreference_allowDividerBelow, false);
}
if (a.hasValue(R.styleable.DividerPreference_multiLine)) {
mMultiLine = a.getBoolean(R.styleable.DividerPreference_multiLine, false);
}
}
public DividerPreference(Context context) {
@@ -59,5 +64,12 @@ public class DividerPreference extends Preference {
if (mAllowBelow != null) {
holder.setDividerAllowedBelow(mAllowBelow);
}
if (mMultiLine != null && mMultiLine) {
TextView textView = (TextView)holder.findViewById(android.R.id.title);
if (textView != null) {
textView.setSingleLine(false);
}
}
}
}

View File

@@ -25,5 +25,17 @@ public interface ApplicationFeatureProvider {
* Returns a new {@link AppHeaderController} instance to customize app header.
*/
AppHeaderController newAppHeaderController(Fragment fragment, View appHeader);
}
/**
* Asynchronously calculates the total number of apps installed on the device, across all users
* and managed profiles.
*/
void calculateNumberOfInstalledApps(NumberOfInstalledAppsCallback callback);
/**
* Callback that receives the total number of packages installed on the device.
*/
public interface NumberOfInstalledAppsCallback {
void onNumberOfInstalledAppsResult(int num);
}
}

View File

@@ -18,17 +18,50 @@ package com.android.settings.applications;
import android.app.Fragment;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.UserManager;
import android.view.View;
import java.util.List;
public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvider {
private final Context mContext;
private final PackageManagerWrapper mPm;
private final UserManager mUm;
public ApplicationFeatureProviderImpl(Context context) {
public ApplicationFeatureProviderImpl(Context context, PackageManagerWrapper pm) {
mContext = context.getApplicationContext();
mPm = pm;
mUm = UserManager.get(mContext);
}
@Override
public AppHeaderController newAppHeaderController(Fragment fragment, View appHeader) {
return new AppHeaderController(mContext, fragment, appHeader);
}
@Override
public void calculateNumberOfInstalledApps(NumberOfInstalledAppsCallback callback) {
new AllUserInstalledAppCounter(callback).execute();
}
private class AllUserInstalledAppCounter extends InstalledAppCounter {
private NumberOfInstalledAppsCallback mCallback;
AllUserInstalledAppCounter(NumberOfInstalledAppsCallback callback) {
super(mContext, ApplicationFeatureProviderImpl.this.mPm);
mCallback = callback;
}
@Override
protected void onCountComplete(int num) {
mCallback.onNumberOfInstalledAppsResult(num);
}
@Override
protected List<UserInfo> getUsersToCount() {
return mUm.getUsers(true /* excludeDying */);
}
}
}

View File

@@ -36,6 +36,13 @@ public interface PackageManagerWrapper {
*/
List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId);
/**
* Calls {@code PackageManager.hasSystemFeature()}.
*
* @see android.content.pm.PackageManager.PackageManager#hasSystemFeature
*/
boolean hasSystemFeature(String name);
/**
* Calls {@code PackageManager.queryIntentActivitiesAsUser()}.
*

View File

@@ -35,6 +35,11 @@ public class PackageManagerWrapperImpl implements PackageManagerWrapper {
return mPm.getInstalledApplicationsAsUser(flags, userId);
}
@Override
public boolean hasSystemFeature(String name) {
return mPm.hasSystemFeature(name);
}
@Override
public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
return mPm.queryIntentActivitiesAsUser(intent, flags, userId);

View File

@@ -18,10 +18,17 @@ package com.android.settings.enterprise;
import android.content.ComponentName;
// This interface replicates a subset of the android.app.admin.DevicePolicyManager (DPM). The
// interface exists so that we can use a thin wrapper around the DPM in production code and a mock
// in tests. We cannot directly mock or shadow the DPM, because some of the methods we rely on are
// newer than the API version supported by Robolectric.
/**
* This interface replicates a subset of the android.app.admin.DevicePolicyManager (DPM). The
* interface exists so that we can use a thin wrapper around the DPM in production code and a mock
* in tests. We cannot directly mock or shadow the DPM, because some of the methods we rely on are
* newer than the API version supported by Robolectric.
*/
public interface DevicePolicyManagerWrapper {
public ComponentName getDeviceOwnerComponentOnAnyUser();
/**
* Calls {@code DevicePolicyManager.getDeviceOwnerComponentOnAnyUser()}.
*
* @see android.app.admin.DevicePolicyManager#getDeviceOwnerComponentOnAnyUser
*/
ComponentName getDeviceOwnerComponentOnAnyUser();
}

View File

@@ -26,6 +26,7 @@ public class DevicePolicyManagerWrapperImpl implements DevicePolicyManagerWrappe
mDpm = dpm;
}
@Override
public ComponentName getDeviceOwnerComponentOnAnyUser() {
return mDpm.getDeviceOwnerComponentOnAnyUser();
}

View File

@@ -17,21 +17,23 @@
package com.android.settings.enterprise;
import android.content.pm.PackageManager;
import android.content.Context;
import com.android.settings.applications.PackageManagerWrapper;
public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFeatureProvider {
private final Context mContext;
private final DevicePolicyManagerWrapper mDpm;
private final PackageManagerWrapper mPm;
public EnterprisePrivacyFeatureProviderImpl(Context context, DevicePolicyManagerWrapper dpm) {
mContext = context.getApplicationContext();
public EnterprisePrivacyFeatureProviderImpl(DevicePolicyManagerWrapper dpm,
PackageManagerWrapper pm) {
mDpm = dpm;
mPm = pm;
}
@Override
public boolean hasDeviceOwner() {
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
if (!mPm.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
return false;
}
return mDpm.getDeviceOwnerComponentOnAnyUser() != null;

View File

@@ -17,7 +17,6 @@
package com.android.settings.enterprise;
import android.content.Context;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import com.android.settings.R;
@@ -25,7 +24,9 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.core.PreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable.SearchIndexProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -55,7 +56,9 @@ public class EnterprisePrivacySettings extends DashboardFragment {
@Override
protected List<PreferenceController> getPreferenceControllers(Context context) {
return null;
final List controllers = new ArrayList<PreferenceController>();
controllers.add(new InstalledPackagesPreferenceController(context));
return controllers;
}
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2016 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.content.res.Resources;
import android.support.v7.preference.Preference;
import com.android.settings.R;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.core.PreferenceController;
import com.android.settings.overlay.FeatureFactory;
public class InstalledPackagesPreferenceController extends PreferenceController {
private static final String KEY_NUMBER_INSTALLED_PACKAGES = "number_installed_packages";
private final ApplicationFeatureProvider mFeatureProvider;
public InstalledPackagesPreferenceController(Context context) {
super(context);
mFeatureProvider = FeatureFactory.getFactory(context)
.getApplicationFeatureProvider(context);
}
@Override
public void updateState(Preference preference) {
mFeatureProvider.calculateNumberOfInstalledApps(
new ApplicationFeatureProvider.NumberOfInstalledAppsCallback() {
@Override
public void onNumberOfInstalledAppsResult(int num) {
preference.setTitle(mContext.getResources().getQuantityString(
R.plurals.number_installed_packages, num, num));
}
});
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
return false;
}
@Override
public String getPreferenceKey() {
return KEY_NUMBER_INSTALLED_PACKAGES;
}
}

View File

@@ -22,6 +22,7 @@ import android.support.annotation.Keep;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProviderImpl;
import com.android.settings.applications.PackageManagerWrapperImpl;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.core.instrumentation.MetricsFeatureProviderImpl;
import com.android.settings.dashboard.DashboardFeatureProvider;
@@ -77,7 +78,8 @@ public final class FeatureFactoryImpl extends FeatureFactory {
@Override
public ApplicationFeatureProvider getApplicationFeatureProvider(Context context) {
if (mApplicationFeatureProvider == null) {
mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(context);
mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(context,
new PackageManagerWrapperImpl(context.getPackageManager()));
}
return mApplicationFeatureProvider;
}
@@ -93,9 +95,10 @@ public final class FeatureFactoryImpl extends FeatureFactory {
@Override
public EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(Context context) {
if (mEnterprisePrivacyFeatureProvider == null) {
mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(context,
mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(
new DevicePolicyManagerWrapperImpl((DevicePolicyManager) context
.getSystemService(Context.DEVICE_POLICY_SERVICE)));
.getSystemService(Context.DEVICE_POLICY_SERVICE)),
new PackageManagerWrapperImpl(context.getPackageManager()));
}
return mEnterprisePrivacyFeatureProvider;
}