• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.NonNull;
20 import android.os.Binder;
21 import android.os.IBinder;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Comparator;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Objects;
32 import java.util.Set;
33 
34 /**
35  * Request used to register {@link SignalThresholdInfo} to be notified when the signal strength
36  * breach the specified thresholds.
37  */
38 public final class SignalStrengthUpdateRequest implements Parcelable {
39     /**
40      * List of SignalThresholdInfo for the request.
41      */
42     private final List<SignalThresholdInfo> mSignalThresholdInfos;
43 
44     /**
45      * Whether the reporting is required for thresholds in the request while device is idle.
46      */
47     private final boolean mIsReportingRequestedWhileIdle;
48 
49     /**
50      * Whether the reporting requested for system thresholds while device is idle.
51      *
52      * System signal thresholds are loaded from carrier config items and mainly used for UI
53      * displaying. By default, they are ignored when device is idle. When setting the value to true,
54      * modem will continue reporting signal strength changes over the system signal thresholds even
55      * device is idle.
56      *
57      * This should only set to true by the system caller.
58      */
59     private final boolean mIsSystemThresholdReportingRequestedWhileIdle;
60 
61     /**
62      * A IBinder object as a token for server side to check if the request client is still living.
63      */
64     private final IBinder mLiveToken;
65 
SignalStrengthUpdateRequest( @onNull List<SignalThresholdInfo> signalThresholdInfos, boolean isReportingRequestedWhileIdle, boolean isSystemThresholdReportingRequestedWhileIdle)66     private SignalStrengthUpdateRequest(
67             @NonNull List<SignalThresholdInfo> signalThresholdInfos,
68             boolean isReportingRequestedWhileIdle,
69             boolean isSystemThresholdReportingRequestedWhileIdle) {
70         validate(signalThresholdInfos);
71 
72         mSignalThresholdInfos = signalThresholdInfos;
73         mIsReportingRequestedWhileIdle = isReportingRequestedWhileIdle;
74         mIsSystemThresholdReportingRequestedWhileIdle =
75                 isSystemThresholdReportingRequestedWhileIdle;
76         mLiveToken = new Binder();
77     }
78 
79     /**
80      * Builder class to create {@link SignalStrengthUpdateRequest} object.
81      */
82     public static final class Builder {
83         private List<SignalThresholdInfo> mSignalThresholdInfos = null;
84         private boolean mIsReportingRequestedWhileIdle = false;
85         private boolean mIsSystemThresholdReportingRequestedWhileIdle = false;
86 
87         /**
88          * Set the collection of SignalThresholdInfo for the builder object
89          *
90          * @param signalThresholdInfos the collection of SignalThresholdInfo
91          *
92          * @return the builder to facilitate the chaining
93          */
setSignalThresholdInfos( @onNull Collection<SignalThresholdInfo> signalThresholdInfos)94         public @NonNull Builder setSignalThresholdInfos(
95                 @NonNull Collection<SignalThresholdInfo> signalThresholdInfos) {
96             Objects.requireNonNull(signalThresholdInfos,
97                     "SignalThresholdInfo collection must not be null");
98             for (SignalThresholdInfo info : signalThresholdInfos) {
99                 Objects.requireNonNull(info,
100                         "SignalThresholdInfo in the collection must not be null");
101             }
102 
103             mSignalThresholdInfos = new ArrayList<>(signalThresholdInfos);
104             // Sort the collection with RAN ascending order, make the ordering not matter for equals
105             mSignalThresholdInfos.sort(
106                     Comparator.comparingInt(SignalThresholdInfo::getRadioAccessNetworkType));
107             return this;
108         }
109 
110         /**
111          * Set the builder object if require reporting on thresholds in this request when device is
112          * idle.
113          *
114          * @param isReportingRequestedWhileIdle true if request reporting when device is idle
115          *
116          * @return the builder to facilitate the chaining
117          */
setReportingRequestedWhileIdle( boolean isReportingRequestedWhileIdle)118         public @NonNull Builder setReportingRequestedWhileIdle(
119                 boolean isReportingRequestedWhileIdle) {
120             mIsReportingRequestedWhileIdle = isReportingRequestedWhileIdle;
121             return this;
122         }
123 
124         /**
125          * Set the builder object if require reporting on the system thresholds when device is idle.
126          *
127          * This can only used by the system caller.
128          *
129          * @param isSystemThresholdReportingRequestedWhileIdle true if request reporting on the
130          *                                                     system thresholds when device is idle
131          * @return the builder to facilitate the chaining
132          * @hide
133          */
setSystemThresholdReportingRequestedWhileIdle( boolean isSystemThresholdReportingRequestedWhileIdle)134         public @NonNull Builder setSystemThresholdReportingRequestedWhileIdle(
135                 boolean isSystemThresholdReportingRequestedWhileIdle) {
136             mIsSystemThresholdReportingRequestedWhileIdle =
137                     isSystemThresholdReportingRequestedWhileIdle;
138             return this;
139         }
140 
141         /**
142          * Build a {@link SignalStrengthUpdateRequest} object.
143          *
144          * @return the SignalStrengthUpdateRequest object
145          *
146          * @throws IllegalArgumentException if the SignalThresholdInfo collection is empty size, the
147          * radio access network type in the collection is not unique
148          */
build()149         public @NonNull SignalStrengthUpdateRequest build() {
150             return new SignalStrengthUpdateRequest(mSignalThresholdInfos,
151                     mIsReportingRequestedWhileIdle, mIsSystemThresholdReportingRequestedWhileIdle);
152         }
153     }
154 
SignalStrengthUpdateRequest(Parcel in)155     private SignalStrengthUpdateRequest(Parcel in) {
156         mSignalThresholdInfos = in.createTypedArrayList(SignalThresholdInfo.CREATOR);
157         mIsReportingRequestedWhileIdle = in.readBoolean();
158         mIsSystemThresholdReportingRequestedWhileIdle = in.readBoolean();
159         mLiveToken = in.readStrongBinder();
160     }
161 
162     /**
163      * Get the collection of SignalThresholdInfo in the request.
164      *
165      * @return the collection of SignalThresholdInfo
166      */
167     @NonNull
getSignalThresholdInfos()168     public Collection<SignalThresholdInfo> getSignalThresholdInfos() {
169         return Collections.unmodifiableList(mSignalThresholdInfos);
170     }
171 
172     /**
173      * Get whether reporting is requested for the threshold in the request while device is idle.
174      *
175      * @return true if reporting requested while device is idle
176      */
isReportingRequestedWhileIdle()177     public boolean isReportingRequestedWhileIdle() {
178         return mIsReportingRequestedWhileIdle;
179     }
180 
181     /**
182      * @return true if reporting requested for system thresholds while device is idle
183      *
184      * @hide
185      */
isSystemThresholdReportingRequestedWhileIdle()186     public boolean isSystemThresholdReportingRequestedWhileIdle() {
187         return mIsSystemThresholdReportingRequestedWhileIdle;
188     }
189 
190     /**
191      * @return the live token of the request
192      *
193      * @hide
194      */
getLiveToken()195     public @NonNull IBinder getLiveToken() {
196         return mLiveToken;
197     }
198 
199     @Override
describeContents()200     public int describeContents() {
201         return 0;
202     }
203 
204     @Override
writeToParcel(@onNull Parcel dest, int flags)205     public void writeToParcel(@NonNull Parcel dest, int flags) {
206         dest.writeTypedList(mSignalThresholdInfos);
207         dest.writeBoolean(mIsReportingRequestedWhileIdle);
208         dest.writeBoolean(mIsSystemThresholdReportingRequestedWhileIdle);
209         dest.writeStrongBinder(mLiveToken);
210     }
211 
212     @Override
equals(Object other)213     public boolean equals(Object other) {
214         if (this == other) return true;
215 
216         if (!(other instanceof SignalStrengthUpdateRequest)) {
217             return false;
218         }
219 
220         SignalStrengthUpdateRequest request = (SignalStrengthUpdateRequest) other;
221         return mSignalThresholdInfos.equals(request.mSignalThresholdInfos)
222                 && mIsReportingRequestedWhileIdle == request.mIsReportingRequestedWhileIdle
223                 && mIsSystemThresholdReportingRequestedWhileIdle
224                     == request.mIsSystemThresholdReportingRequestedWhileIdle;
225     }
226 
227     @Override
hashCode()228     public int hashCode() {
229         return Objects.hash(mSignalThresholdInfos, mIsReportingRequestedWhileIdle,
230                 mIsSystemThresholdReportingRequestedWhileIdle);
231     }
232 
233     public static final @NonNull Parcelable.Creator<SignalStrengthUpdateRequest> CREATOR =
234             new Parcelable.Creator<SignalStrengthUpdateRequest>() {
235                 @Override
236                 public SignalStrengthUpdateRequest createFromParcel(Parcel source) {
237                     return new SignalStrengthUpdateRequest(source);
238                 }
239 
240                 @Override
241                 public SignalStrengthUpdateRequest[] newArray(int size) {
242                     return new SignalStrengthUpdateRequest[size];
243                 }
244             };
245 
246     @Override
toString()247     public String toString() {
248         return new StringBuilder("SignalStrengthUpdateRequest{")
249                 .append("mSignalThresholdInfos=")
250                 .append(mSignalThresholdInfos)
251                 .append(" mIsReportingRequestedWhileIdle=")
252                 .append(mIsReportingRequestedWhileIdle)
253                 .append(" mIsSystemThresholdReportingRequestedWhileIdle=")
254                 .append(mIsSystemThresholdReportingRequestedWhileIdle)
255                 .append(" mLiveToken")
256                 .append(mLiveToken)
257                 .append("}").toString();
258     }
259 
260     /**
261      * Throw IAE when the RAN in the collection is not unique.
262      */
validate(Collection<SignalThresholdInfo> infos)263     private static void validate(Collection<SignalThresholdInfo> infos) {
264         Set<Integer> uniqueRan = new HashSet<>(infos.size());
265         for (SignalThresholdInfo info : infos) {
266             final int ran = info.getRadioAccessNetworkType();
267             if (!uniqueRan.add(ran)) {
268                 throw new IllegalArgumentException("RAN: " + ran + " is not unique");
269             }
270         }
271     }
272 }
273