Add Device Owner disclosure to Add Accounts dialog
This CL adds a footer to the Add Accounts dialog that tells the user when the device is managed by a Device Owner app. Bug: 32692748 Test: make RunSettingsRoboTests Change-Id: I0dd161eb0bbbc87c04692d4fa6547bd41dab05e0
This commit is contained in:
@@ -8034,6 +8034,14 @@
|
||||
<string name="enterprise_privacy_always_on_vpn_work">Always-on VPN turned on in your work profile</string>
|
||||
<!-- Label explaining that a global HTTP proxy was set by the admin. [CHAR LIMIT=NONE] -->
|
||||
<string name="enterprise_privacy_global_http_proxy">Global HTTP proxy set</string>
|
||||
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
|
||||
<string name="do_disclosure_generic">This device is managed.</string>
|
||||
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
|
||||
<string name="do_disclosure_with_name">This device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g>.</string>
|
||||
<!-- Message indicating that the device is enterprise-managed: Space that separates the main text and the "learn more" link that follows it. [CHAR LIMIT=NONE] -->
|
||||
<string name="do_disclosure_learn_more_separator">" "</string>
|
||||
<!-- Message indicating that the device is enterprise-managed: Link to learn more about what a Device Owner app can do [CHAR LIMIT=NONE] -->
|
||||
<string name="do_disclosure_learn_more">Learn more</string>
|
||||
|
||||
<!-- Preference label for the Photos & Videos storage section. [CHAR LIMIT=50] -->
|
||||
<string name="storage_photos_videos">Photos & Videos</string>
|
||||
|
@@ -22,6 +22,7 @@ import static android.content.Intent.EXTRA_USER;
|
||||
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AuthenticatorDescription;
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -41,6 +42,10 @@ import com.android.internal.util.CharSequences;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.FooterPreference;
|
||||
import com.android.settings.widget.FooterPreferenceMixin;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
@@ -61,6 +66,10 @@ import java.util.Map;
|
||||
public class ChooseAccountActivity extends SettingsPreferenceFragment {
|
||||
|
||||
private static final String TAG = "ChooseAccountActivity";
|
||||
|
||||
private EnterprisePrivacyFeatureProvider mFeatureProvider;
|
||||
private FooterPreference mEnterpriseDisclosurePreference = null;
|
||||
|
||||
private String[] mAuthorities;
|
||||
private PreferenceGroup mAddAccountGroup;
|
||||
private final ArrayList<ProviderEntry> mProviderList = new ArrayList<ProviderEntry>();
|
||||
@@ -101,6 +110,10 @@ public class ChooseAccountActivity extends SettingsPreferenceFragment {
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
final Activity activity = getActivity();
|
||||
mFeatureProvider = FeatureFactory.getFactory(activity)
|
||||
.getEnterprisePrivacyFeatureProvider(activity);
|
||||
|
||||
addPreferencesFromResource(R.xml.add_account_settings);
|
||||
mAuthorities = getIntent().getStringArrayExtra(
|
||||
AccountPreferenceBase.AUTHORITIES_FILTER_KEY);
|
||||
@@ -187,6 +200,7 @@ public class ChooseAccountActivity extends SettingsPreferenceFragment {
|
||||
p.checkAccountManagementAndSetDisabled(mUserHandle.getIdentifier());
|
||||
mAddAccountGroup.addPreference(p);
|
||||
}
|
||||
addEnterpriseDisclosure();
|
||||
} else {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
final StringBuilder auths = new StringBuilder();
|
||||
@@ -201,6 +215,19 @@ public class ChooseAccountActivity extends SettingsPreferenceFragment {
|
||||
}
|
||||
}
|
||||
|
||||
private void addEnterpriseDisclosure() {
|
||||
final CharSequence disclosure = mFeatureProvider.getDeviceOwnerDisclosure(getActivity());
|
||||
if (disclosure == null) {
|
||||
return;
|
||||
}
|
||||
if (mEnterpriseDisclosurePreference == null) {
|
||||
mEnterpriseDisclosurePreference = mFooterPreferenceMixin.createFooterPreference();
|
||||
mEnterpriseDisclosurePreference.setSelectable(false);
|
||||
}
|
||||
mEnterpriseDisclosurePreference.setTitle(disclosure);
|
||||
mAddAccountGroup.addPreference(mEnterpriseDisclosurePreference);
|
||||
}
|
||||
|
||||
public ArrayList<String> getAuthoritiesForAccountType(String type) {
|
||||
if (mAccountTypeToAuthorities == null) {
|
||||
mAccountTypeToAuthorities = Maps.newHashMap();
|
||||
|
@@ -33,6 +33,13 @@ public interface DevicePolicyManagerWrapper {
|
||||
*/
|
||||
ComponentName getDeviceOwnerComponentOnAnyUser();
|
||||
|
||||
/**
|
||||
* Calls {@code DevicePolicyManager.getDeviceOwnerNameOnAnyUser()}.
|
||||
*
|
||||
* @see android.app.admin.DevicePolicyManager#getDeviceOwnerNameOnAnyUser
|
||||
*/
|
||||
public CharSequence getDeviceOwnerOrganizationName();
|
||||
|
||||
/**
|
||||
* Calls {@code DevicePolicyManager.getPermissionGrantState()}.
|
||||
*
|
||||
|
@@ -32,6 +32,11 @@ public class DevicePolicyManagerWrapperImpl implements DevicePolicyManagerWrappe
|
||||
return mDpm.getDeviceOwnerComponentOnAnyUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getDeviceOwnerOrganizationName() {
|
||||
return mDpm.getDeviceOwnerOrganizationName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPermissionGrantState(@Nullable ComponentName admin, String packageName,
|
||||
String permission) {
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.enterprise;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public interface EnterprisePrivacyFeatureProvider {
|
||||
@@ -31,6 +33,15 @@ public interface EnterprisePrivacyFeatureProvider {
|
||||
*/
|
||||
boolean isInCompMode();
|
||||
|
||||
/**
|
||||
* Returns a message informing the user that the device is managed by a Device Owner app. The
|
||||
* message includes a Learn More link that takes the user to the enterprise privacy section of
|
||||
* Settings. If the device is not managed by a Device Owner app, returns {@code null}.
|
||||
*
|
||||
* @param context The context in which to show the enterprise privacy section of Settings
|
||||
*/
|
||||
CharSequence getDeviceOwnerDisclosure(Context context);
|
||||
|
||||
/**
|
||||
* Returns the time at which the Device Owner last retrieved security logs, or {@code null} if
|
||||
* logs were never retrieved by the Device Owner on this device.
|
||||
|
@@ -16,11 +16,19 @@
|
||||
|
||||
package com.android.settings.enterprise;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.PackageManagerWrapper;
|
||||
import com.android.settings.vpn2.ConnectivityManagerWrapper;
|
||||
import com.android.settings.vpn2.VpnUtils;
|
||||
@@ -34,15 +42,18 @@ public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFe
|
||||
private final PackageManagerWrapper mPm;
|
||||
private final UserManager mUm;
|
||||
private final ConnectivityManagerWrapper mCm;
|
||||
private final Resources mResources;
|
||||
|
||||
private static final int MY_USER_ID = UserHandle.myUserId();
|
||||
|
||||
public EnterprisePrivacyFeatureProviderImpl(DevicePolicyManagerWrapper dpm,
|
||||
PackageManagerWrapper pm, UserManager um, ConnectivityManagerWrapper cm) {
|
||||
PackageManagerWrapper pm, UserManager um, ConnectivityManagerWrapper cm,
|
||||
Resources resources) {
|
||||
mDpm = dpm;
|
||||
mPm = pm;
|
||||
mUm = um;
|
||||
mCm = cm;
|
||||
mResources = resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,6 +78,26 @@ public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFe
|
||||
return hasDeviceOwner() && getManagedProfileUserId() != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getDeviceOwnerDisclosure(Context context) {
|
||||
if (!hasDeviceOwner()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final SpannableStringBuilder disclosure = new SpannableStringBuilder();
|
||||
final CharSequence organizationName = mDpm.getDeviceOwnerOrganizationName();
|
||||
if (organizationName != null) {
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_with_name,
|
||||
organizationName));
|
||||
} else {
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_generic));
|
||||
}
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_learn_more),
|
||||
new EnterprisePrivacySpan(context), 0);
|
||||
return disclosure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getLastSecurityLogRetrievalTime() {
|
||||
final long timestamp = mDpm.getLastSecurityLogRetrievalTime();
|
||||
@@ -101,4 +132,23 @@ public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFe
|
||||
public boolean isGlobalHttpProxySet() {
|
||||
return mCm.getGlobalProxy() != null;
|
||||
}
|
||||
|
||||
protected static class EnterprisePrivacySpan extends ClickableSpan {
|
||||
private final Context mContext;
|
||||
|
||||
public EnterprisePrivacySpan(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
mContext.startActivity(new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof EnterprisePrivacySpan
|
||||
&& ((EnterprisePrivacySpan) object).mContext == mContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -111,7 +111,8 @@ public class FeatureFactoryImpl extends FeatureFactory {
|
||||
new PackageManagerWrapperImpl(context.getPackageManager()),
|
||||
UserManager.get(context),
|
||||
new ConnectivityManagerWrapperImpl((ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE)));
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE)),
|
||||
context.getResources());
|
||||
}
|
||||
return mEnterprisePrivacyFeatureProvider;
|
||||
}
|
||||
|
@@ -198,7 +198,7 @@ public final class InstalledAppCounterTest {
|
||||
}
|
||||
}
|
||||
|
||||
private class IsLaunchIntentFor extends ArgumentMatcher<Intent> {
|
||||
private static class IsLaunchIntentFor extends ArgumentMatcher<Intent> {
|
||||
private final String mPackageName;
|
||||
|
||||
IsLaunchIntentFor(String packageName) {
|
||||
@@ -211,7 +211,7 @@ public final class InstalledAppCounterTest {
|
||||
if (intent == null) {
|
||||
return false;
|
||||
}
|
||||
if (intent.getAction() != Intent.ACTION_MAIN) {
|
||||
if (!Intent.ACTION_MAIN.equals(intent.getAction())) {
|
||||
return false;
|
||||
}
|
||||
final Set<String> categories = intent.getCategories();
|
||||
|
@@ -17,12 +17,16 @@
|
||||
package com.android.settings.enterprise;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.net.ProxyInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.SpannableStringBuilder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.applications.PackageManagerWrapper;
|
||||
@@ -34,12 +38,14 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
@@ -50,6 +56,7 @@ import static org.mockito.Mockito.when;
|
||||
public final class EnterprisePrivacyFeatureProviderImplTest {
|
||||
|
||||
private final ComponentName DEVICE_OWNER = new ComponentName("dummy", "component");
|
||||
private final String DEVICE_OWNER_ORGANIZATION = new String("ACME");
|
||||
private final Date TIMESTAMP = new Date(2011, 11, 11);
|
||||
private final int MY_USER_ID = UserHandle.myUserId();
|
||||
private final int MANAGED_PROFILE_USER_ID = MY_USER_ID + 1;
|
||||
@@ -61,6 +68,7 @@ public final class EnterprisePrivacyFeatureProviderImplTest {
|
||||
private @Mock PackageManagerWrapper mPackageManager;
|
||||
private @Mock UserManager mUserManager;
|
||||
private @Mock ConnectivityManagerWrapper mConnectivityManger;
|
||||
private Resources mResources;
|
||||
|
||||
private EnterprisePrivacyFeatureProvider mProvider;
|
||||
|
||||
@@ -72,9 +80,10 @@ public final class EnterprisePrivacyFeatureProviderImplTest {
|
||||
.thenReturn(true);
|
||||
when(mUserManager.getProfiles(MY_USER_ID)).thenReturn(mProfiles);
|
||||
mProfiles.add(new UserInfo(MY_USER_ID, "", "", 0 /* flags */));
|
||||
mResources = ShadowApplication.getInstance().getApplicationContext().getResources();
|
||||
|
||||
mProvider = new EnterprisePrivacyFeatureProviderImpl(mDevicePolicyManager, mPackageManager,
|
||||
mUserManager, mConnectivityManger);
|
||||
mUserManager, mConnectivityManger, mResources);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -95,6 +104,33 @@ public final class EnterprisePrivacyFeatureProviderImplTest {
|
||||
assertThat(mProvider.isInCompMode()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeviceOwnerDisclosure() {
|
||||
final Context context = mock(Context.class);
|
||||
|
||||
when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(null);
|
||||
assertThat(mProvider.getDeviceOwnerDisclosure(context)).isNull();
|
||||
|
||||
SpannableStringBuilder disclosure = new SpannableStringBuilder();
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_generic));
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_learn_more),
|
||||
new EnterprisePrivacyFeatureProviderImpl.EnterprisePrivacySpan(context), 0);
|
||||
when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(DEVICE_OWNER);
|
||||
when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
|
||||
assertThat(mProvider.getDeviceOwnerDisclosure(context)).isEqualTo(disclosure);
|
||||
|
||||
disclosure = new SpannableStringBuilder();
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_with_name,
|
||||
DEVICE_OWNER_ORGANIZATION));
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_learn_more),
|
||||
new EnterprisePrivacyFeatureProviderImpl.EnterprisePrivacySpan(context), 0);
|
||||
when(mDevicePolicyManager.getDeviceOwnerOrganizationName())
|
||||
.thenReturn(DEVICE_OWNER_ORGANIZATION);
|
||||
assertThat(mProvider.getDeviceOwnerDisclosure(context)).isEqualTo(disclosure);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastSecurityLogRetrievalTime() {
|
||||
when(mDevicePolicyManager.getLastSecurityLogRetrievalTime()).thenReturn(-1L);
|
||||
|
Reference in New Issue
Block a user