1542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad/*
2542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad * Copyright (C) 2014 The Android Open Source Project
3542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad *
4542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad * Licensed under the Apache License, Version 2.0 (the "License");
5542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad * you may not use this file except in compliance with the License.
6542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad * You may obtain a copy of the License at
7542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad *
8542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad *      http://www.apache.org/licenses/LICENSE-2.0
9542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad *
10542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad * Unless required by applicable law or agreed to in writing, software
11542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad * distributed under the License is distributed on an "AS IS" BASIS,
12542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad * See the License for the specific language governing permissions and
14542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad * limitations under the License.
15542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad */
16542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad
17ef9f6f957d897ea0ed82114185b8fa3fefd4917bTyler Gunnpackage android.telecom;
18542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad
19428cec9056234e32497a91da91d2f81e9309cd83Brad Ebingerimport android.annotation.NonNull;
20c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awadimport android.content.ComponentName;
21542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awadimport android.os.Parcel;
22542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awadimport android.os.Parcelable;
23134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charltonimport android.os.Process;
24134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charltonimport android.os.UserHandle;
25c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad
26dcaa5d6d09150b24aacf677c8a57fc34b6b63157Ihab Awadimport java.util.Objects;
27542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad
28542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad/**
29d9e614fd56677bc39481fce115731d55ab72171aSantos Cordon * The unique identifier for a {@link PhoneAccount}. A {@code PhoneAccountHandle} is made of two
30d9e614fd56677bc39481fce115731d55ab72171aSantos Cordon * parts:
31d9e614fd56677bc39481fce115731d55ab72171aSantos Cordon * <ul>
32ad147f4b59d42f48b73f6861f379535dbcc72b4aBrian Attwell *  <li>The component name of the associated connection service.</li>
33d9e614fd56677bc39481fce115731d55ab72171aSantos Cordon *  <li>A string identifier that is unique across {@code PhoneAccountHandle}s with the same
34d9e614fd56677bc39481fce115731d55ab72171aSantos Cordon *      component name.</li>
35d9e614fd56677bc39481fce115731d55ab72171aSantos Cordon * </ul>
36d9e614fd56677bc39481fce115731d55ab72171aSantos Cordon *
37428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger * Note: This Class requires a non-null {@link ComponentName} and {@link UserHandle} to operate
38428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger * properly. Passing in invalid parameters will generate a log warning.
39428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger *
40ad147f4b59d42f48b73f6861f379535dbcc72b4aBrian Attwell * See {@link PhoneAccount}, {@link TelecomManager}.
41542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad */
42400470fab932fe3374149ab89386e460ea161002Yorke Leepublic final class PhoneAccountHandle implements Parcelable {
43134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton    private final ComponentName mComponentName;
44134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton    private final String mId;
45134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton    private final UserHandle mUserHandle;
46c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad
476eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton    public PhoneAccountHandle(
48428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger            @NonNull ComponentName componentName,
49428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger            @NonNull String id) {
50134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton        this(componentName, id, Process.myUserHandle());
51134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton    }
52134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton
53134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton    public PhoneAccountHandle(
54428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger            @NonNull ComponentName componentName,
55428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger            @NonNull String id,
56428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger            @NonNull UserHandle userHandle) {
57428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger        checkParameters(componentName, userHandle);
58c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad        mComponentName = componentName;
59c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad        mId = id;
60134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton        mUserHandle = userHandle;
61c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    }
62c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad
63c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    /**
64ad147f4b59d42f48b73f6861f379535dbcc72b4aBrian Attwell     * The {@code ComponentName} of the connection service which is responsible for making phone
65ad147f4b59d42f48b73f6861f379535dbcc72b4aBrian Attwell     * calls using this {@code PhoneAccountHandle}.
66c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad     *
67c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad     * @return A suitable {@code ComponentName}.
68c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad     */
69c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    public ComponentName getComponentName() {
70c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad        return mComponentName;
71c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    }
72c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad
73c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    /**
74b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad     * A string that uniquely distinguishes this particular {@code PhoneAccountHandle} from all the
75ad147f4b59d42f48b73f6861f379535dbcc72b4aBrian Attwell     * others supported by the connection service that created it.
76b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad     * <p>
77ad147f4b59d42f48b73f6861f379535dbcc72b4aBrian Attwell     * A connection service must select identifiers that are stable for the lifetime of
78b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad     * their users' relationship with their service, across many Android devices. For example, a
79b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad     * good set of identifiers might be the email addresses with which with users registered for
80b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad     * their accounts with a particular service. Depending on how a service chooses to operate,
81b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad     * a bad set of identifiers might be an increasing series of integers
82b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad     * ({@code 0}, {@code 1}, {@code 2}, ...) that are generated locally on each phone and could
83b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad     * collide with values generated on other phones or after a data wipe of a given phone.
84c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad     *
858b338d47e0ac5730bb802a10047414bf97262725Santos Cordon     * Important: A non-unique identifier could cause non-deterministic call-log backup/restore
868b338d47e0ac5730bb802a10047414bf97262725Santos Cordon     * behavior.
878b338d47e0ac5730bb802a10047414bf97262725Santos Cordon     *
88b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad     * @return A service-specific unique identifier for this {@code PhoneAccountHandle}.
89c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad     */
90c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    public String getId() {
91c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad        return mId;
92c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    }
93c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad
94134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton    /**
95134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton     * @return the {@link UserHandle} to use when connecting to this PhoneAccount.
96134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton     */
97134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton    public UserHandle getUserHandle() {
98134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton        return mUserHandle;
99134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton    }
100134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton
101807fe0a19a710ae4e053e80f610807ff5718f1a1Ihab Awad    @Override
102807fe0a19a710ae4e053e80f610807ff5718f1a1Ihab Awad    public int hashCode() {
103134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton        return Objects.hash(mComponentName, mId, mUserHandle);
104c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    }
105c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad
10698b270309a342be0971320c5731f495a901ca4e4Santos Cordon    @Override
10798b270309a342be0971320c5731f495a901ca4e4Santos Cordon    public String toString() {
10876c01a50d3028d9db251d7fc8bc5dbab1879d493Tyler Gunn        // Note: Log.pii called for mId as it can contain personally identifying phone account
10976c01a50d3028d9db251d7fc8bc5dbab1879d493Tyler Gunn        // information such as SIP account IDs.
11098b270309a342be0971320c5731f495a901ca4e4Santos Cordon        return new StringBuilder().append(mComponentName)
11198b270309a342be0971320c5731f495a901ca4e4Santos Cordon                    .append(", ")
11276c01a50d3028d9db251d7fc8bc5dbab1879d493Tyler Gunn                    .append(Log.pii(mId))
113134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton                    .append(", ")
114134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton                    .append(mUserHandle)
11598b270309a342be0971320c5731f495a901ca4e4Santos Cordon                    .toString();
11698b270309a342be0971320c5731f495a901ca4e4Santos Cordon    }
11798b270309a342be0971320c5731f495a901ca4e4Santos Cordon
11894cf4bff1345f9f7ec981d0bf7f8988f3d93c7a8Ihab Awad    @Override
11994cf4bff1345f9f7ec981d0bf7f8988f3d93c7a8Ihab Awad    public boolean equals(Object other) {
12098b270309a342be0971320c5731f495a901ca4e4Santos Cordon        return other != null &&
1216eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton                other instanceof PhoneAccountHandle &&
1226eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton                Objects.equals(((PhoneAccountHandle) other).getComponentName(),
1236eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton                        getComponentName()) &&
124134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton                Objects.equals(((PhoneAccountHandle) other).getId(), getId()) &&
125134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton                Objects.equals(((PhoneAccountHandle) other).getUserHandle(), getUserHandle());
12698b270309a342be0971320c5731f495a901ca4e4Santos Cordon    }
12798b270309a342be0971320c5731f495a901ca4e4Santos Cordon
128dcaa5d6d09150b24aacf677c8a57fc34b6b63157Ihab Awad    //
129807fe0a19a710ae4e053e80f610807ff5718f1a1Ihab Awad    // Parcelable implementation.
130807fe0a19a710ae4e053e80f610807ff5718f1a1Ihab Awad    //
131542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad
132e7ef59a77d55c9802cc7d919f7dd794bd5fea30eSailesh Nepal    @Override
133542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad    public int describeContents() {
134542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad        return 0;
135542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad    }
136542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad
137e7ef59a77d55c9802cc7d919f7dd794bd5fea30eSailesh Nepal    @Override
138c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    public void writeToParcel(Parcel out, int flags) {
139134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton        mComponentName.writeToParcel(out, flags);
140c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad        out.writeString(mId);
141134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton        mUserHandle.writeToParcel(out, flags);
142c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    }
143542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad
144428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger    private void checkParameters(ComponentName componentName, UserHandle userHandle) {
145428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger        if(componentName == null) {
146428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger            android.util.Log.w("PhoneAccountHandle", new Exception("PhoneAccountHandle has " +
147428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger                    "been created with null ComponentName!"));
148428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger        }
149428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger        if(userHandle == null) {
150428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger            android.util.Log.w("PhoneAccountHandle", new Exception("PhoneAccountHandle has " +
151428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger                    "been created with null UserHandle!"));
152428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger        }
153428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger    }
154428cec9056234e32497a91da91d2f81e9309cd83Brad Ebinger
1556eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton    public static final Creator<PhoneAccountHandle> CREATOR = new Creator<PhoneAccountHandle>() {
156807fe0a19a710ae4e053e80f610807ff5718f1a1Ihab Awad        @Override
1576eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton        public PhoneAccountHandle createFromParcel(Parcel in) {
1586eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton            return new PhoneAccountHandle(in);
159542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad        }
160542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad
161807fe0a19a710ae4e053e80f610807ff5718f1a1Ihab Awad        @Override
1626eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton        public PhoneAccountHandle[] newArray(int size) {
1636eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton            return new PhoneAccountHandle[size];
164542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad        }
165542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad    };
166542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad
1676eb262c3515c927df19340b3eee8c74bc9478d16Evan Charlton    private PhoneAccountHandle(Parcel in) {
168134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton        this(ComponentName.CREATOR.createFromParcel(in),
169134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton                in.readString(),
170134dd68ff980b870ce61eef0a31ea0fa5f96f87dEvan Charlton                UserHandle.CREATOR.createFromParcel(in));
171c35ad0252d1ad9ae50e2dadd670783d4a6259df6Ihab Awad    }
172542e0ea8bfa60f09c33e4be366adf8681c25d0bfIhab Awad}
173