Add Enterprise Privacy page to Settings

This adds a new page to Settings which tells the user about his/her
privacy in light of enterprise management. The new page is only shown
on devices that have a Device Owner app set.

This CL adds a mostly blank page. Follow-up CLs will populate the page
with information about specific admin actions/policies.

The page's title ("Privacy"), icon and location in the Settings app are
tentative. The page will move to its final location once the new IA
redesign is finished.

Test: make RunSettingsRoboTests
BUG: 32692748

Change-Id: I5b5c08c0025207516b0779f54cf68234a4ba3fe4
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 85fb334..06941d0 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -158,6 +158,7 @@
     public static class TestingSettingsActivity extends SettingsActivity { /* empty */ }
     public static class WifiAPITestActivity extends SettingsActivity { /* empty */ }
     public static class WifiInfoActivity extends SettingsActivity { /* empty */ }
+    public static class EnterprisePrivacySettingsActivity extends SettingsActivity { /* empty */ }
 
     // Categories.
     public static class WirelessSettings extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 949b6b7..f67f73f 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -94,6 +94,8 @@
 import com.android.settings.deviceinfo.StorageDashboardFragment;
 import com.android.settings.deviceinfo.StorageSettings;
 import com.android.settings.display.NightDisplaySettings;
+import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
+import com.android.settings.enterprise.EnterprisePrivacySettings;
 import com.android.settings.fuelgauge.BatterySaverSettings;
 import com.android.settings.fuelgauge.PowerUsageDetail;
 import com.android.settings.fuelgauge.PowerUsageSummary;
@@ -277,6 +279,7 @@
             Settings.AccessibilitySettingsActivity.class.getName(),
             Settings.PrintSettingsActivity.class.getName(),
             Settings.PaymentSettingsActivity.class.getName(),
+            Settings.EnterprisePrivacySettingsActivity.class.getName(),
 
             // New IA
             // Home page
@@ -416,6 +419,7 @@
             ConnectedDeviceDashboardFragment.class.getName(),
             AppAndNotificationDashboardFragment.class.getName(),
             UserAndAccountDashboardFragment.class.getName(),
+            EnterprisePrivacySettings.class.getName(),
     };
 
 
@@ -1219,6 +1223,11 @@
         setTileEnabled(new ComponentName(packageName,
                 BackupSettingsActivity.class.getName()), hasBackupActivity, isAdmin, pm);
 
+        setTileEnabled(new ComponentName(packageName,
+                Settings.EnterprisePrivacySettingsActivity.class.getName()),
+                FeatureFactory.getFactory(this).getEnterprisePrivacyFeatureProvider(this)
+                        .hasDeviceOwner(), isAdmin, pm);
+
     }
 
     private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin,
