Add a SCORER_CHANGED broadcast.

Sent whenever the active network scorer is changed.

Bug: 16007033
Change-Id: Ib71e89e2cc98fa424db7e489445ec03edefb6880
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index c09492c..c599dfc 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -81,6 +81,13 @@
     public static final String ACTION_SCORE_NETWORKS = "android.net.scoring.SCORE_NETWORKS";
 
     /**
+     * Extra used with {@link #ACTION_SCORE_NETWORKS} to specify the networks to be scored, as an
+     * array of {@link NetworkKey}s. Can be obtained with
+     * {@link android.content.Intent#getParcelableArrayExtra(String)}}.
+     */
+    public static final String EXTRA_NETWORKS_TO_SCORE = "networksToScore";
+
+    /**
      * Activity action: launch a custom activity for configuring a scorer before enabling it.
      * Scorer applications may choose to specify an activity for this action, in which case the
      * framework will launch that activity which should return RESULT_OK if scoring was enabled.
@@ -92,11 +99,24 @@
     public static final String ACTION_CUSTOM_ENABLE = "android.net.scoring.CUSTOM_ENABLE";
 
     /**
-     * Extra used with {@link #ACTION_SCORE_NETWORKS} to specify the networks to be scored, as an
-     * array of {@link NetworkKey}s. Can be obtained with
-     * {@link android.content.Intent#getParcelableArrayExtra(String)}}.
+     * Broadcast action: the active scorer has been changed. Scorer apps may listen to this to
+     * perform initialization once selected as the active scorer, or clean up unneeded resources
+     * if another scorer has been selected. Note that it is unnecessary to clear existing scores as
+     * this is handled by the system.
+     *
+     * <p>The new scorer will be specified in {@link #EXTRA_NEW_SCORER}.
+     *
+     * <p class="note">This is a protected intent that can only be sent by the system.
      */
-    public static final String EXTRA_NETWORKS_TO_SCORE = "networksToScore";
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SCORER_CHANGED = "android.net.scoring.SCORER_CHANGED";
+
+    /**
+     * Extra used with {@link #ACTION_SCORER_CHANGED} to specify the newly selected scorer's package
+     * name. Will be null if scoring was disabled. Can be obtained with
+     * {@link android.content.Intent#getStringExtra(String)}.
+     */
+    public static final String EXTRA_NEW_SCORER = "newScorer";
 
     private final Context mContext;
     private final INetworkScoreService mService;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 450a889..e675dc7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -254,6 +254,7 @@
     <protected-broadcast
             android:name="android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED" />
     <protected-broadcast android:name="android.net.scoring.SCORE_NETWORKS" />
+    <protected-broadcast android:name="android.net.scoring.SCORER_CHANGED" />
     <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE" />
     <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE" />
     <protected-broadcast android:name="android.intent.action.AIRPLANE_MODE" />
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 1b71518..538501b 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -18,10 +18,12 @@
 
 import android.Manifest.permission;
 import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.net.INetworkScoreCache;
 import android.net.INetworkScoreService;
+import android.net.NetworkScoreManager;
 import android.net.NetworkScorerAppManager;
 import android.net.NetworkScorerAppManager.NetworkScorerAppData;
 import android.net.ScoredNetwork;
@@ -133,7 +135,13 @@
         // as scores should never be compared across apps; in practice, Settings should only be
         // allowing valid apps to be set as scorers, so failure here should be rare.
         clearInternal();
-        return NetworkScorerAppManager.setActiveScorer(mContext, packageName);
+        boolean result = NetworkScorerAppManager.setActiveScorer(mContext, packageName);
+        if (result) {
+            Intent intent = new Intent(NetworkScoreManager.ACTION_SCORER_CHANGED);
+            intent.putExtra(NetworkScoreManager.EXTRA_NEW_SCORER, packageName);
+            mContext.sendBroadcast(intent);
+        }
+        return result;
     }
 
     /** Clear scores. Callers are responsible for checking permissions as appropriate. */