diff --git a/res/values/strings.xml b/res/values/strings.xml
index 54ed1dfd762..f7f438c2fde 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8034,6 +8034,14 @@
Always-on VPN turned on in your work profile
Global HTTP proxy set
+
+ This device is managed.
+
+ This device is managed by %s.
+
+ " "
+
+ Learn more
Photos & Videos
diff --git a/src/com/android/settings/accounts/ChooseAccountActivity.java b/src/com/android/settings/accounts/ChooseAccountActivity.java
index ea39426f436..6f0c110ab3a 100644
--- a/src/com/android/settings/accounts/ChooseAccountActivity.java
+++ b/src/com/android/settings/accounts/ChooseAccountActivity.java
@@ -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 mProviderList = new ArrayList();
@@ -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 getAuthoritiesForAccountType(String type) {
if (mAccountTypeToAuthorities == null) {
mAccountTypeToAuthorities = Maps.newHashMap();
diff --git a/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java b/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java
index a23448ebd43..5be78849280 100644
--- a/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java
+++ b/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java
@@ -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()}.
*
diff --git a/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java b/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java
index d122ec645ef..6e162a8bf59 100644
--- a/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java
+++ b/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java
@@ -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) {
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
index 43f69032a13..91ad119a7fc 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
@@ -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.
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
index 9fbb0835721..bb5412b8cbc 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
@@ -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;
+ }
+ }
}
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index 18fcaafaa1e..342ac731c64 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -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;
}
diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java
index 8495603482f..458959ca653 100644
--- a/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java
+++ b/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java
@@ -198,7 +198,7 @@ public final class InstalledAppCounterTest {
}
}
- private class IsLaunchIntentFor extends ArgumentMatcher {
+ private static class IsLaunchIntentFor extends ArgumentMatcher {
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 categories = intent.getCategories();
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
index be1296cbe9a..7724db8f84f 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
@@ -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);