NsdService: do not use ContentResolver directly

This patch changes NsdService to call registerContentObserver in the
ContentResolver class indirectly through NsdSettings.

This allows to easily intercept it and mock it in unit tests, and solves
test failures on the internal master branch where
registerContentObserver uses final or static methods that cannot be
worked around.

Bug: 32561414
Bug: 62044295
Test: runtest -x frameworks/base/tests/net/../NsdServiceTest.java
Change-Id: If4deb106de551746babb70196b20f21ece478850
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index 2158f60..5f6bd59 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
+import android.net.Uri;
 import android.net.nsd.NsdServiceInfo;
 import android.net.nsd.DnsSdTxtRecord;
 import android.net.nsd.INsdManager;
@@ -96,16 +97,15 @@
          * Observes the NSD on/off setting, and takes action when changed.
          */
         private void registerForNsdSetting() {
-            ContentObserver contentObserver = new ContentObserver(this.getHandler()) {
+            final ContentObserver contentObserver = new ContentObserver(this.getHandler()) {
                 @Override
                 public void onChange(boolean selfChange) {
                     notifyEnabled(isNsdEnabled());
                 }
             };
 
-            mContext.getContentResolver().registerContentObserver(
-                    Settings.Global.getUriFor(Settings.Global.NSD_ON),
-                    false, contentObserver);
+            final Uri uri = Settings.Global.getUriFor(Settings.Global.NSD_ON);
+            mNsdSettings.registerContentObserver(uri, contentObserver);
         }
 
         NsdStateMachine(String name, Handler handler) {
@@ -885,13 +885,18 @@
         }
     }
 
+    /**
+     * Interface which encapsulates dependencies of NsdService that are hard to mock, hard to
+     * override, or have side effects on global state in unit tests.
+     */
     @VisibleForTesting
     public interface NsdSettings {
         boolean isEnabled();
         void putEnabledStatus(boolean isEnabled);
+        void registerContentObserver(Uri uri, ContentObserver observer);
 
         static NsdSettings makeDefault(Context context) {
-            ContentResolver resolver = context.getContentResolver();
+            final ContentResolver resolver = context.getContentResolver();
             return new NsdSettings() {
                 @Override
                 public boolean isEnabled() {
@@ -902,6 +907,11 @@
                 public void putEnabledStatus(boolean isEnabled) {
                     Settings.Global.putInt(resolver, Settings.Global.NSD_ON, isEnabled ? 1 : 0);
                 }
+
+                @Override
+                public void registerContentObserver(Uri uri, ContentObserver observer) {
+                    resolver.registerContentObserver(uri, false, observer);
+                }
             };
         }
     }