Add settings VR listener service.

Bug: 22855417
Bug: 26724891

- Adds a settings panel allowing users to toggle the
  enabled/disabled state of each VrListenerService
  component installed.
- If disabled, a VrListenerService will not be bound
  from the framework, even when requested by a VR
  application.

Change-Id: I606eb712c011d160b9fbdd3c0e8fd744c653ef07
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ceea92e..b6fb084 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2449,6 +2449,22 @@
                        android:value="com.android.settings.notification.NotificationAccessSettings" />
         </activity>
 
+        <activity android:name="Settings$VrListenersSettingsActivity"
+                  android:label="@string/vr_listeners_title"
+                  android:taskAffinity="">
+            <intent-filter android:priority="1">
+                <action android:name="android.settings.VR_LISTENER_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                       android:value="com.android.settings.applications.VrListenerSettings" />
+        </activity>
+
+
         <activity android:name="Settings$ZenAccessSettingsActivity"
                   android:label="@string/manage_zen_access_title"
                   android:taskAffinity="">
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 62476f7..b9207cd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6019,6 +6019,23 @@
         It will also be able to dismiss notifications or trigger action buttons they contain.
     </string>
 
+    <!-- Title for managing VR (virtual reality) helper services. [CHAR LIMIT=50] -->
+    <string name="vr_listeners_title">VR helper services</string>
+
+    <!-- String to show in the list of vr listeners, when none is installed -->
+    <string name="no_vr_listeners">No installed apps have requested to be run as VR helper services.</string>
+
+    <!-- Title for a warning message about security implications of enabling a VR
+          listener, displayed as a dialog message. [CHAR LIMIT=NONE] -->
+    <string name="vr_listener_security_warning_title">Allow VR service access for
+         <xliff:g id="service" example="VrCore">%1$s</xliff:g>?</string>
+    <!-- Summary for a warning message about security implications of enabling a VR
+          listener, displayed as a dialog message. [CHAR LIMIT=NONE] -->
+    <string name="vr_listener_security_warning_summary">
+        <xliff:g id="vr_listener_name">%1$s</xliff:g> will be able to run when you are using
+        applications in virtual reality mode.
+    </string>
+
     <!-- Sound & notification > Advanced section: Title for managing Do Not Disturb access option. [CHAR LIMIT=40] -->
     <string name="manage_zen_access_title">Do Not Disturb access</string>
 
@@ -6883,6 +6900,8 @@
     <!-- Description of allowing overlay setting [CHAR LIMIT=NONE] -->
     <string name="allow_overlay_description">This permission allows an app to display on top of other apps you\u2019re using and may interfere with your use of the interface in other applications, or change what you think you are seeing in other applications.</string>
 
+    <!-- Keyword for VR settinsg -->
+    <string name="keywords_vr_listener">vr virtual reality listener stereo helper service</string>
     <!-- Keyword for SYSTEM_ALERT_WINDOW -->
     <string name="keywords_system_alert_window">system alert window dialog draw on top other apps</string>
     <!-- Main settings screen item's title to go into the overlay settings screen [CHAR LIMIT=30] -->
diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml
index 9b404df..5adf20c 100644
--- a/res/xml/special_access.xml
+++ b/res/xml/special_access.xml
@@ -49,6 +49,16 @@
     </PreferenceScreen>
 
     <PreferenceScreen
+        android:key="enabled_vr_listeners"
+        android:title="@string/vr_listeners_title"
+        android:fragment="com.android.settings.applications.VrListenerSettings"
+        settings:keywords="@string/keywords_vr_listener">
+        <extra
+            android:name="classname"
+            android:value="com.android.settings.Settings$VrListenersSettingsActivity" />
+    </PreferenceScreen>
+
+    <PreferenceScreen
         android:key="write_settings_apps"
         android:title="@string/write_settings"
         android:fragment="com.android.settings.applications.ManageApplications"
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 95aa700..458fa2f 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -95,6 +95,7 @@
     public static class NotificationStationActivity extends SettingsActivity { /* empty */ }
     public static class UserSettingsActivity extends SettingsActivity { /* empty */ }
     public static class NotificationAccessSettingsActivity extends SettingsActivity { /* empty */ }
+    public static class VrListenerSettingsActivity extends SettingsActivity { /* empty */ }
     public static class ZenAccessSettingsActivity extends SettingsActivity { /* empty */ }
     public static class ConditionProviderSettingsActivity extends SettingsActivity { /* empty */ }
     public static class UsbSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/applications/VrListenerSettings.java b/src/com/android/settings/applications/VrListenerSettings.java
