diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index f7f5028..babae74 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -802,11 +802,6 @@
     @Override
     public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
         if (cookie instanceof Long) {
-            if (VDBG) log("CallerInfo query complete, posting missed call notification");
-
-            mApplication.notificationMgr.notifyMissedCall(ci.name, ci.phoneNumber,
-                    ci.numberPresentation, ci.phoneLabel, ci.cachedPhoto, ci.cachedPhotoIcon,
-                    ((Long) cookie).longValue());
         } else if (cookie instanceof Connection) {
             final Connection c = (Connection) cookie;
             if (VDBG) log("CallerInfo query complete (for CallNotifier), "
@@ -1050,17 +1045,6 @@
                 }
             }
 
-            final long date = c.getCreateTime();
-            final int cause = c.getDisconnectCause();
-            final boolean missedCall = c.isIncoming() &&
-                    (cause == DisconnectCause.INCOMING_MISSED);
-            if (missedCall) {
-                // Show the "Missed call" notification.
-                // (Note we *don't* do this if this was an incoming call that
-                // the user deliberately rejected.)
-                showMissedCallNotification(c, date);
-            }
-
             // Possibly play a "post-disconnect tone" thru the earpiece.
             // We do this here, rather than from the InCallScreen
             // activity, since we need to do this even if you're not in
@@ -1079,6 +1063,7 @@
                 // when *that* connection's "disconnect" event comes in.)
             }
 