diff --git a/src/com/android/settings/fuelgauge/WallOfTextPreference.java b/src/com/android/settings/WallOfTextPreference.java
similarity index 99%
rename from src/com/android/settings/fuelgauge/WallOfTextPreference.java
rename to src/com/android/settings/WallOfTextPreference.java
index 6b29742..4cc2f67 100644
--- a/src/com/android/settings/fuelgauge/WallOfTextPreference.java
+++ b/src/com/android/settings/WallOfTextPreference.java
@@ -35,4 +35,4 @@
         final TextView summary = (TextView) view.findViewById(android.R.id.summary);
         summary.setMaxLines(20);
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java b/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java
new file mode 100644
index 0000000..3e45de0
--- /dev/null
+++ b/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java
@@ -0,0 +1,27 @@
+/*
+ * 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.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.
+public interface DevicePolicyManagerWrapper {
+    public ComponentName getDeviceOwnerComponentOnAnyUser();
+}
diff --git a/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java b/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java
new file mode 100644
index 0000000..87adcd6
--- /dev/null
+++ b/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+
+public class DevicePolicyManagerWrapperImpl implements DevicePolicyManagerWrapper {
+    private final DevicePolicyManager mDpm;
+
+    public DevicePolicyManagerWrapperImpl(DevicePolicyManager dpm) {
+        mDpm = dpm;
+    }
+
+    public ComponentName getDeviceOwnerComponentOnAnyUser() {
+        return mDpm.getDeviceOwnerComponentOnAnyUser();
+    }
+}
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
new file mode 100644
index 0000000..e2fb0a3
--- /dev/null
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
@@ -0,0 +1,21 @@
+/*
+ * 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;
+
+public interface EnterprisePrivacyFeatureProvider {
+    boolean hasDeviceOwner();
+}
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
new file mode 100644
index 0000000..3d35c23
--- /dev/null
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
@@ -0,0 +1,39 @@
+/*
+ * 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.pm.PackageManager;
+import android.content.Context;
+
+public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFeatureProvider {
+
+    private final Context mContext;
+    private final DevicePolicyManagerWrapper mDpm;
+
+    public EnterprisePrivacyFeatureProviderImpl(Context context, DevicePolicyManagerWrapper dpm) {
+        mContext = context.getApplicationContext();
+        mDpm = dpm;
+    }
+
+    @Override
+    public boolean hasDeviceOwner() {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
+            return false;
+        }
+        return mDpm.getDeviceOwnerComponentOnAnyUser() != null;
+    }
+}
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
new file mode 100644
index 0000000..a2d1a30
--- /dev/null
+++ b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
@@ -0,0 +1,71 @@
+/*
+ * 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.os.Bundle;
+import android.provider.SearchIndexableResource;
+
+import com.android.settings.R;
+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 java.util.Arrays;
+import java.util.List;
+
+public class EnterprisePrivacySettings extends DashboardFragment {
+
+    static final String TAG = "EnterprisePrivacySettings";
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsEvent.ENTERPRISE_PRIVACY_SETTINGS;
+    }
+
+    @Override
+    protected String getCategoryKey() {
+        return null;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.enterprise_privacy_settings;
+    }
+
+    @Override
+    protected List<PreferenceController> getPreferenceControllers(Context context) {
+        return null;
+    }
+
+    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+        new BaseSearchIndexProvider() {
+            @Override
+            public List<SearchIndexableResource> getXmlResourcesToIndex(
+                    Context context, boolean enabled) {
+                final SearchIndexableResource sir = new SearchIndexableResource(context);
+                sir.xmlResId = R.xml.enterprise_privacy_settings;
+                return Arrays.asList(sir);
+            }
+        };
+}
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index 515975b..55ea4bb 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -24,6 +24,7 @@
 import com.android.settings.applications.ApplicationFeatureProvider;
 import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
+import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
 import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
 import com.android.settings.localepicker.LocaleFeatureProvider;
 
@@ -76,6 +77,8 @@
 
     public abstract LocaleFeatureProvider getLocaleFeatureProvider();
 
+    public abstract EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(
+            Context context);
 
     public static final class FactoryNotFoundException extends RuntimeException {
         public FactoryNotFoundException(Throwable throwable) {
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index 934021d..ec0ff46 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.overlay;
 
+import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.support.annotation.Keep;
 
@@ -25,6 +26,9 @@
 import com.android.settings.core.instrumentation.MetricsFeatureProviderImpl;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProviderImpl;
+import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl;
+import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
+import com.android.settings.enterprise.EnterprisePrivacyFeatureProviderImpl;
 import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
 import com.android.settings.localepicker.LocaleFeatureProvider;
 import com.android.settings.localepicker.LocaleFeatureProviderImpl;
@@ -39,6 +43,7 @@
     private MetricsFeatureProvider mMetricsFeatureProvider;
     private DashboardFeatureProviderImpl mDashboardFeatureProvider;
     private LocaleFeatureProvider mLocaleFeatureProvider;
+    private EnterprisePrivacyFeatureProvider mEnterprisePrivacyFeatureProvider;
 
     @Override
     public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -81,4 +86,14 @@
         }
         return mLocaleFeatureProvider;
     }
+
+    @Override
+    public EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(Context context) {
+        if (mEnterprisePrivacyFeatureProvider == null) {
+            mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(context,
+                    new DevicePolicyManagerWrapperImpl((DevicePolicyManager)context
+                            .getSystemService(Context.DEVICE_POLICY_SERVICE)));
+        }
+        return mEnterprisePrivacyFeatureProvider;
+    }
 }
diff --git a/src/com/android/settings/search/Ranking.java b/src/com/android/settings/search/Ranking.java
index e9ceb85..1070200 100644
--- a/src/com/android/settings/search/Ranking.java
+++ b/src/com/android/settings/search/Ranking.java
@@ -37,6 +37,7 @@
 import com.android.settings.deviceinfo.StorageDashboardFragment;
 import com.android.settings.deviceinfo.StorageSettings;
 import com.android.settings.display.ScreenZoomSettings;
+import com.android.settings.enterprise.EnterprisePrivacySettings;
 import com.android.settings.fuelgauge.BatterySaverSettings;
 import com.android.settings.fuelgauge.PowerUsageSummary;
 import com.android.settings.gestures.GestureSettings;
@@ -170,6 +171,7 @@
 
         // Privacy
         sRankMap.put(PrivacySettings.class.getName(), RANK_PRIVACY);
+        sRankMap.put(EnterprisePrivacySettings.class.getName(), RANK_PRIVACY);
 
         // Date / Time
         sRankMap.put(DateTimeSettings.class.getName(), RANK_DATE_TIME);
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 1b8e0be..7888c0f 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -38,6 +38,7 @@
 import com.android.settings.deviceinfo.StorageDashboardFragment;
 import com.android.settings.deviceinfo.StorageSettings;
 import com.android.settings.display.ScreenZoomSettings;
+import com.android.settings.enterprise.EnterprisePrivacySettings;
 import com.android.settings.fuelgauge.BatterySaverSettings;
 import com.android.settings.fuelgauge.PowerUsageSummary;
 import com.android.settings.gestures.GestureSettings;
@@ -335,12 +336,20 @@
                         NO_DATA_RES_ID,
                         SystemDashboardFragment.class.getName(),
                         R.drawable.ic_settings_about));
+
         sResMap.put(StorageDashboardFragment.class.getName(),
                 new SearchIndexableResource(
                         Ranking.getRankForClassName(StorageDashboardFragment.class.getName()),
                         NO_DATA_RES_ID,
                         StorageDashboardFragment.class.getName(),
                         R.drawable.ic_settings_storage));
+
+        sResMap.put(EnterprisePrivacySettings.class.getName(),
+                new SearchIndexableResource(
+                        Ranking.getRankForClassName(EnterprisePrivacySettings.class.getName()),
+                        NO_DATA_RES_ID,
+                        EnterprisePrivacySettings.class.getName(),
+                        R.drawable.ic_settings_about));
     }
 
     private SearchIndexableResources() {