new file mode 100644
index 0000000..571e85d
--- /dev/null
+++ b/src/com/android/settings/applications/VrListenerSettings.java
@@ -0,0 +1,51 @@
+/*
+ * 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.applications;
+
+import android.provider.Settings;
+import android.service.vr.VrListenerService;
+
+import com.android.internal.logging.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.utils.ManagedServiceSettings;
+
+public class VrListenerSettings extends ManagedServiceSettings {
+    private static final String TAG = VrListenerSettings.class.getSimpleName();
+    private static final Config CONFIG = getVrListenerConfig();
+
+    private static final Config getVrListenerConfig() {
+        final Config c = new Config();
+        c.tag = TAG;
+        c.setting = Settings.Secure.ENABLED_VR_LISTENERS;
+        c.intentAction = VrListenerService.SERVICE_INTERFACE;
+        c.permission = android.Manifest.permission.BIND_VR_LISTENER_SERVICE;
+        c.noun = "vr listener";
+        c.warningDialogTitle = R.string.vr_listener_security_warning_title;
+        c.warningDialogSummary = R.string.vr_listener_security_warning_summary;
+        c.emptyText = R.string.no_vr_listeners;
+        return c;
+    }
+
+    @Override
+    protected Config getConfig() {
+        return CONFIG;
+    }
+
+    @Override
+    protected int getMetricsCategory() {
+        return MetricsEvent.VR_MANAGE_LISTENERS;
+    }
+}
diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java
index b40fbda..0111a38 100644
--- a/src/com/android/settings/notification/NotificationAccessSettings.java
+++ b/src/com/android/settings/notification/NotificationAccessSettings.java
@@ -23,6 +23,8 @@
 
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.R;
+import com.android.settings.utils.ManagedServiceSettings;
+import com.android.settings.utils.ServiceListing;
 
 public class NotificationAccessSettings extends ManagedServiceSettings {
     private static final String TAG = NotificationAccessSettings.class.getSimpleName();
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index f1546aa..d38c580 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -42,7 +42,8 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.notification.ManagedServiceSettings.Config;
+import com.android.settings.utils.ManagedServiceSettings.Config;
+import com.android.settings.utils.ServiceListing;
 
 import java.lang.ref.WeakReference;
 import java.util.Arrays;
diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
index 8ae2274..05f42d8 100644
--- a/src/com/android/settings/notification/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
@@ -35,6 +35,7 @@
 import android.widget.TextView;
 
 import com.android.settings.R;
+import com.android.settings.utils.ServiceListing;
 
 import java.lang.ref.WeakReference;
 import java.text.Collator;
diff --git a/src/com/android/settings/notification/ManagedServiceSettings.java b/src/com/android/settings/utils/ManagedServiceSettings.java
similarity index 98%
rename from src/com/android/settings/notification/ManagedServiceSettings.java
rename to src/com/android/settings/utils/ManagedServiceSettings.java
index 56c7b69..e198955 100644
--- a/src/com/android/settings/notification/ManagedServiceSettings.java
+++ b/src/com/android/settings/utils/ManagedServiceSettings.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.notification;
+package com.android.settings.utils;
 
 import android.annotation.Nullable;
 import android.app.AlertDialog;
@@ -34,6 +34,7 @@
 import android.view.View;
 import android.widget.TextView;
 import com.android.settings.R;
+import com.android.settings.notification.EmptyTextSettings;
 
 import java.util.Collections;
 import java.util.List;
diff --git a/src/com/android/settings/notification/ServiceListing.java b/src/com/android/settings/utils/ServiceListing.java
similarity index 98%
rename from src/com/android/settings/notification/ServiceListing.java
rename to src/com/android/settings/utils/ServiceListing.java
index 161611d..dfca5a3 100644
--- a/src/com/android/settings/notification/ServiceListing.java
+++ b/src/com/android/settings/utils/ServiceListing.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.notification;
+package com.android.settings.utils;
 
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
@@ -32,7 +32,7 @@
 import android.provider.Settings;
 import android.util.Slog;
 
-import com.android.settings.notification.ManagedServiceSettings.Config;
+import com.android.settings.utils.ManagedServiceSettings.Config;
 
 import java.util.ArrayList;
 import java.util.Arrays;