Add outgoing call receiver to undemote a contact

Bug: 10292569
Change-Id: I377220822970d46c6706a636fbcc54f8eb2c8758
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d268345..2ec746e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -27,6 +27,7 @@
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
     <uses-permission android:name="android.permission.NFC" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
@@ -238,6 +239,12 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name=".interactions.UndemoteOutgoingCallReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
+            </intent-filter>
+        </receiver>
+
         <service
             android:name=".calllog.CallLogNotificationsService"
             android:exported="false"
diff --git a/src/com/android/dialer/interactions/PhoneNumberInteraction.java b/src/com/android/dialer/interactions/PhoneNumberInteraction.java
index 8c64c5f..722b9b3 100644
--- a/src/com/android/dialer/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/dialer/interactions/PhoneNumberInteraction.java
@@ -309,15 +309,6 @@
     }
 
     private void performAction(String phoneNumber) {
-        if (mInteractionType == ContactDisplayUtils.INTERACTION_CALL && mContactId !=
-                UNKNOWN_CONTACT_ID) {
-            // Since we are making an outgoing call to this contact, undemote it here.
-            // If the contact is not demoted, this will not do anything.
-            final ContentValues cv = new ContentValues(1);
-            cv.put(String.valueOf(mContactId), PinnedPositions.UNDEMOTE);
-            mContext.getContentResolver().update(PinnedPositions.UPDATE_URI, cv, null, null);
-        }
-
         PhoneNumberInteraction.performAction(mContext, phoneNumber, mInteractionType, mCallOrigin);
     }
 
diff --git a/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java b/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java
new file mode 100644
index 0000000..8782ce4
--- /dev/null
+++ b/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dialer.interactions;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract.PhoneLookup;
+import android.provider.ContactsContract.PinnedPositions;
+
+/**
+ * This broadcast receiver is used to listen to outgoing calls and undemote formerly demoted
+ * contacts if a phone call is made to a phone number belonging to that contact.
+ */
+public class UndemoteOutgoingCallReceiver extends BroadcastReceiver {
+
+    private static final long NO_CONTACT_FOUND = -1;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (intent != null && Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
+            final String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
+            final long id = getContactIdFromPhoneNumber(context, number);
+            if (id != NO_CONTACT_FOUND) {
+                undemoteContactWithId(context, id);
+            }
+        }
+    }
+
+    private void undemoteContactWithId(Context context, long id) {
+        final ContentValues cv = new ContentValues(1);
+        cv.put(String.valueOf(id), PinnedPositions.UNDEMOTE);
+        // If the contact is not demoted, this will not do anything. Otherwise, it will
+        // restore it to an unpinned position. If it was a frequently called contact, it will
+        // show up once again show up on the favorites screen.
+        context.getContentResolver().update(PinnedPositions.UPDATE_URI, cv, null, null);
+    }
+
+    private long getContactIdFromPhoneNumber(Context context, String number) {
+        final Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
+                Uri.encode(number));
+        final Cursor cursor = context.getContentResolver().query(contactUri, new String[] {
+                PhoneLookup._ID}, null, null, null);
+        try {
+            if (cursor.moveToFirst()) {
+                final long id = cursor.getLong(0);
+                return id;
+            } else {
+                return NO_CONTACT_FOUND;
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+}