PhoneAccountHandle.java revision 48d8442e9c8e3331731b8cebc5b95cc40e923956
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
17package android.telecom;
18
19import android.annotation.SystemApi;
20import android.content.ComponentName;
21import android.os.Parcel;
22import android.os.Parcelable;
23import android.os.Process;
24import android.os.UserHandle;
25
26import 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 * See {@link PhoneAccount}, {@link TelecomManager}.
38 */
39public class PhoneAccountHandle implements Parcelable {
40    private final ComponentName mComponentName;
41    private final String mId;
42    private final UserHandle mUserHandle;
43
44    public PhoneAccountHandle(
45            ComponentName componentName,
46            String id) {
47        this(componentName, id, Process.myUserHandle());
48    }
49
50    /** @hide */
51    @SystemApi
52    public PhoneAccountHandle(
53            ComponentName componentName,
54            String id,
55            UserHandle userHandle) {
56        mComponentName = componentName;
57        mId = id;
58        mUserHandle = userHandle;
59    }
60
61    /**
62     * The {@code ComponentName} of the connection service which is responsible for making phone
63     * calls using this {@code PhoneAccountHandle}.
64     *
65     * @return A suitable {@code ComponentName}.
66     */
67    public ComponentName getComponentName() {
68        return mComponentName;
69    }
70
71    /**
72     * A string that uniquely distinguishes this particular {@code PhoneAccountHandle} from all the
73     * others supported by the connection service that created it.
74     * <p>
75     * A connection service must select identifiers that are stable for the lifetime of
76     * their users' relationship with their service, across many Android devices. For example, a
77     * good set of identifiers might be the email addresses with which with users registered for
78     * their accounts with a particular service. Depending on how a service chooses to operate,
79     * a bad set of identifiers might be an increasing series of integers
80     * ({@code 0}, {@code 1}, {@code 2}, ...) that are generated locally on each phone and could
81     * collide with values generated on other phones or after a data wipe of a given phone.
82     *
83     * @return A service-specific unique identifier for this {@code PhoneAccountHandle}.
84     */
85    public String getId() {
86        return mId;
87    }
88
89    /**
90     * @return the {@link UserHandle} to use when connecting to this PhoneAccount.
91     * @hide
92     */
93    @SystemApi
94    public UserHandle getUserHandle() {
95        return mUserHandle;
96    }
97
98    @Override
99    public int hashCode() {
100        return Objects.hash(mComponentName, mId, mUserHandle);
101    }
102
103    @Override
104    public String toString() {
105        // Note: Log.pii called for mId as it can contain personally identifying phone account
106        // information such as SIP account IDs.
107        return new StringBuilder().append(mComponentName)
108                    .append(", ")
109                    .append(Log.pii(mId))
110                    .append(", ")
111                    .append(mUserHandle)
112                    .toString();
113    }
114
115    @Override
116    public boolean equals(Object other) {
117        return other != null &&
118                other instanceof PhoneAccountHandle &&
119                Objects.equals(((PhoneAccountHandle) other).getComponentName(),
120                        getComponentName()) &&
121                Objects.equals(((PhoneAccountHandle) other).getId(), getId()) &&
122                Objects.equals(((PhoneAccountHandle) other).getUserHandle(), getUserHandle());
123    }
124
125    //
126    // Parcelable implementation.
127    //
128
129    @Override
130    public int describeContents() {
131        return 0;
132    }
133
134    @Override
135    public void writeToParcel(Parcel out, int flags) {
136        mComponentName.writeToParcel(out, flags);
137        out.writeString(mId);
138        mUserHandle.writeToParcel(out, flags);
139    }
140
141    public static final Creator<PhoneAccountHandle> CREATOR = new Creator<PhoneAccountHandle>() {
142        @Override
143        public PhoneAccountHandle createFromParcel(Parcel in) {
144            return new PhoneAccountHandle(in);
145        }
146
147        @Override
148        public PhoneAccountHandle[] newArray(int size) {
149            return new PhoneAccountHandle[size];
150        }
151    };
152
153    private PhoneAccountHandle(Parcel in) {
154        this(ComponentName.CREATOR.createFromParcel(in),
155                in.readString(),
156                UserHandle.CREATOR.createFromParcel(in));
157    }
158}
159