+            final int cause = c.getDisconnectCause();
             if (((mPreviousCdmaCallState == Call.State.DIALING)
                     || (mPreviousCdmaCallState == Call.State.ALERTING))
                     && (!isEmergencyNumber)
@@ -1641,11 +1626,7 @@
                 // the abstraction for CDMA devices.
                 mCallLogger.logCall(c, callLogType);
 
-                final long date = c.getCreateTime();
-                if (callLogType == Calls.MISSED_TYPE) {
-                    // Add missed call notification
-                    showMissedCallNotification(c, date);
-                } else {
+                if (callLogType != Calls.MISSED_TYPE) {
                     // Remove Call waiting 20 second display timer in the queue
                     removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE);
                 }
@@ -1685,44 +1666,6 @@
     }
 
     /**
-     * Helper function used to show a missed call notification.
-     */
-    private void showMissedCallNotification(Connection c, final long date) {
-        PhoneUtils.CallerInfoToken info =
-                PhoneUtils.startGetCallerInfo(mApplication, c, this, Long.valueOf(date));
-        if (info != null) {
-            // at this point, we've requested to start a query, but it makes no
-            // sense to log this missed call until the query comes back.
-            if (VDBG) log("showMissedCallNotification: Querying for CallerInfo on missed call...");
-            if (info.isFinal) {
-                // it seems that the query we have actually is up to date.
-                // send the notification then.
-                CallerInfo ci = info.currentInfo;
-
-                // Check number presentation value; if we have a non-allowed presentation,
-                // then display an appropriate presentation string instead as the missed
-                // call.
-                String name = ci.name;
-                String number = ci.phoneNumber;
-                if (ci.numberPresentation == PhoneConstants.PRESENTATION_RESTRICTED) {
-                    name = mApplication.getString(R.string.private_num);
-                } else if (ci.numberPresentation != PhoneConstants.PRESENTATION_ALLOWED) {
-                    name = mApplication.getString(R.string.unknown);
-                } else {
-                    number = PhoneUtils.modifyForSpecialCnapCases(mApplication,
-                            ci, number, ci.numberPresentation);
-                }
-                mApplication.notificationMgr.notifyMissedCall(name, number, ci.numberPresentation,
-                        ci.phoneLabel, ci.cachedPhoto, ci.cachedPhotoIcon, date);
-            }
-        } else {
-            // getCallerInfo() can return null in rare cases, like if we weren't
-            // able to get a valid phone number out of the specified Connection.
-            Log.w(LOG_TAG, "showMissedCallNotification: got null CallerInfo for Connection " + c);
-        }
-    }
-
-    /**
      *  Inner class to handle emergency call tone and vibrator
      */
     private class EmergencyTonePlayerVibrator {
diff --git a/src/com/android/phone/ClearMissedCallsService.java b/src/com/android/phone/ClearMissedCallsService.java
deleted file mode 100644
index b882472..0000000
--- a/src/com/android/phone/ClearMissedCallsService.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 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.phone;
-
-import android.app.IntentService;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.provider.CallLog.Calls;
-
-/**
- * Handles the intent to clear the missed calls that is triggered when a notification is dismissed.
- */
-public class ClearMissedCallsService extends IntentService {
-    /** This action is used to clear missed calls. */
-    public static final String ACTION_CLEAR_MISSED_CALLS =
-            "com.android.phone.intent.CLEAR_MISSED_CALLS";
-
-    private PhoneGlobals mApp;
-
-    public ClearMissedCallsService() {
-        super(ClearMissedCallsService.class.getSimpleName());
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mApp = PhoneGlobals.getInstance();
-    }
-
-    @Override
-    protected void onHandleIntent(Intent intent) {
-        if (ACTION_CLEAR_MISSED_CALLS.equals(intent.getAction())) {
-            // Clear the list of new missed calls.
-            ContentValues values = new ContentValues();
-            values.put(Calls.NEW, 0);
-            values.put(Calls.IS_READ, 1);
-            StringBuilder where = new StringBuilder();
-            where.append(Calls.NEW);
-            where.append(" = 1 AND ");
-            where.append(Calls.TYPE);
-            where.append(" = ?");
-            getContentResolver().update(Calls.CONTENT_URI, values, where.toString(),
-                    new String[]{ Integer.toString(Calls.MISSED_TYPE) });
-            mApp.notificationMgr.cancelMissedCallNotification();
-        }
-    }
-}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 7435747..39df173 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -74,31 +74,19 @@
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
-    private static final String[] CALL_LOG_PROJECTION = new String[] {
-        Calls._ID,
-        Calls.NUMBER,
-        Calls.NUMBER_PRESENTATION,
-        Calls.DATE,
-        Calls.DURATION,
-        Calls.TYPE,
-    };
-
     // notification types
-    static final int MISSED_CALL_NOTIFICATION = 1;
-    static final int IN_CALL_NOTIFICATION = 2;
-    static final int MMI_NOTIFICATION = 3;
-    static final int NETWORK_SELECTION_NOTIFICATION = 4;
-    static final int VOICEMAIL_NOTIFICATION = 5;
-    static final int CALL_FORWARD_NOTIFICATION = 6;
-    static final int DATA_DISCONNECTED_ROAMING_NOTIFICATION = 7;
-    static final int SELECTED_OPERATOR_FAIL_NOTIFICATION = 8;
+    static final int MMI_NOTIFICATION = 1;
+    static final int NETWORK_SELECTION_NOTIFICATION = 2;
+    static final int VOICEMAIL_NOTIFICATION = 3;
+    static final int CALL_FORWARD_NOTIFICATION = 4;
+    static final int DATA_DISCONNECTED_ROAMING_NOTIFICATION = 5;
+    static final int SELECTED_OPERATOR_FAIL_NOTIFICATION = 6;
 
     /** The singleton NotificationMgr instance. */
     private static NotificationMgr sInstance;
 
     private PhoneGlobals mApp;
     private Phone mPhone;
-    private CallManager mCM;
 
     private Context mContext;
     private NotificationManager mNotificationManager;
@@ -107,9 +95,6 @@
 
     public StatusBarHelper statusBarHelper;
 
-    // used to track the missed call counter, default to 0.
-    private int mNumberMissedCalls = 0;
-
     // used to track the notification of selected network unavailable
     private boolean mSelectedUnavailableNotify = false;
 
@@ -118,14 +103,9 @@
     private static final int VM_NUMBER_RETRY_DELAY_MILLIS = 10000;
     private int mVmNumberRetriesRemaining = MAX_VM_NUMBER_RETRIES;
 
-    // Query used to look up caller-id info for the "call log" notification.
-    private QueryHandler mQueryHandler = null;
-    private static final int CALL_LOG_TOKEN = -1;
-    private static final int CONTACT_TOKEN = -2;
-
     /**
      * Private constructor (this is a singleton).
-     * @see init()
+     * @see #init(PhoneGlobals)
      */
     private NotificationMgr(PhoneGlobals app) {
         mApp = app;
@@ -135,7 +115,6 @@
         mStatusBarManager =
                 (StatusBarManager) app.getSystemService(Context.STATUS_BAR_SERVICE);
         mPhone = app.phone;  // TODO: better style to use mCM.getDefaultPhone() everywhere instead
-        mCM = app.mCM;
         statusBarHelper = new StatusBarHelper();
     }
 
@@ -151,8 +130,6 @@
         synchronized (NotificationMgr.class) {
             if (sInstance == null) {
                 sInstance = new NotificationMgr(app);
-                // Update the notifications that need to be touched at startup.
-                sInstance.updateNotificationsAtStartup();
             } else {
                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
             }
@@ -255,31 +232,6 @@
         }
     }
 
