• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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.accounts;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.compat.annotation.UnsupportedAppUsage;
22 import android.content.Context;
23 import android.os.Build;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.os.RemoteException;
27 import android.os.ServiceManager;
28 import android.text.TextUtils;
29 import android.util.ArraySet;
30 import android.util.Log;
31 
32 import com.android.internal.annotations.GuardedBy;
33 
34 import java.util.Set;
35 
36 /**
37  * Value type that represents an Account in the {@link AccountManager}. This object is
38  * {@link Parcelable} and also overrides {@link #equals} and {@link #hashCode}, making it
39  * suitable for use as the key of a {@link java.util.Map}
40  */
41 public class Account implements Parcelable {
42     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
43     private static final String TAG = "Account";
44 
45     @GuardedBy("sAccessedAccounts")
46     private static final Set<Account> sAccessedAccounts = new ArraySet<>();
47 
48     public final String name;
49     public final String type;
50     private String mSafeName;
51     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
52     private final @Nullable String accessId;
53 
equals(@ullable Object o)54     public boolean equals(@Nullable Object o) {
55         if (o == this) return true;
56         if (!(o instanceof Account)) return false;
57         final Account other = (Account)o;
58         return name.equals(other.name) && type.equals(other.type);
59     }
60 
hashCode()61     public int hashCode() {
62         int result = 17;
63         result = 31 * result + name.hashCode();
64         result = 31 * result + type.hashCode();
65         return result;
66     }
67 
Account(String name, String type)68     public Account(String name, String type) {
69         this(name, type, null);
70     }
71 
72     /**
73      * @hide
74      */
Account(@onNull Account other, @NonNull String accessId)75     public Account(@NonNull Account other, @NonNull String accessId) {
76         this(other.name, other.type, accessId);
77     }
78 
79     /**
80      * @hide
81      */
Account(String name, String type, String accessId)82     public Account(String name, String type, String accessId) {
83         if (TextUtils.isEmpty(name)) {
84             throw new IllegalArgumentException("the name must not be empty: " + name);
85         }
86         if (TextUtils.isEmpty(type)) {
87             throw new IllegalArgumentException("the type must not be empty: " + type);
88         }
89         this.name = name;
90         this.type = type;
91         this.accessId = accessId;
92     }
93 
Account(Parcel in)94     public Account(Parcel in) {
95         this.name = in.readString();
96         this.type = in.readString();
97         if (TextUtils.isEmpty(name)) {
98             throw new android.os.BadParcelableException("the name must not be empty: " + name);
99         }
100         if (TextUtils.isEmpty(type)) {
101             throw new android.os.BadParcelableException("the type must not be empty: " + type);
102         }
103         this.accessId = in.readString();
104         if (accessId != null) {
105             synchronized (sAccessedAccounts) {
106                 if (sAccessedAccounts.add(this)) {
107                     try {
108                         IAccountManager accountManager = IAccountManager.Stub.asInterface(
109                                 ServiceManager.getService(Context.ACCOUNT_SERVICE));
110                         accountManager.onAccountAccessed(accessId);
111                     } catch (RemoteException e) {
112                         Log.e(TAG, "Error noting account access", e);
113                     }
114                 }
115             }
116         }
117     }
118 
119     /** @hide */
getAccessId()120     public String getAccessId() {
121         return accessId;
122     }
123 
describeContents()124     public int describeContents() {
125         return 0;
126     }
127 
writeToParcel(Parcel dest, int flags)128     public void writeToParcel(Parcel dest, int flags) {
129         dest.writeString(name);
130         dest.writeString(type);
131         dest.writeString(accessId);
132     }
133 
134     public static final @android.annotation.NonNull Creator<Account> CREATOR = new Creator<Account>() {
135         public Account createFromParcel(Parcel source) {
136             return new Account(source);
137         }
138 
139         public Account[] newArray(int size) {
140             return new Account[size];
141         }
142     };
143 
toString()144     public String toString() {
145         return "Account {name=" + name + ", type=" + type + "}";
146     }
147 
148     /**
149      * Return a string representation of the account that is safe to print
150      * to logs and other places where PII should be avoided.
151      * @hide
152      */
toSafeString()153     public String toSafeString() {
154         if (mSafeName == null) {
155             mSafeName = toSafeName(name, 'x');
156         }
157         return "Account {name=" + mSafeName + ", type=" + type + "}";
158     }
159 
160     /**
161      * Given a name, replace all letter or digits with the replacement char.
162      * @param name The input name string.
163      * @param replacement the replacement character.
164      * @return the string after replacement.
165      * @hide
166      */
toSafeName(String name, char replacement)167     public static String toSafeName(String name, char replacement) {
168         final StringBuilder builder = new StringBuilder(64);
169         final int len = name.length();
170         for (int i = 0; i < len; i++) {
171             final char c = name.charAt(i);
172             if (Character.isLetterOrDigit(c)) {
173                 builder.append(replacement);
174             } else {
175                 builder.append(c);
176             }
177         }
178         return builder.toString();
179     }
180 }
181