11197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee/*
21197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * Copyright (C) 2013 The Android Open Source Project
31197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee *
41197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License");
51197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * you may not use this file except in compliance with the License.
61197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * You may obtain a copy of the License at
71197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee *
81197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee *      http://www.apache.org/licenses/LICENSE-2.0
91197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee *
101197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * Unless required by applicable law or agreed to in writing, software
111197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * distributed under the License is distributed on an "AS IS" BASIS,
121197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * See the License for the specific language governing permissions and
141197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * limitations under the License.
151197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee */
161197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee
171197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leepackage com.android.dialer.interactions;
181197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee
19515575ebcf136c215579536c209d9e2644da16ceYorke Leeimport static android.Manifest.permission.READ_CONTACTS;
20515575ebcf136c215579536c209d9e2644da16ceYorke Leeimport static android.Manifest.permission.WRITE_CONTACTS;
21515575ebcf136c215579536c209d9e2644da16ceYorke Lee
221197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leeimport android.content.BroadcastReceiver;
231197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leeimport android.content.ContentValues;
241197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leeimport android.content.Context;
251197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leeimport android.content.Intent;
261197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leeimport android.database.Cursor;
271197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leeimport android.net.Uri;
289b8cc3fa7ea04358624466162fe3ca942673963dYorke Leeimport android.provider.ContactsContract;
291197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leeimport android.provider.ContactsContract.PhoneLookup;
301197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leeimport android.provider.ContactsContract.PinnedPositions;
31e2f52619318af486a4fef2bca86c8237c46603f6Yorke Leeimport android.text.TextUtils;
321197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee
33c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Leeimport com.android.contacts.common.util.PermissionsUtil;
34c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Lee
351197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee/**
361197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * This broadcast receiver is used to listen to outgoing calls and undemote formerly demoted
371197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee * contacts if a phone call is made to a phone number belonging to that contact.
387c414093c8c66a69cfea77a0ac10c1354f96cb7cMakoto Onuki *
397c414093c8c66a69cfea77a0ac10c1354f96cb7cMakoto Onuki * NOTE This doesn't work for corp contacts.
401197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee */
411197d3322b7905724b3eefe40ff8374dd5e26939Yorke Leepublic class UndemoteOutgoingCallReceiver extends BroadcastReceiver {
421197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee
431197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee    private static final long NO_CONTACT_FOUND = -1;
441197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee
451197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee    @Override
46a3ce90e2cbab33692837cc01ac12d0b48ab399f0Yorke Lee    public void onReceive(final Context context, Intent intent) {
47515575ebcf136c215579536c209d9e2644da16ceYorke Lee        if (!PermissionsUtil.hasPermission(context, READ_CONTACTS)
48515575ebcf136c215579536c209d9e2644da16ceYorke Lee            || !PermissionsUtil.hasPermission(context, WRITE_CONTACTS)) {
49c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Lee            return;
50c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Lee        }
511197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee        if (intent != null && Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
521197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee            final String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
53e2f52619318af486a4fef2bca86c8237c46603f6Yorke Lee            if (TextUtils.isEmpty(number)) {
54e2f52619318af486a4fef2bca86c8237c46603f6Yorke Lee                return;
55e2f52619318af486a4fef2bca86c8237c46603f6Yorke Lee            }
56c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Lee            new Thread() {
57ab9ae646ad4926b69dc02502861e8919b2cdb711Yorke Lee                @Override
58ab9ae646ad4926b69dc02502861e8919b2cdb711Yorke Lee                public void run() {
59ab9ae646ad4926b69dc02502861e8919b2cdb711Yorke Lee                    final long id = getContactIdFromPhoneNumber(context, number);
60ab9ae646ad4926b69dc02502861e8919b2cdb711Yorke Lee                    if (id != NO_CONTACT_FOUND) {
61a3ce90e2cbab33692837cc01ac12d0b48ab399f0Yorke Lee                        undemoteContactWithId(context, id);
62a3ce90e2cbab33692837cc01ac12d0b48ab399f0Yorke Lee                    }
63ab9ae646ad4926b69dc02502861e8919b2cdb711Yorke Lee                }
64c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Lee            }.start();
651197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee        }
661197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee    }
671197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee
681197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee    private void undemoteContactWithId(Context context, long id) {
691197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee        // If the contact is not demoted, this will not do anything. Otherwise, it will
701197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee        // restore it to an unpinned position. If it was a frequently called contact, it will
711197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee        // show up once again show up on the favorites screen.
72515575ebcf136c215579536c209d9e2644da16ceYorke Lee        if (PermissionsUtil.hasPermission(context, WRITE_CONTACTS)) {
73515575ebcf136c215579536c209d9e2644da16ceYorke Lee            try {
74515575ebcf136c215579536c209d9e2644da16ceYorke Lee                PinnedPositions.undemote(context.getContentResolver(), id);
75515575ebcf136c215579536c209d9e2644da16ceYorke Lee            } catch (SecurityException e) {
76515575ebcf136c215579536c209d9e2644da16ceYorke Lee                // Just in case
77515575ebcf136c215579536c209d9e2644da16ceYorke Lee            }
78515575ebcf136c215579536c209d9e2644da16ceYorke Lee        }
791197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee    }
801197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee
811197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee    private long getContactIdFromPhoneNumber(Context context, String number) {
82515575ebcf136c215579536c209d9e2644da16ceYorke Lee        if (!PermissionsUtil.hasPermission(context, READ_CONTACTS)) {
83515575ebcf136c215579536c209d9e2644da16ceYorke Lee            return NO_CONTACT_FOUND;
84515575ebcf136c215579536c209d9e2644da16ceYorke Lee        }
851197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee        final Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
861197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee                Uri.encode(number));
87515575ebcf136c215579536c209d9e2644da16ceYorke Lee        final Cursor cursor;
88515575ebcf136c215579536c209d9e2644da16ceYorke Lee        try {
89515575ebcf136c215579536c209d9e2644da16ceYorke Lee            cursor = context.getContentResolver().query(contactUri, new String[] {
90515575ebcf136c215579536c209d9e2644da16ceYorke Lee                    PhoneLookup._ID}, null, null, null);
91515575ebcf136c215579536c209d9e2644da16ceYorke Lee        } catch (SecurityException e) {
92515575ebcf136c215579536c209d9e2644da16ceYorke Lee            // Just in case
93515575ebcf136c215579536c209d9e2644da16ceYorke Lee            return NO_CONTACT_FOUND;
94515575ebcf136c215579536c209d9e2644da16ceYorke Lee        }
953fee3e5a6ac02e4ddc536e4739d336341d22e19aYorke Lee        if (cursor == null) {
963fee3e5a6ac02e4ddc536e4739d336341d22e19aYorke Lee            return NO_CONTACT_FOUND;
973fee3e5a6ac02e4ddc536e4739d336341d22e19aYorke Lee        }
981197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee        try {
991197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee            if (cursor.moveToFirst()) {
1001197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee                final long id = cursor.getLong(0);
1011197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee                return id;
1021197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee            } else {
1031197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee                return NO_CONTACT_FOUND;
1041197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee            }
1051197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee        } finally {
1061197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee            cursor.close();
1071197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee        }
1081197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee    }
1091197d3322b7905724b3eefe40ff8374dd5e26939Yorke Lee}
110