DataRowHandlerForPhoneNumber.java revision aa18c233fdec3359c5231d4a5f61188446bf5d6f
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * 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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License
15 */
16package com.android.providers.contacts;
17
18import android.content.ContentValues;
19import android.content.Context;
20import android.database.Cursor;
21import android.database.sqlite.SQLiteDatabase;
22import android.provider.ContactsContract.CommonDataKinds.Phone;
23import android.telephony.PhoneNumberUtils;
24import android.text.TextUtils;
25
26import com.android.providers.contacts.ContactsDatabaseHelper.PhoneLookupColumns;
27import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
28import com.android.providers.contacts.SearchIndexManager.IndexBuilder;
29import com.android.providers.contacts.aggregation.AbstractContactAggregator;
30
31/**
32 * Handler for phone number data rows.
33 */
34public class DataRowHandlerForPhoneNumber extends DataRowHandlerForCommonDataKind {
35
36    public DataRowHandlerForPhoneNumber(Context context,
37            ContactsDatabaseHelper dbHelper, AbstractContactAggregator aggregator) {
38        super(context, dbHelper, aggregator, Phone.CONTENT_ITEM_TYPE, Phone.TYPE, Phone.LABEL);
39    }
40
41    @Override
42    public long insert(SQLiteDatabase db, TransactionContext txContext, long rawContactId,
43            ContentValues values) {
44        fillNormalizedNumber(values);
45
46        final long dataId = super.insert(db, txContext, rawContactId, values);
47        if (values.containsKey(Phone.NUMBER)) {
48            final String number = values.getAsString(Phone.NUMBER);
49            final String normalizedNumber = values.getAsString(Phone.NORMALIZED_NUMBER);
50            updatePhoneLookup(db, rawContactId, dataId, number, normalizedNumber);
51            mContactAggregator.updateHasPhoneNumber(db, rawContactId);
52            fixRawContactDisplayName(db, txContext, rawContactId);
53
54            triggerAggregation(txContext, rawContactId);
55        }
56        return dataId;
57    }
58
59    @Override
60    public boolean update(SQLiteDatabase db, TransactionContext txContext, ContentValues values,
61            Cursor c, boolean callerIsSyncAdapter) {
62        fillNormalizedNumber(values);
63
64        if (!super.update(db, txContext, values, c, callerIsSyncAdapter)) {
65            return false;
66        }
67
68        if (values.containsKey(Phone.NUMBER)) {
69            long dataId = c.getLong(DataUpdateQuery._ID);
70            long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID);
71            updatePhoneLookup(db, rawContactId, dataId,
72                    values.getAsString(Phone.NUMBER),
73                    values.getAsString(Phone.NORMALIZED_NUMBER));
74            mContactAggregator.updateHasPhoneNumber(db, rawContactId);
75            fixRawContactDisplayName(db, txContext, rawContactId);
76
77            triggerAggregation(txContext, rawContactId);
78        }
79
80        return true;
81    }
82
83    private void fillNormalizedNumber(ContentValues values) {
84        // No NUMBER? Also ignore NORMALIZED_NUMBER
85        if (!values.containsKey(Phone.NUMBER)) {
86            values.remove(Phone.NORMALIZED_NUMBER);
87            return;
88        }
89
90        // NUMBER is given. Try to extract NORMALIZED_NUMBER from it, unless it is also given
91        final String number = values.getAsString(Phone.NUMBER);
92        final String numberE164 = values.getAsString(Phone.NORMALIZED_NUMBER);
93        if (number != null && numberE164 == null) {
94            final String newNumberE164 = PhoneNumberUtils.formatNumberToE164(number,
95                    mDbHelper.getCurrentCountryIso());
96            values.put(Phone.NORMALIZED_NUMBER, newNumberE164);
97        }
98    }
99
100    @Override
101    public int delete(SQLiteDatabase db, TransactionContext txContext, Cursor c) {
102        long dataId = c.getLong(DataDeleteQuery._ID);
103        long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID);
104
105        int count = super.delete(db, txContext, c);
106
107        updatePhoneLookup(db, rawContactId, dataId, null, null);
108        mContactAggregator.updateHasPhoneNumber(db, rawContactId);
109        fixRawContactDisplayName(db, txContext, rawContactId);
110        triggerAggregation(txContext, rawContactId);
111        return count;
112    }
113
114    private void updatePhoneLookup(SQLiteDatabase db, long rawContactId, long dataId,
115            String number, String numberE164) {
116        mSelectionArgs1[0] = String.valueOf(dataId);
117        db.delete(Tables.PHONE_LOOKUP, PhoneLookupColumns.DATA_ID + "=?", mSelectionArgs1);
118        if (number != null) {
119            String normalizedNumber = PhoneNumberUtils.normalizeNumber(number);
120            if (!TextUtils.isEmpty(normalizedNumber)) {
121                ContentValues phoneValues = new ContentValues();
122                phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactId);
123                phoneValues.put(PhoneLookupColumns.DATA_ID, dataId);
124                phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber);
125                phoneValues.put(PhoneLookupColumns.MIN_MATCH,
126                        PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber));
127                db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
128
129                if (numberE164 != null && !numberE164.equals(normalizedNumber)) {
130                    phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, numberE164);
131                    phoneValues.put(PhoneLookupColumns.MIN_MATCH,
132                            PhoneNumberUtils.toCallerIDMinMatch(numberE164));
133                    db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
134                }
135            }
136        }
137    }
138
139    @Override
140    protected int getTypeRank(int type) {
141        switch (type) {
142            case Phone.TYPE_MOBILE: return 0;
143            case Phone.TYPE_WORK: return 1;
144            case Phone.TYPE_HOME: return 2;
145            case Phone.TYPE_PAGER: return 3;
146            case Phone.TYPE_CUSTOM: return 4;
147            case Phone.TYPE_OTHER: return 5;
148            case Phone.TYPE_FAX_WORK: return 6;
149            case Phone.TYPE_FAX_HOME: return 7;
150            default: return 1000;
151        }
152    }
153
154    @Override
155    public boolean containsSearchableColumns(ContentValues values) {
156        return values.containsKey(Phone.NUMBER);
157    }
158
159    @Override
160    public void appendSearchableData(IndexBuilder builder) {
161        String number = builder.getString(Phone.NUMBER);
162        if (TextUtils.isEmpty(number)) {
163            return;
164        }
165
166        String normalizedNumber = PhoneNumberUtils.normalizeNumber(number);
167        if (TextUtils.isEmpty(normalizedNumber)) {
168            return;
169        }
170
171        builder.appendToken(normalizedNumber);
172
173        String numberE164 = PhoneNumberUtils.formatNumberToE164(
174                number, mDbHelper.getCurrentCountryIso());
175        if (numberE164 != null && !numberE164.equals(normalizedNumber)) {
176            builder.appendToken(numberE164);
177        }
178    }
179}
180