Teleca 2b changes.
[android/platform/packages/apps/Phone.git] / src / com / android / phone / NotificationMgr.java
index e68ab8c..9c7237f 100644 (file)
@@ -39,6 +39,7 @@ import android.util.Log;
 import android.widget.RemoteViews;
 import android.widget.Toast;
 
+import com.android.internal.R.drawable;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallerInfo;
 import com.android.internal.telephony.CallerInfoAsyncQuery;
@@ -90,6 +91,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
     static final int VOICEMAIL_NOTIFICATION = 5;
     static final int CALL_FORWARD_NOTIFICATION = 6;
     static final int DATA_DISCONNECTED_ROAMING_NOTIFICATION = 7;
+    static final int ECBM_NOTIFICATION = 8;
 
     private static NotificationMgr sMe = null;
     private Phone mPhone;
@@ -134,7 +136,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
 
     static void init(Context context) {
         sMe = new NotificationMgr(context);
-        
+
         // update the notifications that need to be touched at startup.
         sMe.updateNotifications();
     }
@@ -149,9 +151,9 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
      * the Status bar.  All interaction with the status bar should be
      * though the methods contained herein.
      */
-    
-    /** 
-     * Factory method 
+
+    /**
+     * Factory method
      */
     StatusBarMgr getStatusBarMgr() {
         if (mStatusBarMgr == null) {
@@ -159,23 +161,23 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
         }
         return mStatusBarMgr;
     }
-    
+
     /**
      * StatusBarMgr implementation
-     */ 
+     */
     class StatusBarMgr {
         // current settings
         private boolean mIsNotificationEnabled = true;
         private boolean mIsExpandedViewEnabled = true;
-        
+
         private StatusBarMgr () {
         }
-        
+
         /**
-         * Sets the notification state (enable / disable 
+         * Sets the notification state (enable / disable
          * vibrating notifications) for the status bar,
          * updates the status bar service if there is a change.
-         * Independent of the remaining Status Bar 
+         * Independent of the remaining Status Bar
          * functionality, including icons and expanded view.
          */
         void enableNotificationAlerts(boolean enable) {
@@ -184,12 +186,12 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
                 updateStatusBar();
             }
         }
-        
+
         /**
-         * Sets the ability to expand the notifications for the 
-         * status bar, updates the status bar service if there 
-         * is a change. Independent of the remaining Status Bar 
-         * functionality, including icons and notification 
+         * Sets the ability to expand the notifications for the
+         * status bar, updates the status bar service if there
+         * is a change. Independent of the remaining Status Bar
+         * functionality, including icons and notification
          * alerts.
          */
         void enableExpandedView(boolean enable) {
@@ -198,28 +200,28 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
                 updateStatusBar();
             }
         }
-        
+
         /**
-         * Method to synchronize status bar state with our current 
+         * Method to synchronize status bar state with our current
          * state.
          */
         void updateStatusBar() {
             int state = StatusBarManager.DISABLE_NONE;
-            
+
             if (!mIsExpandedViewEnabled) {
                 state |= StatusBarManager.DISABLE_EXPAND;
             }
-            
+
             if (!mIsNotificationEnabled) {
                 state |= StatusBarManager.DISABLE_NOTIFICATION_ALERTS;
             }
-            
+
             // send the message to the status bar manager.
             if (DBG) log("updating status bar state: " + state);
             mStatusBar.disable(state);
         }
     }
-    
+
     /**
      * Makes sure notifications are up to date.
      */
@@ -233,11 +235,11 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
         StringBuilder where = new StringBuilder("type=");
         where.append(Calls.MISSED_TYPE);
         where.append(" AND new=1");
-        
+
         // start the query
         mQueryHandler.startQuery(CALL_LOG_TOKEN, null, Calls.CONTENT_URI,  CALL_LOG_PROJECTION,
                 where.toString(), null, Calls.DEFAULT_SORT_ORDER);
-        
+
         // synchronize the in call notification
         if (mPhone.getState() != Phone.State.OFFHOOK) {
             if (DBG) log("Phone is idle, canceling notification.");
@@ -246,27 +248,27 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             if (DBG) log("Phone is offhook, updating notification.");
             updateInCallNotification();
         }
-        
+
         // 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[] {
             Phones.NUMBER,
             Phones.NAME
     };
