Expose the scan API and network select API.

Bug: 67748005
Test: Basic telephony sanity
Change-Id: I54aa5d5eacfeb39ada14e843917fe08e382e79de
diff --git a/api/current.txt b/api/current.txt
index 79eae18..ead3d02 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -40047,6 +40047,34 @@
     field public static final int UNKNOWN_RSSI = 99; // 0x63
   }
 
+  public class NetworkScan {
+    method public void stop() throws android.os.RemoteException;
+    field public static final int ERROR_INTERRUPTED = 10002; // 0x2712
+    field public static final int ERROR_INVALID_SCAN = 2; // 0x2
+    field public static final int ERROR_INVALID_SCANID = 10001; // 0x2711
+    field public static final int ERROR_MODEM_ERROR = 1; // 0x1
+    field public static final int ERROR_MODEM_UNAVAILABLE = 3; // 0x3
+    field public static final int ERROR_RADIO_INTERFACE_ERROR = 10000; // 0x2710
+    field public static final int ERROR_UNSUPPORTED = 4; // 0x4
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public final class NetworkScanRequest implements android.os.Parcelable {
+    ctor public NetworkScanRequest(int, android.telephony.RadioAccessSpecifier[], int, int, boolean, int, java.util.ArrayList<java.lang.String>);
+    method public int describeContents();
+    method public boolean getIncrementalResults();
+    method public int getIncrementalResultsPeriodicity();
+    method public int getMaxSearchTime();
+    method public java.util.ArrayList<java.lang.String> getPlmns();
+    method public int getScanType();
+    method public int getSearchPeriodicity();
+    method public android.telephony.RadioAccessSpecifier[] getSpecifiers();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.NetworkScanRequest> CREATOR;
+    field public static final int SCAN_TYPE_ONE_SHOT = 0; // 0x0
+    field public static final int SCAN_TYPE_PERIODIC = 1; // 0x1
+  }
+
   public class PhoneNumberFormattingTextWatcher implements android.text.TextWatcher {
     ctor public PhoneNumberFormattingTextWatcher();
     ctor public PhoneNumberFormattingTextWatcher(java.lang.String);
@@ -40139,6 +40167,121 @@
     field public static final int LISTEN_SIGNAL_STRENGTHS = 256; // 0x100
   }
 
+  public final class RadioAccessSpecifier implements android.os.Parcelable {
+    ctor public RadioAccessSpecifier(int, int[], int[]);
+    method public int describeContents();
+    method public int[] getBands();
+    method public int[] getChannels();
+    method public int getRadioAccessNetwork();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.RadioAccessSpecifier> CREATOR;
+  }
+
+  public final class RadioNetworkConstants {
+    ctor public RadioNetworkConstants();
+  }
+
+  public static final class RadioNetworkConstants.EutranBands {
+    ctor public RadioNetworkConstants.EutranBands();
+    field public static final int BAND_1 = 1; // 0x1
+    field public static final int BAND_10 = 10; // 0xa
+    field public static final int BAND_11 = 11; // 0xb
+    field public static final int BAND_12 = 12; // 0xc
+    field public static final int BAND_13 = 13; // 0xd
+    field public static final int BAND_14 = 14; // 0xe
+    field public static final int BAND_17 = 17; // 0x11
+    field public static final int BAND_18 = 18; // 0x12
+    field public static final int BAND_19 = 19; // 0x13
+    field public static final int BAND_2 = 2; // 0x2
+    field public static final int BAND_20 = 20; // 0x14
+    field public static final int BAND_21 = 21; // 0x15
+    field public static final int BAND_22 = 22; // 0x16
+    field public static final int BAND_23 = 23; // 0x17
+    field public static final int BAND_24 = 24; // 0x18
+    field public static final int BAND_25 = 25; // 0x19
+    field public static final int BAND_26 = 26; // 0x1a
+    field public static final int BAND_27 = 27; // 0x1b
+    field public static final int BAND_28 = 28; // 0x1c
+    field public static final int BAND_3 = 3; // 0x3
+    field public static final int BAND_30 = 30; // 0x1e
+    field public static final int BAND_31 = 31; // 0x1f
+    field public static final int BAND_33 = 33; // 0x21
+    field public static final int BAND_34 = 34; // 0x22
+    field public static final int BAND_35 = 35; // 0x23
+    field public static final int BAND_36 = 36; // 0x24
+    field public static final int BAND_37 = 37; // 0x25
+    field public static final int BAND_38 = 38; // 0x26
+    field public static final int BAND_39 = 39; // 0x27
+    field public static final int BAND_4 = 4; // 0x4
+    field public static final int BAND_40 = 40; // 0x28
+    field public static final int BAND_41 = 41; // 0x29
+    field public static final int BAND_42 = 42; // 0x2a
+    field public static final int BAND_43 = 43; // 0x2b
+    field public static final int BAND_44 = 44; // 0x2c
+    field public static final int BAND_45 = 45; // 0x2d
+    field public static final int BAND_46 = 46; // 0x2e
+    field public static final int BAND_47 = 47; // 0x2f
+    field public static final int BAND_48 = 48; // 0x30
+    field public static final int BAND_5 = 5; // 0x5
+    field public static final int BAND_6 = 6; // 0x6
+    field public static final int BAND_65 = 65; // 0x41
+    field public static final int BAND_66 = 66; // 0x42
+    field public static final int BAND_68 = 68; // 0x44
+    field public static final int BAND_7 = 7; // 0x7
+    field public static final int BAND_70 = 70; // 0x46
+    field public static final int BAND_8 = 8; // 0x8
+    field public static final int BAND_9 = 9; // 0x9
+  }
+
+  public static final class RadioNetworkConstants.GeranBands {
+    ctor public RadioNetworkConstants.GeranBands();
+    field public static final int BAND_450 = 3; // 0x3
+    field public static final int BAND_480 = 4; // 0x4
+    field public static final int BAND_710 = 5; // 0x5
+    field public static final int BAND_750 = 6; // 0x6
+    field public static final int BAND_850 = 8; // 0x8
+    field public static final int BAND_DCS1800 = 12; // 0xc
+    field public static final int BAND_E900 = 10; // 0xa
+    field public static final int BAND_ER900 = 14; // 0xe
+    field public static final int BAND_P900 = 9; // 0x9
+    field public static final int BAND_PCS1900 = 13; // 0xd
+    field public static final int BAND_R900 = 11; // 0xb
+    field public static final int BAND_T380 = 1; // 0x1
+    field public static final int BAND_T410 = 2; // 0x2
+    field public static final int BAND_T810 = 7; // 0x7
+  }
+
+  public static final class RadioNetworkConstants.RadioAccessNetworks {
+    ctor public RadioNetworkConstants.RadioAccessNetworks();
+    field public static final int EUTRAN = 3; // 0x3
+    field public static final int GERAN = 1; // 0x1
+    field public static final int UTRAN = 2; // 0x2
+  }
+
+  public static final class RadioNetworkConstants.UtranBands {
+    ctor public RadioNetworkConstants.UtranBands();
+    field public static final int BAND_1 = 1; // 0x1
+    field public static final int BAND_10 = 10; // 0xa
+    field public static final int BAND_11 = 11; // 0xb
+    field public static final int BAND_12 = 12; // 0xc
+    field public static final int BAND_13 = 13; // 0xd
+    field public static final int BAND_14 = 14; // 0xe
+    field public static final int BAND_19 = 19; // 0x13
+    field public static final int BAND_2 = 2; // 0x2
+    field public static final int BAND_20 = 20; // 0x14
+    field public static final int BAND_21 = 21; // 0x15
+    field public static final int BAND_22 = 22; // 0x16
+    field public static final int BAND_25 = 25; // 0x19
+    field public static final int BAND_26 = 26; // 0x1a
+    field public static final int BAND_3 = 3; // 0x3
+    field public static final int BAND_4 = 4; // 0x4
+    field public static final int BAND_5 = 5; // 0x5
+    field public static final int BAND_6 = 6; // 0x6
+    field public static final int BAND_7 = 7; // 0x7
+    field public static final int BAND_8 = 8; // 0x8
+    field public static final int BAND_9 = 9; // 0x9
+  }
+
   public class ServiceState implements android.os.Parcelable {
     ctor public ServiceState();
     ctor public ServiceState(android.telephony.ServiceState);
@@ -40416,12 +40559,15 @@
     method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
     method public boolean isWorldPhone();
     method public void listen(android.telephony.PhoneStateListener, int);
+    method public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, android.telephony.TelephonyScanManager.NetworkScanCallback);
     method public void sendDialerSpecialCode(java.lang.String);
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
     method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
     method public void sendVisualVoicemailSms(java.lang.String, int, java.lang.String, android.app.PendingIntent);
     method public void setDataEnabled(boolean);
     method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
+    method public void setNetworkSelectionModeAutomatic();
+    method public boolean setNetworkSelectionModeManual(java.lang.String, boolean);
     method public boolean setOperatorBrandOverride(java.lang.String);
     method public boolean setPreferredNetworkTypeToGlobal();
     method public void setVisualVoicemailSmsFilterSettings(android.telephony.VisualVoicemailSmsFilterSettings);
@@ -40509,6 +40655,17 @@
     method public void onReceiveUssdResponseFailed(android.telephony.TelephonyManager, java.lang.String, int);
   }
 
