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 com.android.contacts.editor;
18 
19 import com.android.contacts.common.model.AccountTypeManager;
20 import com.android.contacts.common.model.RawContactDelta;
21 import com.android.contacts.common.model.account.AccountType;
22 import com.android.contacts.common.model.account.GoogleAccountType;
23 
24 import android.content.Context;
25 import android.provider.ContactsContract.RawContacts;
26 
27 import java.util.Comparator;
28 
29 /**
30  * Compares {@link RawContactDelta}s
31  */
32 class RawContactDeltaComparator implements Comparator<RawContactDelta> {
33 
34     private Context mContext;
35 
RawContactDeltaComparator(Context context)36     public RawContactDeltaComparator(Context context) {
37         mContext = context;
38     }
39 
40     @Override
compare(RawContactDelta one, RawContactDelta two)41     public int compare(RawContactDelta one, RawContactDelta two) {
42         // Check direct equality
43         if (one.equals(two)) {
44             return 0;
45         }
46 
47         final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
48         String accountType1 = one.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
49         String dataSet1 = one.getValues().getAsString(RawContacts.DATA_SET);
50         final AccountType type1 = accountTypes.getAccountType(accountType1, dataSet1);
51         String accountType2 = two.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
52         String dataSet2 = two.getValues().getAsString(RawContacts.DATA_SET);
53         final AccountType type2 = accountTypes.getAccountType(accountType2, dataSet2);
54 
55         // Check read-only. Sort read/write before read-only.
56         if (!type1.areContactsWritable() && type2.areContactsWritable()) {
57             return 1;
58         } else if (type1.areContactsWritable() && !type2.areContactsWritable()) {
59             return -1;
60         }
61 
62         // Check account type. Sort Google before non-Google.
63         boolean skipAccountTypeCheck = false;
64         boolean isGoogleAccount1 = type1 instanceof GoogleAccountType;
65         boolean isGoogleAccount2 = type2 instanceof GoogleAccountType;
66         if (isGoogleAccount1 && !isGoogleAccount2) {
67             return -1;
68         } else if (!isGoogleAccount1 && isGoogleAccount2) {
69             return 1;
70         } else if (isGoogleAccount1 && isGoogleAccount2) {
71             skipAccountTypeCheck = true;
72         }
73 
74         int value;
75         if (!skipAccountTypeCheck) {
76             // Sort accounts with type before accounts without types.
77             if (type1.accountType != null && type2.accountType == null) {
78                 return -1;
79             } else if (type1.accountType == null && type2.accountType != null) {
80                 return 1;
81             }
82 
83             if (type1.accountType != null && type2.accountType != null) {
84                 value = type1.accountType.compareTo(type2.accountType);
85                 if (value != 0) {
86                     return value;
87                 }
88             }
89 
90             // Fall back to data set. Sort accounts with data sets before
91             // those without.
92             if (type1.dataSet != null && type2.dataSet == null) {
93                 return -1;
94             } else if (type1.dataSet == null && type2.dataSet != null) {
95                 return 1;
96             }
97 
98             if (type1.dataSet != null && type2.dataSet != null) {
99                 value = type1.dataSet.compareTo(type2.dataSet);
100                 if (value != 0) {
101                     return value;
102                 }
103             }
104         }
105 
106         // Check account name
107         String oneAccount = one.getAccountName();
108         if (oneAccount == null) {
109             oneAccount = "";
110         }
111         String twoAccount = two.getAccountName();
112         if (twoAccount == null) {
113             twoAccount = "";
114         }
115         value = oneAccount.compareTo(twoAccount);
116         if (value != 0) {
117             return value;
118         }
119 
120         // Both are in the same account, fall back to contact ID
121         Long oneId = one.getRawContactId();
122         Long twoId = two.getRawContactId();
123         if (oneId == null && twoId == null) {
124             return 0;
125         } else if (oneId == null) {
126             return -1;
127         } else if (twoId == null) {
128             return 1;
129         }
130 
131         return Long.compare(oneId, twoId);
132     }
133 }
134