-    /**
-     * Makes sure phone-related notifications are up to date on a
-     * freshly-booted device.
-     */
-    private void updateNotificationsAtStartup() {
-        if (DBG) log("updateNotificationsAtStartup()...");
-
-        // instantiate query handler
-        mQueryHandler = new QueryHandler(mContext.getContentResolver());
-
-        // setup query spec, look for all Missed calls that are new.
-        StringBuilder where = new StringBuilder("type=");
-        where.append(Calls.MISSED_TYPE);
-        where.append(" AND new=1");
-
-        // start the query
-        if (DBG) log("- start call log query...");
-        mQueryHandler.startQuery(CALL_LOG_TOKEN, null, Calls.CONTENT_URI,  CALL_LOG_PROJECTION,
-                where.toString(), null, Calls.DEFAULT_SORT_ORDER);
-
-        // Depend on android.app.StatusBarManager to be set to
-        // disable(DISABLE_NONE) upon startup.  This will be the
-        // case even if the phone app crashes.
-    }
-
     /** The projection to use when querying the phones table */
     static final String[] PHONES_PROJECTION = new String[] {
         PhoneLookup.NUMBER,
@@ -288,306 +240,6 @@
     };
 
     /**
-     * Class used to run asynchronous queries to re-populate the notifications we care about.
-     * There are really 3 steps to this:
-     *  1. Find the list of missed calls
-     *  2. For each call, run a query to retrieve the caller's name.
-     *  3. For each caller, try obtaining photo.
-     */
-    private class QueryHandler extends AsyncQueryHandler
-            implements ContactsAsyncHelper.OnImageLoadCompleteListener {
-
-        /**
-         * Used to store relevant fields for the Missed Call
-         * notifications.
-         */
-        private class NotificationInfo {
-            public String name;
-            public String number;
-            public int presentation;
-            /**
-             * Type of the call. {@link android.provider.CallLog.Calls#INCOMING_TYPE}
-             * {@link android.provider.CallLog.Calls#OUTGOING_TYPE}, or
-             * {@link android.provider.CallLog.Calls#MISSED_TYPE}.
-             */
-            public String type;
-            public long date;
-        }
-
-        public QueryHandler(ContentResolver cr) {
-            super(cr);
-        }
-
-        /**
-         * Handles the query results.
-         */
-        @Override
-        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
-            // TODO: it would be faster to use a join here, but for the purposes
-            // of this small record set, it should be ok.
-
-            // Note that CursorJoiner is not useable here because the number
-            // comparisons are not strictly equals; the comparisons happen in
-            // the SQL function PHONE_NUMBERS_EQUAL, which is not available for
-            // the CursorJoiner.
-
-            // Executing our own query is also feasible (with a join), but that
-            // will require some work (possibly destabilizing) in Contacts
-            // Provider.
-
-            // At this point, we will execute subqueries on each row just as
-            // CallLogActivity.java does.
-            switch (token) {
-                case CALL_LOG_TOKEN:
-                    if (DBG) log("call log query complete.");
-
-                    // initial call to retrieve the call list.
-                    if (cursor != null) {
-                        while (cursor.moveToNext()) {
-                            // for each call in the call log list, create
-                            // the notification object and query contacts
-                            NotificationInfo n = getNotificationInfo (cursor);
-
-                            if (DBG) log("query contacts for number: " + n.number);
-
-                            mQueryHandler.startQuery(CONTACT_TOKEN, n,
-                                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, n.number),
-                                    PHONES_PROJECTION, null, null, PhoneLookup.NUMBER);
-                        }
-
-                        if (DBG) log("closing call log cursor.");
-                        cursor.close();
-                    }
-                    break;
-                case CONTACT_TOKEN:
-                    if (DBG) log("contact query complete.");
-
-                    // subqueries to get the caller name.
-                    if ((cursor != null) && (cookie != null)){
-                        NotificationInfo n = (NotificationInfo) cookie;
-
-                        Uri personUri = null;
-                        if (cursor.moveToFirst()) {
-                            n.name = cursor.getString(
-                                    cursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME));
-                            long person_id = cursor.getLong(
-                                    cursor.getColumnIndexOrThrow(PhoneLookup._ID));
-                            if (DBG) {
-                                log("contact :" + n.name + " found for phone: " + n.number
-                                        + ". id : " + person_id);
-                            }
-                            personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, person_id);
-                        }
-
-                        if (personUri != null) {
-                            if (DBG) {
-                                log("Start obtaining picture for the missed call. Uri: "
-                                        + personUri);
-                            }
-                            // Now try to obtain a photo for this person.
-                            // ContactsAsyncHelper will do that and call onImageLoadComplete()
-                            // after that.
-                            ContactsAsyncHelper.startObtainPhotoAsync(
-                                    0, mContext, personUri, this, n);
-                        } else {
-                            if (DBG) {
-                                log("Failed to find Uri for obtaining photo."
-                                        + " Just send notification without it.");
-                            }
-                            // We couldn't find person Uri, so we're sure we cannot obtain a photo.
-                            // Call notifyMissedCall() right now.
-                            notifyMissedCall(n.name, n.number, n.presentation, n.type, null, null,
-                                    n.date);
-                        }
-
-                        if (DBG) log("closing contact cursor.");
-                        cursor.close();
-                    }
-                    break;
-                default:
-            }
-        }
-
-        @Override
-        public void onImageLoadComplete(
-                int token, Drawable photo, Bitmap photoIcon, Object cookie) {
-            if (DBG) log("Finished loading image: " + photo);
-            NotificationInfo n = (NotificationInfo) cookie;
-            notifyMissedCall(n.name, n.number, n.presentation, n.type, photo, photoIcon, n.date);
-        }
-
-        /**
-         * Factory method to generate a NotificationInfo object given a
-         * cursor from the call log table.
-         */
-        private final NotificationInfo getNotificationInfo(Cursor cursor) {
-            NotificationInfo n = new NotificationInfo();
-            n.name = null;
-            n.number = cursor.getString(cursor.getColumnIndexOrThrow(Calls.NUMBER));
-            n.presentation = cursor.getInt(cursor.getColumnIndexOrThrow(Calls.NUMBER_PRESENTATION));
-            n.type = cursor.getString(cursor.getColumnIndexOrThrow(Calls.TYPE));
-            n.date = cursor.getLong(cursor.getColumnIndexOrThrow(Calls.DATE));
-
-            // make sure we update the number depending upon saved values in
-            // CallLog.addCall().  If either special values for unknown or
-            // private number are detected, we need to hand off the message
-            // to the missed call notification.
-            if (n.presentation != Calls.PRESENTATION_ALLOWED) {
-                n.number = null;
-            }
-
-            if (DBG) log("NotificationInfo constructed for number: " + n.number);
-
-            return n;
-        }
-    }
-
-    /**
-     * Configures a Notification to emit the blinky green message-waiting/
-     * missed-call signal.
-     */
-    private static void configureLedNotification(Notification note) {
-        note.flags |= Notification.FLAG_SHOW_LIGHTS;
-        note.defaults |= Notification.DEFAULT_LIGHTS;
-    }
-
-    /**
-     * Displays a notification about a missed call.
-     *
-     * @param name the contact name.
-     * @param number the phone number. Note that this may be a non-callable String like "Unknown",
-     * or "Private Number", which possibly come from methods like
-     * {@link PhoneUtils#modifyForSpecialCnapCases(Context, CallerInfo, String, int)}.
-     * @param type the type of the call. {@link android.provider.CallLog.Calls#INCOMING_TYPE}
-     * {@link android.provider.CallLog.Calls#OUTGOING_TYPE}, or
-     * {@link android.provider.CallLog.Calls#MISSED_TYPE}
-     * @param photo picture which may be used for the notification (when photoIcon is null).
-     * This also can be null when the picture itself isn't available. If photoIcon is available
-     * it should be prioritized (because this may be too huge for notification).
-     * See also {@link ContactsAsyncHelper}.
-     * @param photoIcon picture which should be used for the notification. Can be null. This is
-     * the most suitable for {@link android.app.Notification.Builder#setLargeIcon(Bitmap)}, this
-     * should be used when non-null.
-     * @param date the time when the missed call happened
-     */
-    /* package */ void notifyMissedCall(String name, String number, int presentation, String type,
-            Drawable photo, Bitmap photoIcon, long date) {
-
-        // When the user clicks this notification, we go to the call log.
-        final PendingIntent pendingCallLogIntent = PhoneGlobals.createPendingCallLogIntent(
-                mContext);
-
-        // Never display the missed call notification on non-voice-capable
-        // devices, even if the device does somehow manage to get an
-        // incoming call.
-        if (!PhoneGlobals.sVoiceCapable) {
-            if (DBG) log("notifyMissedCall: non-voice-capable device, not posting notification");
-            return;
-        }
-
-        if (VDBG) {
-            log("notifyMissedCall(). name: " + name + ", number: " + number
-                + ", label: " + type + ", photo: " + photo + ", photoIcon: " + photoIcon
-                + ", date: " + date);
-        }
-
-        // title resource id
-        int titleResId;
-        // the text in the notification's line 1 and 2.
-        String expandedText, callName;
-
-        // increment number of missed calls.
-        mNumberMissedCalls++;
-
-        // get the name for the ticker text
-        // i.e. "Missed call from <caller name or number>"
-        if (name != null && TextUtils.isGraphic(name)) {
-            callName = name;
-        } else if (!TextUtils.isEmpty(number)){
-            final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
-            // A number should always be displayed LTR using {@link BidiFormatter}
-            // regardless of the content of the rest of the notification.
-            callName = bidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR);
-        } else {
-            // use "unknown" if the caller is unidentifiable.
-            callName = mContext.getString(R.string.unknown);
-        }
-
-        // display the first line of the notification:
-        // 1 missed call: call name
-        // more than 1 missed call: <number of calls> + "missed calls"
-        if (mNumberMissedCalls == 1) {
-            titleResId = R.string.notification_missedCallTitle;
-            expandedText = callName;
-        } else {
-            titleResId = R.string.notification_missedCallsTitle;
-            expandedText = mContext.getString(R.string.notification_missedCallsMsg,
-                    mNumberMissedCalls);
-        }
-
-        Notification.Builder builder = new Notification.Builder(mContext);
-        builder.setSmallIcon(android.R.drawable.stat_notify_missed_call)
-                .setTicker(mContext.getString(R.string.notification_missedCallTicker, callName))
-                .setWhen(date)
-                .setContentTitle(mContext.getText(titleResId))
-                .setContentText(expandedText)
-                .setContentIntent(pendingCallLogIntent)
-                .setAutoCancel(true)
-                .setDeleteIntent(createClearMissedCallsIntent());
-
-        // Simple workaround for issue 6476275; refrain having actions when the given number seems
-        // not a real one but a non-number which was embedded by methods outside (like
-        // PhoneUtils#modifyForSpecialCnapCases()).
-        // TODO: consider removing equals() checks here, and modify callers of this method instead.
-        if (mNumberMissedCalls == 1
-                && !TextUtils.isEmpty(number)
-                && (presentation == PhoneConstants.PRESENTATION_ALLOWED ||
-                        presentation == PhoneConstants.PRESENTATION_PAYPHONE)) {
-            if (DBG) log("Add actions with the number " + number);
-
-            builder.addAction(R.drawable.stat_sys_phone_call,
-                    mContext.getString(R.string.notification_missedCall_call_back),
-                    PhoneGlobals.getCallBackPendingIntent(mContext, number));
-
-            builder.addAction(R.drawable.ic_text_holo_dark,
-                    mContext.getString(R.string.notification_missedCall_message),
-                    PhoneGlobals.getSendSmsFromNotificationPendingIntent(mContext, number));
-
-            if (photoIcon != null) {
-                builder.setLargeIcon(photoIcon);
-            } else if (photo instanceof BitmapDrawable) {
-                builder.setLargeIcon(((BitmapDrawable) photo).getBitmap());
-            }
-        } else {
-            if (DBG) {
-                log("Suppress actions. number: " + number + ", missedCalls: " + mNumberMissedCalls);
-            }
-        }
-
-        Notification notification = builder.getNotification();
-        configureLedNotification(notification);
-        mNotificationManager.notify(MISSED_CALL_NOTIFICATION, notification);
-    }
-
-    /** Returns an intent to be invoked when the missed call notification is cleared. */
-    private PendingIntent createClearMissedCallsIntent() {
-        Intent intent = new Intent(mContext, ClearMissedCallsService.class);
-        intent.setAction(ClearMissedCallsService.ACTION_CLEAR_MISSED_CALLS);
-        return PendingIntent.getService(mContext, 0, intent, 0);
-    }
-
-    /**
-     * Cancels the "missed call" notification.
-     *
-     * @see ITelephony.cancelMissedCallsNotification()
-     */
-    void cancelMissedCallNotification() {
-        // reset the number of missed calls to 0.
-        mNumberMissedCalls = 0;
-        mNotificationManager.cancel(MISSED_CALL_NOTIFICATION);
-    }
-
-    /**
      * Updates the message waiting indicator (voicemail) notification.
      *
      * @param visible true if there are messages waiting
@@ -699,7 +351,6 @@
                 notification.defaults |= Notification.DEFAULT_VIBRATE;
             }
             notification.flags |= Notification.FLAG_NO_CLEAR;
-            configureLedNotification(notification);
             mNotificationManager.notify(VOICEMAIL_NOTIFICATION, notification);
         } else {
             mNotificationManager.cancel(VOICEMAIL_NOTIFICATION);
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 4d858ec..6b48233 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -133,20 +133,6 @@
     public static final String ACTION_HANG_UP_ONGOING_CALL =
             "com.android.phone.ACTION_HANG_UP_ONGOING_CALL";
 
-    /**
-     * Intent Action used for making a phone call from Notification bar.
-     * This is for missed call notifications.
-     */
-    public static final String ACTION_CALL_BACK_FROM_NOTIFICATION =
-            "com.android.phone.ACTION_CALL_BACK_FROM_NOTIFICATION";
-
-    /**
-     * Intent Action used for sending a SMS from notification bar.
-     * This is for missed call notifications.
-     */
-    public static final String ACTION_SEND_SMS_FROM_NOTIFICATION =
-            "com.android.phone.ACTION_SEND_SMS_FROM_NOTIFICATION";
-
     private static PhoneGlobals sMe;
 
     // A few important fields we expose to the rest of the package