+  public final class TelephonyScanManager {
+    ctor public TelephonyScanManager();
+  }
+
+  public static abstract class TelephonyScanManager.NetworkScanCallback {
+    ctor public TelephonyScanManager.NetworkScanCallback();
+    method public void onComplete();
+    method public void onError(int);
+    method public void onResults(java.util.List<android.telephony.CellInfo>);
+  }
+
   public abstract class VisualVoicemailService extends android.app.Service {
     ctor public VisualVoicemailService();
     method public android.os.IBinder onBind(android.content.Intent);
diff --git a/telephony/java/android/telephony/NetworkScan.java b/telephony/java/android/telephony/NetworkScan.java
index f15fde8..a277212 100644
--- a/telephony/java/android/telephony/NetworkScan.java
+++ b/telephony/java/android/telephony/NetworkScan.java
@@ -19,50 +19,92 @@
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.annotation.IntDef;
 import android.util.Log;
 
 import com.android.internal.telephony.ITelephony;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
- * Allows applications to request the system to perform a network scan.
- *
- * The caller of {@link #requestNetworkScan(NetworkScanRequest, NetworkScanCallback)} will
- * receive a NetworkScan which contains the callback method to stop the scan requested.
- * @hide
+ * The caller of
+ * {@link TelephonyManager#requestNetworkScan(NetworkScanRequest, NetworkScanCallback)}
+ * will receive an instance of {@link NetworkScan}, which contains a callback method
+ * {@link #stop()} for stopping the in-progress scan.
  */
 public class NetworkScan {
 
-    public static final String TAG = "NetworkScan";
+    private static final String TAG = "NetworkScan";
 
     // Below errors are mapped from RadioError which is returned from RIL. We will consolidate
     // RadioErrors during the mapping if those RadioErrors mean no difference to the users.
+
+    /**
+     * Defines acceptable values of scan error code.
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({ERROR_MODEM_ERROR, ERROR_INVALID_SCAN, ERROR_MODEM_UNAVAILABLE, ERROR_UNSUPPORTED,
+            ERROR_RADIO_INTERFACE_ERROR, ERROR_INVALID_SCANID, ERROR_INTERRUPTED})
+    public @interface ScanErrorCode {}
+
+    /**
+     * The RIL has successfully performed the network scan.
+     */
     public static final int SUCCESS = 0;                    // RadioError:NONE
+
+    /**
+     * The scan has failed due to some modem errors.
+     */
     public static final int ERROR_MODEM_ERROR = 1;          // RadioError:RADIO_NOT_AVAILABLE
                                                             // RadioError:NO_MEMORY
                                                             // RadioError:INTERNAL_ERR
                                                             // RadioError:MODEM_ERR
                                                             // RadioError:OPERATION_NOT_ALLOWED
+
+    /**
+     * The parameters of the scan is invalid.
+     */
     public static final int ERROR_INVALID_SCAN = 2;         // RadioError:INVALID_ARGUMENTS
-    public static final int ERROR_MODEM_BUSY = 3;           // RadioError:DEVICE_IN_USE
+
+    /**
+     * The modem can not perform the scan because it is doing something else.
+     */
+    public static final int ERROR_MODEM_UNAVAILABLE = 3;    // RadioError:DEVICE_IN_USE
+
+    /**
+     * The modem does not support the request scan.
+     */
     public static final int ERROR_UNSUPPORTED = 4;          // RadioError:REQUEST_NOT_SUPPORTED
 
+
     // Below errors are generated at the Telephony.
-    public static final int ERROR_RIL_ERROR = 10000;        // Nothing or only exception is
-                                                            // returned from RIL.
-    public static final int ERROR_INVALID_SCANID = 10001;   // The scanId is invalid. The user is
-                                                            // either trying to stop a scan which
-                                                            // does not exist or started by others.
-    public static final int ERROR_INTERRUPTED = 10002;      // Scan was interrupted by another scan
-                                                            // with higher priority.
+
+    /**
+     * The RIL returns nothing or exceptions.
+     */
+    public static final int ERROR_RADIO_INTERFACE_ERROR = 10000;
+
+    /**
+     * The scan ID is invalid. The user is either trying to stop a scan which does not exist
+     * or started by others.
+     */
+    public static final int ERROR_INVALID_SCANID = 10001;
+
+    /**
+     * The scan has been interrupted by another scan with higher priority.
+     */
+    public static final int ERROR_INTERRUPTED = 10002;
+
     private final int mScanId;
     private final int mSubId;
 
     /**
      * Stops the network scan
      *
-     * This is the callback method to stop an ongoing scan. When user requests a new scan,
-     * a NetworkScan object will be returned, and the user can stop the scan by calling this
-     * method.
+     * Use this method to stop an ongoing scan. When user requests a new scan, a {@link NetworkScan}
+     * object will be returned, and the user can stop the scan by calling this method.
      */
     public void stop() throws RemoteException {
         try {
diff --git a/telephony/java/android/telephony/NetworkScanRequest.java b/telephony/java/android/telephony/NetworkScanRequest.java
index 9674c93..ea503c3 100644
--- a/telephony/java/android/telephony/NetworkScanRequest.java
+++ b/telephony/java/android/telephony/NetworkScanRequest.java
@@ -16,11 +16,14 @@
 
 package android.telephony;
 
+import android.annotation.IntDef;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * Defines a request to peform a network scan.
@@ -28,7 +31,6 @@
  * This class defines whether the network scan will be performed only once or periodically until
  * cancelled, when the scan is performed periodically, the time interval is not controlled by the
  * user but defined by the modem vendor.
- * @hide
  */
 public final class NetworkScanRequest implements Parcelable {
 
@@ -54,6 +56,14 @@
     /** @hide */
     public static final int MAX_INCREMENTAL_PERIODICITY_SEC = 10;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        SCAN_TYPE_ONE_SHOT,
+        SCAN_TYPE_PERIODIC,
+    })
+    public @interface ScanType {}
+
     /** Performs the scan only once */
     public static final int SCAN_TYPE_ONE_SHOT = 0;
     /**
@@ -65,21 +75,21 @@
     public static final int SCAN_TYPE_PERIODIC = 1;
 
     /** Defines the type of the scan. */
-    public int scanType;
+    private int mScanType;
 
     /**
      * Search periodicity (in seconds).
      * Expected range for the input is [5s - 300s]
-     * This value must be less than or equal to maxSearchTime
+     * This value must be less than or equal to mMaxSearchTime
      */
-    public int searchPeriodicity;
+    private int mSearchPeriodicity;
 
     /**
      * Maximum duration of the periodic search (in seconds).
      * Expected range for the input is [60s - 3600s]
      * If the search lasts this long, it will be terminated.
      */
-    public int maxSearchTime;
+    private int mMaxSearchTime;
 
     /**
      * Indicates whether the modem should report incremental
@@ -87,18 +97,18 @@
      * FALSE – Incremental results are not reported.
      * TRUE (default) – Incremental results are reported
      */
-    public boolean incrementalResults;
+    private boolean mIncrementalResults;
 
     /**
      * Indicates the periodicity with which the modem should
      * report incremental results to the client (in seconds).
      * Expected range for the input is [1s - 10s]
-     * This value must be less than or equal to maxSearchTime
+     * This value must be less than or equal to mMaxSearchTime
      */
-    public int incrementalResultsPeriodicity;
+    private int mIncrementalResultsPeriodicity;
 
     /** Describes the radio access technologies with bands or channels that need to be scanned. */
-    public RadioAccessSpecifier[] specifiers;
+    private RadioAccessSpecifier[] mSpecifiers;
 
     /**
      * Describes the List of PLMN ids (MCC-MNC)
@@ -107,20 +117,24 @@
      * If list not sent, search to be completed till end and all PLMNs found to be reported.
      * Max size of array is MAX_MCC_MNC_LIST_SIZE
      */
-    public ArrayList<String> mccMncs;
+    private ArrayList<String> mMccMncs;
 
     /**
-     * Creates a new NetworkScanRequest with scanType and network specifiers
+     * Creates a new NetworkScanRequest with mScanType and network mSpecifiers
      *
-     * @param scanType The type of the scan
+     * @param scanType The type of the scan, can be either one shot or periodic
      * @param specifiers the radio network with bands / channels to be scanned
-     * @param searchPeriodicity Search periodicity (in seconds)
-     * @param maxSearchTime Maximum duration of the periodic search (in seconds)
+     * @param searchPeriodicity The modem will restart the scan every searchPeriodicity seconds if
+     *                          no network has been found, until it reaches the maxSearchTime. Only
+     *                          valid when scan type is periodic scan.
+     * @param maxSearchTime Maximum duration of the search (in seconds)
      * @param incrementalResults Indicates whether the modem should report incremental
      *                           results of the network scan to the client
      * @param incrementalResultsPeriodicity Indicates the periodicity with which the modem should
-     *                                      report incremental results to the client (in seconds)
-     * @param mccMncs Describes the List of PLMN ids (MCC-MNC)
+     *                                      report incremental results to the client (in seconds),
+     *                                      only valid when incrementalResults is true
+     * @param mccMncs Describes the list of PLMN ids (MCC-MNC), once any network in the list has
+     *                been found, the scan will be terminated by the modem.
      */
     public NetworkScanRequest(int scanType, RadioAccessSpecifier[] specifiers,
                     int searchPeriodicity,
@@ -128,19 +142,63 @@
                     boolean incrementalResults,
                     int incrementalResultsPeriodicity,
                     ArrayList<String> mccMncs) {
-        this.scanType = scanType;
-        this.specifiers = specifiers;
-        this.searchPeriodicity = searchPeriodicity;
-        this.maxSearchTime = maxSearchTime;
-        this.incrementalResults = incrementalResults;
-        this.incrementalResultsPeriodicity = incrementalResultsPeriodicity;
-        if (mccMncs != null) {
-            this.mccMncs = mccMncs;
+        this.mScanType = scanType;
+        this.mSpecifiers = specifiers.clone();
+        this.mSearchPeriodicity = searchPeriodicity;
+        this.mMaxSearchTime = maxSearchTime;
+        this.mIncrementalResults = incrementalResults;
+        this.mIncrementalResultsPeriodicity = incrementalResultsPeriodicity;
+        if (mMccMncs != null) {
+            this.mMccMncs = (ArrayList<String>) mccMncs.clone();
         } else {
-            this.mccMncs = new ArrayList<>();
+            this.mMccMncs = new ArrayList<>();
         }
     }
 
+    /** Returns the type of the scan. */
+    @ScanType
+    public int getScanType() {
+        return mScanType;
+    }
+
+    /** Returns the search periodicity in seconds. */
+    public int getSearchPeriodicity() {
+        return mSearchPeriodicity;
+    }
+
+    /** Returns maximum duration of the periodic search in seconds. */
+    public int getMaxSearchTime() {
+        return mMaxSearchTime;
+    }
+
+    /**
+     * Returns whether incremental result is enabled.
+     * FALSE – Incremental results is not enabled.
+     * TRUE – Incremental results is reported.
+     */
+    public boolean getIncrementalResults() {
+        return mIncrementalResults;
+    }
+
+    /** Returns the periodicity in seconds of incremental results. */
+    public int getIncrementalResultsPeriodicity() {
+        return mIncrementalResultsPeriodicity;
+    }
+
+    /** Returns the radio access technologies with bands or channels that need to be scanned. */
+    public RadioAccessSpecifier[] getSpecifiers() {
+        return mSpecifiers.clone();
+    }
+
+    /**
+     * Returns the List of PLMN ids (MCC-MNC) for early termination of scan.
+     * If any PLMN of this list is found, search should end at that point and
+     * results with all PLMN found till that point should be sent as response.
+     */
+    public ArrayList<String> getPlmns() {
+        return (ArrayList<String>) mMccMncs.clone();
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -148,26 +206,26 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(scanType);
-        dest.writeParcelableArray(specifiers, flags);
-        dest.writeInt(searchPeriodicity);
-        dest.writeInt(maxSearchTime);
-        dest.writeBoolean(incrementalResults);
-        dest.writeInt(incrementalResultsPeriodicity);
-        dest.writeStringList(mccMncs);
+        dest.writeInt(mScanType);
+        dest.writeParcelableArray(mSpecifiers, flags);
+        dest.writeInt(mSearchPeriodicity);
+        dest.writeInt(mMaxSearchTime);
+        dest.writeBoolean(mIncrementalResults);
+        dest.writeInt(mIncrementalResultsPeriodicity);
+        dest.writeStringList(mMccMncs);
     }
 
     private NetworkScanRequest(Parcel in) {
-        scanType = in.readInt();
-        specifiers = (RadioAccessSpecifier[]) in.readParcelableArray(
+        mScanType = in.readInt();
+        mSpecifiers = (RadioAccessSpecifier[]) in.readParcelableArray(
                 Object.class.getClassLoader(),
                 RadioAccessSpecifier.class);
-        searchPeriodicity = in.readInt();
-        maxSearchTime = in.readInt();
-        incrementalResults = in.readBoolean();
-        incrementalResultsPeriodicity = in.readInt();
-        mccMncs = new ArrayList<>();
-        in.readStringList(mccMncs);
+        mSearchPeriodicity = in.readInt();
+        mMaxSearchTime = in.readInt();
+        mIncrementalResults = in.readBoolean();
+        mIncrementalResultsPeriodicity = in.readInt();
+        mMccMncs = new ArrayList<>();
+        in.readStringList(mMccMncs);
     }
 
     @Override
@@ -184,25 +242,25 @@
             return false;
         }
 
-        return (scanType == nsr.scanType
-                && Arrays.equals(specifiers, nsr.specifiers)
-                && searchPeriodicity == nsr.searchPeriodicity
-                && maxSearchTime == nsr.maxSearchTime
-                && incrementalResults == nsr.incrementalResults
-                && incrementalResultsPeriodicity == nsr.incrementalResultsPeriodicity
-                && (((mccMncs != null)
-                && mccMncs.equals(nsr.mccMncs))));
+        return (mScanType == nsr.mScanType
+                && Arrays.equals(mSpecifiers, nsr.mSpecifiers)
+                && mSearchPeriodicity == nsr.mSearchPeriodicity
+                && mMaxSearchTime == nsr.mMaxSearchTime
+                && mIncrementalResults == nsr.mIncrementalResults
+                && mIncrementalResultsPeriodicity == nsr.mIncrementalResultsPeriodicity
+                && (((mMccMncs != null)
+                && mMccMncs.equals(nsr.mMccMncs))));
     }
 
     @Override
     public int hashCode () {
-        return ((scanType * 31)
-                + (Arrays.hashCode(specifiers)) * 37
-                + (searchPeriodicity * 41)
-                + (maxSearchTime * 43)
-                + ((incrementalResults == true? 1 : 0) * 47)
-                + (incrementalResultsPeriodicity * 53)
-                + (mccMncs.hashCode() * 59));
+        return ((mScanType * 31)
+                + (Arrays.hashCode(mSpecifiers)) * 37
+                + (mSearchPeriodicity * 41)
+                + (mMaxSearchTime * 43)
+                + ((mIncrementalResults == true? 1 : 0) * 47)
+                + (mIncrementalResultsPeriodicity * 53)
+                + (mMccMncs.hashCode() * 59));
     }
 
     public static final Creator<NetworkScanRequest> CREATOR =
diff --git a/telephony/java/android/telephony/RadioAccessSpecifier.java b/telephony/java/android/telephony/RadioAccessSpecifier.java
index 33ce8b4..5412c61 100644
--- a/telephony/java/android/telephony/RadioAccessSpecifier.java
+++ b/telephony/java/android/telephony/RadioAccessSpecifier.java
@@ -25,34 +25,40 @@
  * Describes a particular radio access network to be scanned.
  *
  * The scan can be performed on either bands or channels for a specific radio access network type.
- * @hide
  */
 public final class RadioAccessSpecifier implements Parcelable {
 
     /**
      * The radio access network that needs to be scanned
      *
+     * This parameter must be provided or else the scan will be rejected.
+     *
      * See {@link RadioNetworkConstants.RadioAccessNetworks} for details.
      */
-    public int radioAccessNetwork;
+    private int mRadioAccessNetwork;
 
     /**
      * The frequency bands that need to be scanned
      *
-     * bands must be used together with radioAccessNetwork
+     * When no specific bands are specified (empty array or null), all the frequency bands
+     * supported by the modem will be scanned.
      *
      * See {@link RadioNetworkConstants} for details.
      */
-    public int[] bands;
+    private int[] mBands;
 
     /**
      * The frequency channels that need to be scanned
      *
-     * channels must be used together with radioAccessNetwork
+     * When any specific channels are provided for scan, the corresponding frequency bands that
+     * contains those channels must also be provided, or else the channels will be ignored.
      *
-     * See {@link RadioNetworkConstants.RadioAccessNetworks} for details.
+     * When no specific channels are specified (empty array or null), all the frequency channels
+     * supported by the modem will be scanned.
+     *
+     * See {@link RadioNetworkConstants} for details.
      */
-    public int[] channels;
+    private int[] mChannels;
 
     /**
     * Creates a new RadioAccessSpecifier with radio network, bands and channels
@@ -65,9 +71,34 @@
     * @param channels the frequency bands to be scanned
     */
     public RadioAccessSpecifier(int ran, int[] bands, int[] channels) {
-        this.radioAccessNetwork = ran;
-        this.bands = bands;
-        this.channels = channels;
+        this.mRadioAccessNetwork = ran;
+        this.mBands = bands.clone();
+        this.mChannels = channels.clone();
+    }
+
+    /**
+     * Returns the radio access network that needs to be scanned.
+     *
+     * The returned value is define in {@link RadioNetworkConstants.RadioAccessNetworks};
+     */
+    public int getRadioAccessNetwork() {
+        return mRadioAccessNetwork;
+    }
+
+    /**
+     * Returns the frequency bands that need to be scanned.
+     *
+     * The returned value is defined in either of {@link RadioNetworkConstants.GeranBands},
+     * {@link RadioNetworkConstants.UtranBands} and {@link RadioNetworkConstants.EutranBands}, and
+     * it depends on the returned value of {@link #getRadioAccessNetwork()}.
+     */
+    public int[] getBands() {
+        return mBands.clone();
+    }
+
+    /** Returns the frequency channels that need to be scanned. */
+    public int[] getChannels() {
+        return mChannels.clone();
     }
 
     public static final Parcelable.Creator<RadioAccessSpecifier> CREATOR =
@@ -90,15 +121,15 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(radioAccessNetwork);
-        dest.writeIntArray(bands);
-        dest.writeIntArray(channels);
+        dest.writeInt(mRadioAccessNetwork);
+        dest.writeIntArray(mBands);
+        dest.writeIntArray(mChannels);
     }
 
     private RadioAccessSpecifier(Parcel in) {
-        radioAccessNetwork = in.readInt();
-        bands = in.createIntArray();
-        channels = in.createIntArray();
+        mRadioAccessNetwork = in.readInt();
+        mBands = in.createIntArray();
+        mChannels = in.createIntArray();
     }
 
     @Override
@@ -115,15 +146,15 @@
             return false;
         }
 
-        return (radioAccessNetwork == ras.radioAccessNetwork
-                && Arrays.equals(bands, ras.bands)
-                && Arrays.equals(channels, ras.channels));
+        return (mRadioAccessNetwork == ras.mRadioAccessNetwork
+                && Arrays.equals(mBands, ras.mBands)
+                && Arrays.equals(mChannels, ras.mChannels));
     }
 
     @Override
     public int hashCode () {
-        return ((radioAccessNetwork * 31)
-                + (Arrays.hashCode(bands) * 37)
-                + (Arrays.hashCode(channels)) * 39);
+        return ((mRadioAccessNetwork * 31)
+                + (Arrays.hashCode(mBands) * 37)
+                + (Arrays.hashCode(mChannels)) * 39);
     }
 }
diff --git a/telephony/java/android/telephony/RadioNetworkConstants.java b/telephony/java/android/telephony/RadioNetworkConstants.java
index 1a9072d..5f5dd82 100644
--- a/telephony/java/android/telephony/RadioNetworkConstants.java
+++ b/telephony/java/android/telephony/RadioNetworkConstants.java
@@ -18,7 +18,6 @@
 
 /**
  * Contains radio access network related constants.
- * @hide
  */
 public final class RadioNetworkConstants {
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 00aa449..3bc0ed9 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4764,15 +4764,14 @@
      * Requires Permission:
      *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
      * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
-     *
-     * @hide
-     * TODO: Add an overload that takes no args.
      */
-    public void setNetworkSelectionModeAutomatic(int subId) {
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setNetworkSelectionModeAutomatic() {
         try {
             ITelephony telephony = getITelephony();
-            if (telephony != null)
-                telephony.setNetworkSelectionModeAutomatic(subId);
+            if (telephony != null) {
+                telephony.setNetworkSelectionModeAutomatic(getSubId());
+            }
         } catch (RemoteException ex) {
             Rlog.e(TAG, "setNetworkSelectionModeAutomatic RemoteException", ex);
         } catch (NullPointerException ex) {
@@ -4820,9 +4819,9 @@
      *
      * @param request Contains all the RAT with bands/channels that need to be scanned.
      * @param callback Returns network scan results or errors.
-     * @return A NetworkScan obj which contains a callback which can stop the scan.
-     * @hide
+     * @return A NetworkScan obj which contains a callback which can be used to stop the scan.
      */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public NetworkScan requestNetworkScan(
             NetworkScanRequest request, TelephonyScanManager.NetworkScanCallback callback) {
         synchronized (this) {
@@ -4841,15 +4840,20 @@
      *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
      * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
      *
-     * @hide
-     * TODO: Add an overload that takes no args.
+     * @param operatorNumeric the PLMN ID of the network to select.
+     * @param persistSelection whether the selection will persist until reboot. If true, only allows
+     * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
+     * normal network selection next time.
+     * @return true on success; false on any failure.
      */
-    public boolean setNetworkSelectionModeManual(int subId, OperatorInfo operator,
-            boolean persistSelection) {
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean setNetworkSelectionModeManual(String operatorNumeric, boolean persistSelection) {
         try {
             ITelephony telephony = getITelephony();
-            if (telephony != null)
-                return telephony.setNetworkSelectionModeManual(subId, operator, persistSelection);
+            if (telephony != null) {
+                return telephony.setNetworkSelectionModeManual(
+                        getSubId(), operatorNumeric, persistSelection);
+            }
         } catch (RemoteException ex) {
             Rlog.e(TAG, "setNetworkSelectionModeManual RemoteException", ex);
         } catch (NullPointerException ex) {
@@ -4874,8 +4878,9 @@
     public boolean setPreferredNetworkType(int subId, int networkType) {
         try {
             ITelephony telephony = getITelephony();
-            if (telephony != null)
+            if (telephony != null) {
                 return telephony.setPreferredNetworkType(subId, networkType);
+            }
         } catch (RemoteException ex) {
             Rlog.e(TAG, "setPreferredNetworkType RemoteException", ex);
         } catch (NullPointerException ex) {
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index 7bcdcdc..c182e34 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -38,7 +38,6 @@
 
 /**
  * Manages the radio access network scan requests and callbacks.
- * @hide
  */
 public final class TelephonyScanManager {
 
@@ -55,7 +54,8 @@
     public static final int CALLBACK_SCAN_COMPLETE = 3;
 
     /**
-     * The caller of {@link #requestNetworkScan(NetworkScanRequest, NetworkScanCallback)} should
+     * The caller of
+     * {@link TelephonyManager#requestNetworkScan(NetworkScanRequest, NetworkScanCallback)} should
      * implement and provide this callback so that the scan results or errors can be returned.
      */
     public static abstract class NetworkScanCallback {
@@ -75,8 +75,10 @@
          *
          * This callback will be called whenever there is any error about the scan, and the scan
          * will be terminated. onComplete() will NOT be called.
+         *
+         * @param error Error code when the scan is failed, as defined in {@link NetworkScan}.
          */
-        public void onError(int error) {}
+        public void onError(@NetworkScan.ScanErrorCode int error) {}
     }
 
     private static class NetworkScanInfo {
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index fd6091a..64083e3 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -846,13 +846,13 @@
      * Ask the radio to connect to the input network and change selection mode to manual.
      *
      * @param subId the id of the subscription.
-     * @param operatorInfo the operator to attach to.
-     * @param persistSelection should the selection persist till reboot or its
-     *        turned off? Will also result in notification being not shown to
-     *        the user if the signal is lost.
+     * @param operatorNumeric the PLMN of the operator to attach to.
+     * @param persistSelection Whether the selection will persist until reboot. If true, only allows
+     * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
+     * normal network selection next time.
      * @return true if the request suceeded.
      */
-    boolean setNetworkSelectionModeManual(int subId, in OperatorInfo operator,
+    boolean setNetworkSelectionModeManual(int subId, in String operatorNumeric,
             boolean persistSelection);
 
     /**