Stub APIs for network scoring.

NetworkScoreManager defines all interactions between the framework and
the scorer app. An ACTION_SCORE_NETWORKS broadcast is sent to the
default scorer with any unscored networks, which responds by calling
updateScores() with scores for those networks. An app may also check
whether they are currently the default scorer with
getDefaultScorerPackage() and request to become the default via the
ACTION_CHANGE_DEFAULT broadcast.

Bug: 13786258
Change-Id: Id3dc0f7c1109f0e3afd73356e2475b7f34167419
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f444680..77b5485 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -72,6 +72,7 @@
 import android.net.IConnectivityManager;
 import android.net.INetworkPolicyManager;
 import android.net.NetworkPolicyManager;
+import android.net.NetworkScoreManager;
 import android.net.Uri;
 import android.net.nsd.INsdManager;
 import android.net.nsd.NsdManager;
@@ -654,6 +655,12 @@
                 ITvInputManager service = ITvInputManager.Stub.asInterface(iBinder);
                 return new TvInputManager(service, UserHandle.myUserId());
             }});
+
+        registerService(NETWORK_SCORE_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                return new NetworkScoreManager(ctx);
+            }
+        });
     }
 
     static ContextImpl getImpl(Context context) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 15cb9e9..ff92d82 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2643,6 +2643,14 @@
     public static final String TV_INPUT_SERVICE = "tv_input";
 
     /**
+     * {@link android.net.NetworkScoreManager} for managing network scoring.
+     * @see #getSystemService
+     * @see android.net.NetworkScoreManager
+     * @hide
+     */
+    public static final String NETWORK_SCORE_SERVICE = "network_score";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
new file mode 100644
index 0000000..3430547
--- /dev/null
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2014 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 android.net;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
+
+/**
+ * Class that manages communication between network subsystems and a network scorer.
+ *
+ * <p>You can get an instance of this class by calling
+ * {@link android.content.Context#getSystemService(String)}:
+ *
+ * <pre>NetworkScoreManager manager =
+ *     (NetworkScoreManager) getSystemService(Context.NETWORK_SCORE_SERVICE)</pre>
+ *
+ * <p>A network scorer is any application which:
+ * <ul>
+ * <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission.
+ * <li>Includes a receiver for {@link #ACTION_SCORE_NETWORKS} guarded by the
+ *     {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission which scores networks
+ *     and (eventually) calls {@link #updateScores} with the results.
+ * </ul>
+ *
+ * <p>The system keeps track of a default scorer application; at any time, only this application
+ * will receive {@link #ACTION_SCORE_NETWORKS} broadcasts and will be permitted to call
+ * {@link #updateScores}. Applications may determine the current default scorer with
+ * {@link #getDefaultScorerPackage()} and request to change the default scorer by sending an
+ * {@link #ACTION_CHANGE_DEFAULT} broadcast with another scorer.
+ *
+ * @hide
+ */
+public class NetworkScoreManager {
+    /**
+     * Activity action: ask the user to change the default network scorer. This will show a dialog
+     * that asks the user whether they want to replace the current default scorer with the one
+     * specified in {@link #EXTRA_PACKAGE_NAME}. The activity will finish with RESULT_OK if the
+     * default was changed or RESULT_CANCELED if it failed for any reason.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_CHANGE_DEFAULT = "android.net.scoring.CHANGE_DEFAULT";
+
+    /**
+     * Extra used with {@link #ACTION_CHANGE_DEFAULT} to specify the new scorer package. Set with
+     * {@link android.content.Intent#putExtra(String, String)}.
+     */
+    public static final String EXTRA_PACKAGE_NAME = "packageName";
+
+    /**
+     * Broadcast action: new network scores are being requested. This intent will only be delivered
+     * to the current default scorer app. That app is responsible for scoring the networks and
+     * calling {@link #updateScores} when complete. The networks to score are specified in
+     * {@link #EXTRA_NETWORKS_TO_SCORE}, and will generally consist of all networks which have been
+     * configured by the user as well as any open networks.
+     *
+     * <p class="note">This is a protected intent that can only be sent by the system.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    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";
+
+    private final Context mContext;
+
+    /** @hide */
+    public NetworkScoreManager(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Obtain the package name of the current default network scorer.
+     *
+     * At any time, only one scorer application will receive {@link #ACTION_SCORE_NETWORKS}
+     * broadcasts and be allowed to call {@link #updateScores}. Applications may use this method to
+     * determine the current scorer and offer the user the ability to select a different scorer via
+     * the {@link #ACTION_CHANGE_DEFAULT} intent.
+     * @return the full package name of the current default scorer, or null if there is no active
+     *     scorer.
+     */
+    public String getDefaultScorerPackage() {
+        // TODO: Implement.
+        return null;
+    }
+
+    /**
+     * Update network scores.
+     *
+     * This may be called at any time to re-score active networks. Scores will generally be updated
+     * quickly, but if this method is called too frequently, the scores may be held and applied at
+     * a later time.
+     *
+     * @param networks the networks which have been scored by the scorer.
+     * @throws SecurityException if the caller is not the default scorer.
+     */
+    public void updateScores(ScoredNetwork[] networks) throws SecurityException {
+        // TODO: Implement.
+    }
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b2709af..606a4b1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -234,6 +234,7 @@
     <protected-broadcast android:name="android.net.conn.NETWORK_CONDITIONS_MEASURED" />
     <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.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE" />
     <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE" />
     <protected-broadcast android:name="android.intent.action.AIRPLANE_MODE" />
@@ -762,6 +763,13 @@
         android:description="@string/permdesc_changeWimaxState"
         android:label="@string/permlab_changeWimaxState" />
 
+    <!-- Allows applications to act as network scorers. @hide -->
+    <permission android:name="android.permission.SCORE_NETWORKS"
+        android:permissionGroup="android.permission-group.NETWORK"
+        android:protectionLevel="normal"
+        android:description="@string/permdesc_scoreNetworks"
+        android:label="@string/permlab_scoreNetworks" />
+
     <!-- ======================================= -->
     <!-- Permissions for short range, peripheral networks -->
     <!-- ======================================= -->
@@ -2290,6 +2298,13 @@
         android:description="@string/permdesc_broadcastWapPush"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to broadcast a SCORE_NETWORKS request.
+         <p>Not for use by third-party applications. @hide -->
+    <permission android:name="android.permission.BROADCAST_SCORE_NETWORKS"
+        android:label="@string/permlab_broadcastScoreNetworks"
+        android:description="@string/permdesc_broadcastScoreNetworks"
+        android:protectionLevel="signature|system" />
+
     <!-- Not for use by third-party applications. -->
     <permission android:name="android.permission.MASTER_CLEAR"
         android:label="@string/permlab_masterClear"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 35f761b..b0e1150 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -906,6 +906,14 @@
         silently replace the content of any webpage with malicious variants.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_broadcastScoreNetworks">send score networks broadcast</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_broadcastScoreNetworks">Allows the app
+        to broadcast a notification that networks need to be scored.
+        Never needed for normal apps.
+    </string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_setProcessLimit">limit number of running processes</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_setProcessLimit">Allows the app
@@ -1881,6 +1889,15 @@
       connect the phone to and disconnect the phone from WiMAX networks.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_scoreNetworks">score networks</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_scoreNetworks" product="tablet">Allows the app to
+      rank networks and influence which networks the tablet should prefer.</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_scoreNetworks" product="default">Allows the app to
+        rank networks and influence which networks the phone should prefer.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_bluetooth">pair with Bluetooth devices</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_bluetooth" product="tablet">Allows the app to view the