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