1 /*
2  * Copyright (C) 2018 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.ims.feature;
18 
19 import android.annotation.NonNull;
20 import android.annotation.SystemApi;
21 import android.annotation.TestApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.telephony.ims.stub.ImsRegistrationImplBase;
25 import android.util.ArraySet;
26 
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Set;
30 
31 /**
32  * Request to send to IMS provider, which will try to enable/disable capabilities that are added to
33  * the request.
34  * {@hide}
35  */
36 @SystemApi
37 @TestApi
38 public final class CapabilityChangeRequest implements Parcelable {
39 
40     /**
41      * Contains a feature capability, defined as
42      * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
43      * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO},
44      * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT}, or
45      * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS},
46      * along with an associated technology, defined as
47      * {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE} or
48      * {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
49      */
50     public static class CapabilityPair {
51         private final int mCapability;
52         private final int radioTech;
53 
CapabilityPair(@mTelFeature.MmTelCapabilities.MmTelCapability int capability, @ImsRegistrationImplBase.ImsRegistrationTech int radioTech)54         public CapabilityPair(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
55                 @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
56             this.mCapability = capability;
57             this.radioTech = radioTech;
58         }
59 
60         /**
61          * @hide
62          */
63         @Override
equals(Object o)64         public boolean equals(Object o) {
65             if (this == o) return true;
66             if (!(o instanceof CapabilityPair)) return false;
67 
68             CapabilityPair that = (CapabilityPair) o;
69 
70             if (getCapability() != that.getCapability()) return false;
71             return getRadioTech() == that.getRadioTech();
72         }
73 
74         /**
75          * @hide
76          */
77         @Override
hashCode()78         public int hashCode() {
79             int result = getCapability();
80             result = 31 * result + getRadioTech();
81             return result;
82         }
83 
84         /**
85          * @return The stored capability, defined as
86          * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
87          * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO},
88          * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT}, or
89          * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}
90          */
getCapability()91         public @MmTelFeature.MmTelCapabilities.MmTelCapability int getCapability() {
92             return mCapability;
93         }
94 
95         /**
96          * @return the stored radio technology, defined as
97          * {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE} or
98          * {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
99          */
getRadioTech()100         public @ImsRegistrationImplBase.ImsRegistrationTech int getRadioTech() {
101             return radioTech;
102         }
103 
104         @NonNull
105         @Override
toString()106         public String toString() {
107             return "CapabilityPair{"
108                     + "mCapability=" + mCapability
109                     + ", radioTech=" + radioTech + '}';
110         }
111     }
112 
113     // Pair contains <radio tech, mCapability>
114     private final Set<CapabilityPair> mCapabilitiesToEnable;
115     // Pair contains <radio tech, mCapability>
116     private final Set<CapabilityPair> mCapabilitiesToDisable;
117 
118     /** @hide */
CapabilityChangeRequest()119     public CapabilityChangeRequest() {
120         mCapabilitiesToEnable = new ArraySet<>();
121         mCapabilitiesToDisable = new ArraySet<>();
122     }
123 
124     /**
125      * Add one or many capabilities to the request to be enabled.
126      *
127      * @param capabilities A bitfield of capabilities to enable, valid values are defined in
128      *   {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
129      * @param radioTech  the radio tech that these capabilities should be enabled for, valid
130      *   values are in {@link ImsRegistrationImplBase.ImsRegistrationTech}.
131      */
addCapabilitiesToEnableForTech( @mTelFeature.MmTelCapabilities.MmTelCapability int capabilities, @ImsRegistrationImplBase.ImsRegistrationTech int radioTech)132     public void addCapabilitiesToEnableForTech(
133             @MmTelFeature.MmTelCapabilities.MmTelCapability int capabilities,
134             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
135         addAllCapabilities(mCapabilitiesToEnable, capabilities, radioTech);
136     }
137 
138     /**
139      * Add one or many capabilities to the request to be disabled.
140      * @param capabilities A bitfield of capabilities to diable, valid values are defined in
141      *   {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
142      * @param radioTech the radio tech that these capabilities should be disabled for, valid
143      *   values are in {@link ImsRegistrationImplBase.ImsRegistrationTech}.
144      */
addCapabilitiesToDisableForTech( @mTelFeature.MmTelCapabilities.MmTelCapability int capabilities, @ImsRegistrationImplBase.ImsRegistrationTech int radioTech)145     public void addCapabilitiesToDisableForTech(
146             @MmTelFeature.MmTelCapabilities.MmTelCapability int capabilities,
147             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
148         addAllCapabilities(mCapabilitiesToDisable, capabilities, radioTech);
149     }
150 
151     /**
152      * @return a {@link List} of {@link CapabilityPair}s that are requesting to be enabled.
153      */
getCapabilitiesToEnable()154     public List<CapabilityPair> getCapabilitiesToEnable() {
155         return new ArrayList<>(mCapabilitiesToEnable);
156     }
157 
158     /**
159      * @return a {@link List} of {@link CapabilityPair}s that are requesting to be disabled.
160      */
getCapabilitiesToDisable()161     public List<CapabilityPair> getCapabilitiesToDisable() {
162         return new ArrayList<>(mCapabilitiesToDisable);
163     }
164 
165     // Iterate through capabilities bitfield and add each one as a pair associated with the radio
166     // technology
addAllCapabilities(Set<CapabilityPair> set, int capabilities, int tech)167     private void addAllCapabilities(Set<CapabilityPair> set, int capabilities, int tech) {
168         long highestCapability = Long.highestOneBit(capabilities);
169         for (int i = 1; i <= highestCapability; i *= 2) {
170             if ((i & capabilities) > 0) {
171                 set.add(new CapabilityPair(/*capability*/ i, /*radioTech*/ tech));
172             }
173         }
174     }
175 
176     /**
177      * @hide
178      */
CapabilityChangeRequest(Parcel in)179     protected CapabilityChangeRequest(Parcel in) {
180         int enableSize = in.readInt();
181         mCapabilitiesToEnable = new ArraySet<>(enableSize);
182         for (int i = 0; i < enableSize; i++) {
183             mCapabilitiesToEnable.add(new CapabilityPair(/*capability*/ in.readInt(),
184                     /*radioTech*/ in.readInt()));
185         }
186         int disableSize = in.readInt();
187         mCapabilitiesToDisable = new ArraySet<>(disableSize);
188         for (int i = 0; i < disableSize; i++) {
189             mCapabilitiesToDisable.add(new CapabilityPair(/*capability*/ in.readInt(),
190                     /*radioTech*/ in.readInt()));
191         }
192     }
193 
194     public static final @android.annotation.NonNull Creator<CapabilityChangeRequest> CREATOR =
195             new Creator<CapabilityChangeRequest>() {
196                 @Override
197                 public CapabilityChangeRequest createFromParcel(Parcel in) {
198                     return new CapabilityChangeRequest(in);
199                 }
200 
201                 @Override
202                 public CapabilityChangeRequest[] newArray(int size) {
203                     return new CapabilityChangeRequest[size];
204                 }
205             };
206 
207     @Override
describeContents()208     public int describeContents() {
209         return 0;
210     }
211 
212     @Override
writeToParcel(Parcel dest, int flags)213     public void writeToParcel(Parcel dest, int flags) {
214         dest.writeInt(mCapabilitiesToEnable.size());
215         for (CapabilityPair pair : mCapabilitiesToEnable) {
216             dest.writeInt(pair.getCapability());
217             dest.writeInt(pair.getRadioTech());
218         }
219         dest.writeInt(mCapabilitiesToDisable.size());
220         for (CapabilityPair pair : mCapabilitiesToDisable) {
221             dest.writeInt(pair.getCapability());
222             dest.writeInt(pair.getRadioTech());
223         }
224     }
225 
226     @NonNull
227     @Override
toString()228     public String toString() {
229         return "CapabilityChangeRequest{"
230                 + "mCapabilitiesToEnable=" + mCapabilitiesToEnable
231                 + ", mCapabilitiesToDisable=" + mCapabilitiesToDisable + '}';
232     }
233 
234     /**
235      * @hide
236      */
237     @Override
equals(Object o)238     public boolean equals(Object o) {
239         if (this == o) return true;
240         if (!(o instanceof CapabilityChangeRequest)) return false;
241 
242         CapabilityChangeRequest
243                 that = (CapabilityChangeRequest) o;
244 
245         if (!mCapabilitiesToEnable.equals(that.mCapabilitiesToEnable)) return false;
246         return mCapabilitiesToDisable.equals(that.mCapabilitiesToDisable);
247     }
248 
249     /**
250      * @hide
251      */
252     @Override
hashCode()253     public int hashCode() {
254         int result = mCapabilitiesToEnable.hashCode();
255         result = 31 * result + mCapabilitiesToDisable.hashCode();
256         return result;
257     }
258 }
259