@@ -622,27 +608,6 @@
     }
 
     /**
-     * Returns an Intent that can be used to go to the "Call log"
-     * UI (aka CallLogActivity) in the Contacts app.
-     *
-     * Watch out: there's no guarantee that the system has any activity to
-     * handle this intent.  (In particular there may be no "Call log" at
-     * all on on non-voice-capable devices.)
-     */
-    /* package */ static Intent createCallLogIntent() {
-        Intent intent = new Intent(Intent.ACTION_VIEW, null);
-        intent.setType("vnd.android.cursor.dir/calls");
-        return intent;
-    }
-
-    /* package */static PendingIntent createPendingCallLogIntent(Context context) {
-        final Intent callLogIntent = PhoneGlobals.createCallLogIntent();
-        final TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
-        taskStackBuilder.addNextIntent(callLogIntent);
-        return taskStackBuilder.getPendingIntent(0, 0);
-    }
-
-    /**
      * Returns PendingIntent for hanging up ongoing phone call. This will typically be used from
      * Notification context.
      */
@@ -652,21 +617,6 @@
         return PendingIntent.getBroadcast(context, 0, intent, 0);
     }
 
-    /* package */ static PendingIntent getCallBackPendingIntent(Context context, String number) {
-        Intent intent = new Intent(ACTION_CALL_BACK_FROM_NOTIFICATION,
-                Uri.fromParts(Constants.SCHEME_TEL, number, null),
-                context, NotificationBroadcastReceiver.class);
-        return PendingIntent.getBroadcast(context, 0, intent, 0);
-    }
-
-    /* package */ static PendingIntent getSendSmsFromNotificationPendingIntent(
-            Context context, String number) {
-        Intent intent = new Intent(ACTION_SEND_SMS_FROM_NOTIFICATION,
-                Uri.fromParts(Constants.SCHEME_SMSTO, number, null),
-                context, NotificationBroadcastReceiver.class);
-        return PendingIntent.getBroadcast(context, 0, intent, 0);
-    }
-
     boolean isSimPinEnabled() {
         return mIsSimPinEnabled;
     }