-    
+
     /**
      * Class used to run asynchronous queries to re-populate
      * the notifications we care about.
      */
     private class QueryHandler extends AsyncQueryHandler {
-        
+
         /**
-         * Used to store relevant fields for the Missed Call 
-         * notifications. 
+         * Used to store relevant fields for the Missed Call
+         * notifications.
          */
         private class NotificationInfo {
             public String name;
@@ -274,7 +276,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             public String label;
             public long date;
         }
-        
+
         public QueryHandler(ContentResolver cr) {
             super(cr);
         }
@@ -283,63 +285,63 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
          * Handles the query results.  There are really 2 steps to this,
          * similar to what happens in RecentCallsListActivity.
          *  1. Find the list of missed calls
-         *  2. For each call, run a query to retrieve the caller's name. 
+         *  2. For each call, run a query to retrieve the caller's name.
          */
         @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 
+
+            // 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
             // RecentCallsListActivity.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 
+                            // 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(Phones.CONTENT_FILTER_URL, n.number), 
+
+                            mQueryHandler.startQuery(CONTACT_TOKEN, n,
+                                    Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, n.number),
                                     PHONES_PROJECTION, null, null, Phones.DEFAULT_SORT_ORDER);
                         }
-                        
+
                         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;
-                        
+
                         if (cursor.moveToFirst()) {
                             // we have contacts data, get the name.
                             if (DBG) log("contact :" + n.name + " found for phone: " + n.number);
                             n.name = cursor.getString(cursor.getColumnIndexOrThrow(Phones.NAME));
                         }
-                        
+
                         // send the notification
                         if (DBG) log("sending notification.");
                         notifyMissedCall(n.name, n.number, n.label, n.date);
-                        
+
                         if (DBG) log("closing contact cursor.");
                         cursor.close();
                     }
@@ -347,10 +349,10 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
                 default:
             }
         }
-        
+
         /**
          * Factory method to generate a NotificationInfo object given a
-         * cursor from the call log table. 
+         * cursor from the call log table.
          */
         private final NotificationInfo getNotificationInfo(Cursor cursor) {
             NotificationInfo n = new NotificationInfo();
@@ -358,23 +360,23 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             n.number = cursor.getString(cursor.getColumnIndexOrThrow(Calls.NUMBER));
             n.label = 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.number.equals(CallerInfo.UNKNOWN_NUMBER)) || 
+            if ( (n.number.equals(CallerInfo.UNKNOWN_NUMBER)) ||
                  (n.number.equals(CallerInfo.PRIVATE_NUMBER)) ||
                  (n.number.equals(CallerInfo.PAYPHONE_NUMBER)) ) {
                 n.number = null;
             }
-            
+
             if (DBG) log("NotificationInfo constructed for number: " + n.number);
 
             return n;
         }
     }
