1 /*
2  * Copyright (C) 2016 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 package com.android.contacts.group;
17 
18 import android.content.ContentUris;
19 import android.content.Context;
20 import android.database.Cursor;
21 import android.net.Uri;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.provider.ContactsContract;
25 import android.text.TextUtils;
26 
27 import com.android.contacts.GroupMetaDataLoader;
28 import com.android.contacts.model.AccountTypeManager;
29 import com.android.contacts.model.account.AccountType;
30 
31 import com.google.common.base.MoreObjects;
32 
33 /** Meta data for a contact group. */
34 public final class GroupMetaData implements Parcelable {
35 
36     public static final Creator<GroupMetaData> CREATOR = new Creator<GroupMetaData>() {
37 
38         public GroupMetaData createFromParcel(Parcel in) {
39             return new GroupMetaData(in);
40         }
41 
42         public GroupMetaData[] newArray(int size) {
43             return new GroupMetaData[size];
44         }
45     };
46 
47     public final Uri uri;
48     public final String accountName;
49     public final String accountType;
50     public final String dataSet;
51     public final long groupId;
52     public final String groupName;
53     public final boolean readOnly;
54     public final boolean defaultGroup;
55     public final boolean favorites;
56     public final boolean editable;
57 
58     /**
59      * @param cursor Cursor loaded with {@link GroupMetaDataLoader#COLUMNS} as the projection.
60      */
GroupMetaData(Context context, Cursor cursor)61     public GroupMetaData(Context context, Cursor cursor) {
62         final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(context);
63         final long groupId = cursor.getLong(GroupMetaDataLoader.GROUP_ID);
64         final Uri groupUri = ContentUris.withAppendedId(
65                 ContactsContract.Groups.CONTENT_URI, groupId);
66         final AccountType accountType = accountTypeManager.getAccountType(
67                 cursor.getString(GroupMetaDataLoader.ACCOUNT_TYPE),
68                 cursor.getString(GroupMetaDataLoader.DATA_SET));
69         final boolean editable = accountType == null
70                 ? false : accountType.isGroupMembershipEditable();
71 
72         this.uri = groupUri;
73         this.accountName = cursor.getString(GroupMetaDataLoader.ACCOUNT_NAME);
74         this.accountType = cursor.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
75         this.dataSet = cursor.getString(GroupMetaDataLoader.DATA_SET);
76         this.groupId = groupId;
77         this.groupName = cursor.getString(GroupMetaDataLoader.TITLE);
78         this.readOnly = getBoolean(cursor, GroupMetaDataLoader.IS_READ_ONLY);
79         this.defaultGroup = getBoolean(cursor, GroupMetaDataLoader.AUTO_ADD);
80         this.favorites = getBoolean(cursor, GroupMetaDataLoader.FAVORITES);
81         this.editable = editable;
82     }
83 
getBoolean(Cursor cursor, int columnIndex)84     private static boolean getBoolean(Cursor cursor, int columnIndex) {
85          return cursor.isNull(columnIndex) ? false : cursor.getInt(columnIndex) != 0;
86     }
87 
GroupMetaData(Parcel source)88     private GroupMetaData(Parcel source) {
89         uri = source.readParcelable(Uri.class.getClassLoader());
90         accountName = source.readString();
91         accountType = source.readString();
92         dataSet = source.readString();
93         groupId = source.readLong();
94         groupName = source.readString();
95         readOnly = source.readInt() == 1;
96         defaultGroup = source.readInt() == 1;
97         favorites = source.readInt() == 1;
98         editable = source.readInt() == 1;
99     }
100 
101     @Override
writeToParcel(Parcel dest, int flags)102     public void writeToParcel(Parcel dest, int flags) {
103         dest.writeParcelable(uri, 0);
104         dest.writeString(accountName);
105         dest.writeString(accountType);
106         dest.writeString(dataSet);
107         dest.writeLong(groupId);
108         dest.writeString(groupName);
109         dest.writeInt(readOnly ? 1 : 0);
110         dest.writeInt(defaultGroup ? 1 : 0);
111         dest.writeInt(favorites ? 1 : 0);
112         dest.writeInt(editable ? 1 : 0);
113     }
114 
115     /** Whether all metadata fields are set. */
isValid()116     public boolean isValid() {
117         return uri != null
118                 && !TextUtils.isEmpty(accountName)
119                 && !TextUtils.isEmpty(groupName)
120                 && groupId > 0;
121     }
122 
123     @Override
describeContents()124     public int describeContents() {
125         return 0;
126     }
127 
128     @Override
toString()129     public String toString() {
130         return MoreObjects.toStringHelper(this)
131                 .add("accountName", accountName)
132                 .add("accountType", accountType)
133                 .add("dataSet", dataSet)
134                 .add("groupId", groupId)
135                 .add("groupName", groupName)
136                 .add("readOnly", readOnly)
137                 .add("defaultGroup", defaultGroup)
138                 .add("favorites", favorites)
139                 .add("editable", editable)
140                 .add("isValid", isValid())
141                 .toString();
142     }
143 }