@@ -1069,39 +1019,11 @@
 
             if (action.equals(ACTION_HANG_UP_ONGOING_CALL)) {
                 PhoneUtils.hangup(PhoneGlobals.getInstance().mCM);
-            } else if (action.equals(ACTION_CALL_BACK_FROM_NOTIFICATION)) {
-                // Collapse the expanded notification and the notification item itself.
-                closeSystemDialogs(context);
-                clearMissedCallNotification(context);
-
-                Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
-                callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-                context.startActivity(callIntent);
-            } else if (action.equals(ACTION_SEND_SMS_FROM_NOTIFICATION)) {
-                // Collapse the expanded notification and the notification item itself.
-                closeSystemDialogs(context);
-                clearMissedCallNotification(context);
-
-                Intent smsIntent = new Intent(Intent.ACTION_SENDTO, intent.getData());
-                smsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                context.startActivity(smsIntent);
             } else {
                 Log.w(LOG_TAG, "Received hang-up request from notification,"
                         + " but there's no call the system can hang up.");
             }
         }
-
-        private void closeSystemDialogs(Context context) {
-            Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-            context.sendBroadcastAsUser(intent, UserHandle.ALL);
-        }
-
-        private void clearMissedCallNotification(Context context) {
-            Intent clearIntent = new Intent(context, ClearMissedCallsService.class);
-            clearIntent.setAction(ClearMissedCallsService.ACTION_CLEAR_MISSED_CALLS);
-            context.startService(clearIntent);
-        }
     }
 
     private void handleServiceStateChanged(Intent intent) {
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 7f75ab2..335ec95 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -977,15 +977,6 @@
         return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
     }
 
-    public void cancelMissedCallsNotification() {
-        cancelMissedCallsNotificationUsingSubId(getDefaultSubscription());
-    }
-
-    public void cancelMissedCallsNotificationUsingSubId(long subId) {
-        enforceModifyPermission();
-        mApp.notificationMgr.cancelMissedCallNotification();
-    }
-
     public int getCallState() {
         return getCallStateUsingSubId(getDefaultSubscription());
     }