-    
+
     /**
      * Displays a notification about a missed call.
      *
@@ -386,7 +388,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
         int titleResId;
         // the text in the notification's line 1 and 2.
         String expandedText, callName;
-        
+
         // increment number of missed calls.
         mNumberMissedCalls++;
 
@@ -400,7 +402,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             // 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"
@@ -409,13 +411,13 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             expandedText = callName;
         } else {
             titleResId = R.string.notification_missedCallsTitle;
-            expandedText = mContext.getString(R.string.notification_missedCallsMsg, 
+            expandedText = mContext.getString(R.string.notification_missedCallsMsg,
                     mNumberMissedCalls);
         }
-        
+
         // create the target call log intent
         final Intent intent = PhoneApp.createCallLogIntent();
-        
+
         // make the notification
         mNotificationMgr.notify(
                 MISSED_CALL_NOTIFICATION,
@@ -437,6 +439,49 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
         mNotificationMgr.cancel(MISSED_CALL_NOTIFICATION);
     }
 
+    /**
+     * Displays a notification for Emergency Callback Mode.
+     *
+     * @param nameOrNumber either the contact name, or the phone number if no contact
+     * @param label the label of the number if nameOrNumber is a name, null if it is a number
+     */
+    void notifyECBM() {
+        // The details of our message
+        CharSequence message = "Emergency Callback Mode is active";
+
+        // look up the notification manager service
+        mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+
+        // The PendingIntent to launch our activity if the user selects this notification
+        Intent EmcbAlarm = new Intent(Intent.ACTION_MAIN, null);
+        EmcbAlarm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        EmcbAlarm.setClassName("com.android.phone", EmergencyCallbackMode.class.getName());
+
+        PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0,
+                EmcbAlarm, 0);
+
+        // The ticker text, this uses a formatted string so our message could be localized
+        String tickerText = mContext.getString(R.string.ecbm_mode_text, message);
+
+        // construct the Notification object.
+         Notification ecbmNotif = new Notification(com.android.internal.R.drawable.stat_ecb_mode,
+                 tickerText, System.currentTimeMillis());
+
+        // Set the info for the views that show in the notification panel.
+        ecbmNotif.setLatestEventInfo(mContext, null, message, contentIntent);
+
+        // Note that we use R.layout.incoming_message_panel as the ID for
+        // the notification.  It could be any integer you want, but we use
+        // the convention of using a resource id for a string related to
+        // the notification.  It will always be a unique number within your
+        // application.
+        mNotificationMgr.notify(ECBM_NOTIFICATION, ecbmNotif);
+    }
+
+    void cancelEcbmNotification() {
+        mNotificationMgr.cancel(ECBM_NOTIFICATION);
+    }
+
     void notifySpeakerphone() {
         if (mSpeakerphoneIcon == null) {
             mSpeakerphoneIcon = mStatusBar.addIcon("speakerphone",
@@ -567,7 +612,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
         RemoteViews contentView = new RemoteViews(mContext.getPackageName(),
                                                    R.layout.ongoing_call_notification);
         contentView.setImageViewResource(R.id.icon, expandedViewIcon);
-        
+
         // if the connection is valid, then build what we need for the
         // first line of notification information, and start the chronometer.
         // Otherwise, don't bother and just stick with line 2.
@@ -599,7 +644,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             }
 
             if (DBG) log("- Updating expanded view: line 1 '" + expandedViewLine1 + "'");
-    
+
             // Text line #1 is actually a Chronometer, not a plain TextView.
             // We format the elapsed time of the current call into a line like
             // "Ongoing call (01:23)".
@@ -610,26 +655,26 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
         } else if (DBG) {
             log("updateInCallNotification: connection is null, call status not updated.");
         }
-        
-        // display conference call string if this call is a conference 
+
+        // display conference call string if this call is a conference
         // call, otherwise display the connection information.
-        
-        // TODO: it may not make sense for every point to make separate 
+
+        // TODO: it may not make sense for every point to make separate
         // checks for isConferenceCall, so we need to think about
         // possibly including this in startGetCallerInfo or some other
         // common point.
-        String expandedViewLine2 = ""; 
+        String expandedViewLine2 = "";
         if (PhoneUtils.isConferenceCall(currentCall)) {
             // if this is a conference call, just use that as the caller name.
             expandedViewLine2 = mContext.getString(R.string.card_title_conf_call);
         } else {
             // Start asynchronous call to get the compact name.
-            PhoneUtils.CallerInfoToken cit = 
+            PhoneUtils.CallerInfoToken cit =
                 PhoneUtils.startGetCallerInfo (mContext, currentCall, this, contentView);
             // Line 2 of the expanded view (smaller text):
             expandedViewLine2 = PhoneUtils.getCompactNameFromCallerInfo(cit.currentInfo, mContext);
         }
-        
+
         if (DBG) log("- Updating expanded view: line 2 '" + expandedViewLine2 + "'");
         contentView.setTextViewText(R.id.text2, expandedViewLine2);
         notification.contentView = contentView;
@@ -657,12 +702,12 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
 
     /**
      * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface.
-     * refreshes the contentView when called. 
+     * refreshes the contentView when called.
      */
     public void onQueryComplete(int token, Object cookie, CallerInfo ci){
         if (DBG) log("callerinfo query complete, updating ui.");
 
-        ((RemoteViews) cookie).setTextViewText(R.id.text2, 
+        ((RemoteViews) cookie).setTextViewText(R.id.text2,
                 PhoneUtils.getCompactNameFromCallerInfo(ci, mContext));
     }
 
@@ -695,7 +740,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             int resId = android.R.drawable.stat_notify_voicemail;
 
             // This Notification can get a lot fancier once we have more
-            // information about the current voicemail messages. 
+            // information about the current voicemail messages.
             // (For example, the current voicemail system can't tell
             // us the caller-id or timestamp of a message, or tell us the
             // message count.)
@@ -763,7 +808,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             Intent intent = new Intent(Intent.ACTION_CALL,
                     Uri.fromParts("voicemail", "", null));
             PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
-            
+
             Notification notification = new Notification(
                     resId,  // icon
                     null, // tickerText
@@ -783,7 +828,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             notification.ledARGB = 0xff00ff00;
             notification.ledOnMS = 500;
             notification.ledOffMS = 2000;
-            
+
             mNotificationMgr.notify(
                     VOICEMAIL_NOTIFICATION,
                     notification);
@@ -803,12 +848,12 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList
             // If Unconditional Call Forwarding (forward all calls) for VOICE
             // is enabled, just show a notification.  We'll default to expanded
             // view for now, so the there is less confusion about the icon.  If
-            // it is deemed too weird to have CF indications as expanded views, 
+            // it is deemed too weird to have CF indications as expanded views,
             // then we'll flip the flag back.
 
-            // TODO: We may want to take a look to see if the notification can 
-            // display the target to forward calls to.  This will require some 
-            // effort though, since there are multiple layers of messages that 
+            // TODO: We may want to take a look to see if the notification can
+            // display the target to forward calls to.  This will require some
+            // effort though, since there are multiple layers of messages that
             // will need to propagate that information.
 
             Notification notification;