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