• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.telecom;
18 
19 import android.annotation.NonNull;
20 import android.content.ComponentName;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.os.Process;
24 import android.os.UserHandle;
25 
26 import java.util.Objects;
27 
28 /**
29  * The unique identifier for a {@link PhoneAccount}. A {@code PhoneAccountHandle} is made of two
30  * parts:
31  * <ul>
32  *  <li>The component name of the associated connection service.</li>
33  *  <li>A string identifier that is unique across {@code PhoneAccountHandle}s with the same
34  *      component name.</li>
35  * </ul>
36  *
37  * Note: This Class requires a non-null {@link ComponentName} and {@link UserHandle} to operate
38  * properly. Passing in invalid parameters will generate a log warning.
39  *
40  * See {@link PhoneAccount}, {@link TelecomManager}.
41  */
42 public final class PhoneAccountHandle implements Parcelable {
43     private final ComponentName mComponentName;
44     private final String mId;
45     private final UserHandle mUserHandle;
46 
PhoneAccountHandle( @onNull ComponentName componentName, @NonNull String id)47     public PhoneAccountHandle(
48             @NonNull ComponentName componentName,
49             @NonNull String id) {
50         this(componentName, id, Process.myUserHandle());
51     }
52 
PhoneAccountHandle( @onNull ComponentName componentName, @NonNull String id, @NonNull UserHandle userHandle)53     public PhoneAccountHandle(
54             @NonNull ComponentName componentName,
55             @NonNull String id,
56             @NonNull UserHandle userHandle) {
57         checkParameters(componentName, userHandle);
58         mComponentName = componentName;
59         mId = id;
60         mUserHandle = userHandle;
61     }
62 
63     /**
64      * The {@code ComponentName} of the connection service which is responsible for making phone
65      * calls using this {@code PhoneAccountHandle}.
66      *
67      * @return A suitable {@code ComponentName}.
68      */
getComponentName()69     public ComponentName getComponentName() {
70         return mComponentName;
71     }
72 
73     /**
74      * A string that uniquely distinguishes this particular {@code PhoneAccountHandle} from all the
75      * others supported by the connection service that created it.
76      * <p>
77      * A connection service must select identifiers that are stable for the lifetime of
78      * their users' relationship with their service, across many Android devices. For example, a
79      * good set of identifiers might be the email addresses with which with users registered for
80      * their accounts with a particular service. Depending on how a service chooses to operate,
81      * a bad set of identifiers might be an increasing series of integers
82      * ({@code 0}, {@code 1}, {@code 2}, ...) that are generated locally on each phone and could
83      * collide with values generated on other phones or after a data wipe of a given phone.
84      *
85      * Important: A non-unique identifier could cause non-deterministic call-log backup/restore
86      * behavior.
87      *
88      * @return A service-specific unique identifier for this {@code PhoneAccountHandle}.
89      */
getId()90     public String getId() {
91         return mId;
92     }
93 
94     /**
95      * @return the {@link UserHandle} to use when connecting to this PhoneAccount.
96      */
getUserHandle()97     public UserHandle getUserHandle() {
98         return mUserHandle;
99     }
100 
101     @Override
hashCode()102     public int hashCode() {
103         return Objects.hash(mComponentName, mId, mUserHandle);
104     }
105 
106     @Override
toString()107     public String toString() {
108         // Note: Log.pii called for mId as it can contain personally identifying phone account
109         // information such as SIP account IDs.
110         return new StringBuilder().append(mComponentName)
111                     .append(", ")
112                     .append(Log.pii(mId))
113                     .append(", ")
114                     .append(mUserHandle)
115                     .toString();
116     }
117 
118     @Override
equals(Object other)119     public boolean equals(Object other) {
120         return other != null &&
121                 other instanceof PhoneAccountHandle &&
122                 Objects.equals(((PhoneAccountHandle) other).getComponentName(),
123                         getComponentName()) &&
124                 Objects.equals(((PhoneAccountHandle) other).getId(), getId()) &&
125                 Objects.equals(((PhoneAccountHandle) other).getUserHandle(), getUserHandle());
126     }
127 
128     //
129     // Parcelable implementation.
130     //
131 
132     @Override
describeContents()133     public int describeContents() {
134         return 0;
135     }
136 
137     @Override
writeToParcel(Parcel out, int flags)138     public void writeToParcel(Parcel out, int flags) {
139         mComponentName.writeToParcel(out, flags);
140         out.writeString(mId);
141         mUserHandle.writeToParcel(out, flags);
142     }
143 
checkParameters(ComponentName componentName, UserHandle userHandle)144     private void checkParameters(ComponentName componentName, UserHandle userHandle) {
145         if(componentName == null) {
146             android.util.Log.w("PhoneAccountHandle", new Exception("PhoneAccountHandle has " +
147                     "been created with null ComponentName!"));
148         }
149         if(userHandle == null) {
150             android.util.Log.w("PhoneAccountHandle", new Exception("PhoneAccountHandle has " +
151                     "been created with null UserHandle!"));
152         }
153     }
154 
155     public static final Creator<PhoneAccountHandle> CREATOR = new Creator<PhoneAccountHandle>() {
156         @Override
157         public PhoneAccountHandle createFromParcel(Parcel in) {
158             return new PhoneAccountHandle(in);
159         }
160 
161         @Override
162         public PhoneAccountHandle[] newArray(int size) {
163             return new PhoneAccountHandle[size];
164         }
165     };
166 
PhoneAccountHandle(Parcel in)167     private PhoneAccountHandle(Parcel in) {
168         this(ComponentName.CREATOR.createFromParcel(in),
169                 in.readString(),
170                 UserHandle.CREATOR.createFromParcel(in));
171     }
172 }
173