1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telephony;
18 
19 import android.annotation.IntDef;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 
28 /**
29  * Defines a request to peform a network scan.
30  *
31  * This class defines whether the network scan will be performed only once or periodically until
32  * cancelled, when the scan is performed periodically, the time interval is not controlled by the
33  * user but defined by the modem vendor.
34  */
35 public final class NetworkScanRequest implements Parcelable {
36 
37     // Below size limits for RAN/Band/Channel are for pre-treble modems and will be removed later.
38     /** @hide */
39     public static final int MAX_RADIO_ACCESS_NETWORKS = 8;
40     /** @hide */
41     public static final int MAX_BANDS = 8;
42     /** @hide */
43     public static final int MAX_CHANNELS = 32;
44     /** @hide */
45     public static final int MAX_MCC_MNC_LIST_SIZE = 20;
46     /** @hide */
47     public static final int MIN_SEARCH_PERIODICITY_SEC = 5;
48     /** @hide */
49     public static final int MAX_SEARCH_PERIODICITY_SEC = 300;
50     /** @hide */
51     public static final int MIN_SEARCH_MAX_SEC = 60;
52     /** @hide */
53     public static final int MAX_SEARCH_MAX_SEC = 3600;
54     /** @hide */
55     public static final int MIN_INCREMENTAL_PERIODICITY_SEC = 1;
56     /** @hide */
57     public static final int MAX_INCREMENTAL_PERIODICITY_SEC = 10;
58 
59     /** @hide */
60     @Retention(RetentionPolicy.SOURCE)
61     @IntDef({
62         SCAN_TYPE_ONE_SHOT,
63         SCAN_TYPE_PERIODIC,
64     })
65     public @interface ScanType {}
66 
67     /** Performs the scan only once */
68     public static final int SCAN_TYPE_ONE_SHOT = 0;
69     /**
70      * Performs the scan periodically until cancelled
71      *
72      * The modem will start new scans periodically, and the interval between two scans is usually
73      * multiple minutes.
74      */
75     public static final int SCAN_TYPE_PERIODIC = 1;
76 
77     /** Defines the type of the scan. */
78     private int mScanType;
79 
80     /**
81      * Search periodicity (in seconds).
82      * Expected range for the input is [5s - 300s]
83      * This value must be less than or equal to mMaxSearchTime
84      */
85     private int mSearchPeriodicity;
86 
87     /**
88      * Maximum duration of the periodic search (in seconds).
89      * Expected range for the input is [60s - 3600s]
90      * If the search lasts this long, it will be terminated.
91      */
92     private int mMaxSearchTime;
93 
94     /**
95      * Indicates whether the modem should report incremental
96      * results of the network scan to the client.
97      * FALSE – Incremental results are not reported.
98      * TRUE (default) – Incremental results are reported
99      */
100     private boolean mIncrementalResults;
101 
102     /**
103      * Indicates the periodicity with which the modem should
104      * report incremental results to the client (in seconds).
105      * Expected range for the input is [1s - 10s]
106      * This value must be less than or equal to mMaxSearchTime
107      */
108     private int mIncrementalResultsPeriodicity;
109 
110     /** Describes the radio access technologies with bands or channels that need to be scanned. */
111     private RadioAccessSpecifier[] mSpecifiers;
112 
113     /**
114      * Describes the List of PLMN ids (MCC-MNC)
115      * If any PLMN of this list is found, search should end at that point and
116      * results with all PLMN found till that point should be sent as response.
117      * If list not sent, search to be completed till end and all PLMNs found to be reported.
118      * Max size of array is MAX_MCC_MNC_LIST_SIZE
119      */
120     private ArrayList<String> mMccMncs;
121 
122     /**
123      * Creates a new NetworkScanRequest with mScanType and network mSpecifiers
124      *
125      * @param scanType The type of the scan, can be either one shot or periodic
126      * @param specifiers the radio network with bands / channels to be scanned
127      * @param searchPeriodicity The modem will restart the scan every searchPeriodicity seconds if
128      *                          no network has been found, until it reaches the maxSearchTime. Only
129      *                          valid when scan type is periodic scan.
130      * @param maxSearchTime Maximum duration of the search (in seconds)
131      * @param incrementalResults Indicates whether the modem should report incremental
132      *                           results of the network scan to the client
133      * @param incrementalResultsPeriodicity Indicates the periodicity with which the modem should
134      *                                      report incremental results to the client (in seconds),
135      *                                      only valid when incrementalResults is true
136      * @param mccMncs Describes the list of PLMN ids (MCC-MNC), once any network in the list has
137      *                been found, the scan will be terminated by the modem.
138      */
NetworkScanRequest(int scanType, RadioAccessSpecifier[] specifiers, int searchPeriodicity, int maxSearchTime, boolean incrementalResults, int incrementalResultsPeriodicity, ArrayList<String> mccMncs)139     public NetworkScanRequest(int scanType, RadioAccessSpecifier[] specifiers,
140                     int searchPeriodicity,
141                     int maxSearchTime,
142                     boolean incrementalResults,
143                     int incrementalResultsPeriodicity,
144                     ArrayList<String> mccMncs) {
145         this.mScanType = scanType;
146         if (specifiers != null) {
147             this.mSpecifiers = specifiers.clone();
148         } else {
149             this.mSpecifiers = null;
150         }
151         this.mSearchPeriodicity = searchPeriodicity;
152         this.mMaxSearchTime = maxSearchTime;
153         this.mIncrementalResults = incrementalResults;
154         this.mIncrementalResultsPeriodicity = incrementalResultsPeriodicity;
155         if (mccMncs != null) {
156             this.mMccMncs = (ArrayList<String>) mccMncs.clone();
157         } else {
158             this.mMccMncs = new ArrayList<>();
159         }
160     }
161 
162     /** Returns the type of the scan. */
163     @ScanType
getScanType()164     public int getScanType() {
165         return mScanType;
166     }
167 
168     /** Returns the search periodicity in seconds. */
getSearchPeriodicity()169     public int getSearchPeriodicity() {
170         return mSearchPeriodicity;
171     }
172 
173     /** Returns maximum duration of the periodic search in seconds. */
getMaxSearchTime()174     public int getMaxSearchTime() {
175         return mMaxSearchTime;
176     }
177 
178     /**
179      * Returns whether incremental result is enabled.
180      * FALSE – Incremental results is not enabled.
181      * TRUE – Incremental results is reported.
182      */
getIncrementalResults()183     public boolean getIncrementalResults() {
184         return mIncrementalResults;
185     }
186 
187     /** Returns the periodicity in seconds of incremental results. */
getIncrementalResultsPeriodicity()188     public int getIncrementalResultsPeriodicity() {
189         return mIncrementalResultsPeriodicity;
190     }
191 
192     /** Returns the radio access technologies with bands or channels that need to be scanned. */
getSpecifiers()193     public RadioAccessSpecifier[] getSpecifiers() {
194         return mSpecifiers == null ? null : mSpecifiers.clone();
195     }
196 
197     /**
198      * Returns the List of PLMN ids (MCC-MNC) for early termination of scan.
199      * If any PLMN of this list is found, search should end at that point and
200      * results with all PLMN found till that point should be sent as response.
201      */
getPlmns()202     public ArrayList<String> getPlmns() {
203         return (ArrayList<String>) mMccMncs.clone();
204     }
205 
206     @Override
describeContents()207     public int describeContents() {
208         return 0;
209     }
210 
211     @Override
writeToParcel(Parcel dest, int flags)212     public void writeToParcel(Parcel dest, int flags) {
213         dest.writeInt(mScanType);
214         dest.writeParcelableArray(mSpecifiers, flags);
215         dest.writeInt(mSearchPeriodicity);
216         dest.writeInt(mMaxSearchTime);
217         dest.writeBoolean(mIncrementalResults);
218         dest.writeInt(mIncrementalResultsPeriodicity);
219         dest.writeStringList(mMccMncs);
220     }
221 
NetworkScanRequest(Parcel in)222     private NetworkScanRequest(Parcel in) {
223         mScanType = in.readInt();
224         Parcelable[] tempSpecifiers = in.readParcelableArray(Object.class.getClassLoader());
225         if (tempSpecifiers != null) {
226             mSpecifiers = new RadioAccessSpecifier[tempSpecifiers.length];
227             for (int i = 0; i < tempSpecifiers.length; i++) {
228                 mSpecifiers[i] = (RadioAccessSpecifier) tempSpecifiers[i];
229             }
230         } else {
231             mSpecifiers = null;
232         }
233         mSearchPeriodicity = in.readInt();
234         mMaxSearchTime = in.readInt();
235         mIncrementalResults = in.readBoolean();
236         mIncrementalResultsPeriodicity = in.readInt();
237         mMccMncs = new ArrayList<>();
238         in.readStringList(mMccMncs);
239     }
240 
241     @Override
equals(Object o)242     public boolean equals (Object o) {
243         NetworkScanRequest nsr;
244 
245         try {
246             nsr = (NetworkScanRequest) o;
247         } catch (ClassCastException ex) {
248             return false;
249         }
250 
251         if (o == null) {
252             return false;
253         }
254 
255         return (mScanType == nsr.mScanType
256                 && Arrays.equals(mSpecifiers, nsr.mSpecifiers)
257                 && mSearchPeriodicity == nsr.mSearchPeriodicity
258                 && mMaxSearchTime == nsr.mMaxSearchTime
259                 && mIncrementalResults == nsr.mIncrementalResults
260                 && mIncrementalResultsPeriodicity == nsr.mIncrementalResultsPeriodicity
261                 && (((mMccMncs != null)
262                 && mMccMncs.equals(nsr.mMccMncs))));
263     }
264 
265     @Override
hashCode()266     public int hashCode () {
267         return ((mScanType * 31)
268                 + (Arrays.hashCode(mSpecifiers)) * 37
269                 + (mSearchPeriodicity * 41)
270                 + (mMaxSearchTime * 43)
271                 + ((mIncrementalResults == true? 1 : 0) * 47)
272                 + (mIncrementalResultsPeriodicity * 53)
273                 + (mMccMncs.hashCode() * 59));
274     }
275 
276     public static final @android.annotation.NonNull Creator<NetworkScanRequest> CREATOR =
277             new Creator<NetworkScanRequest>() {
278                 @Override
279                 public NetworkScanRequest createFromParcel(Parcel in) {
280                     return new NetworkScanRequest(in);
281                 }
282 
283                 @Override
284                 public NetworkScanRequest[] newArray(int size) {
285                     return new NetworkScanRequest[size];
286                 }
287             };
288 }
289