diff options
author | Daniel Sandler <dsandler@google.com> | 2011-02-03 14:51:35 -0500 |
---|---|---|
committer | Daniel Sandler <dsandler@google.com> | 2011-02-03 21:11:46 -0500 |
commit | e40451a89dc91dfd636af7cb32a23b4a4cc93fdc (patch) | |
tree | 875a847a9a638ce36310887dc7818e02e8cb96dc | |
parent | 8275c6087897e8fd614681d1cd12db62e6b9fcd5 (diff) | |
download | frameworks_base-e40451a89dc91dfd636af7cb32a23b4a4cc93fdc.zip frameworks_base-e40451a89dc91dfd636af7cb32a23b4a4cc93fdc.tar.gz frameworks_base-e40451a89dc91dfd636af7cb32a23b4a4cc93fdc.tar.bz2 |
Ongoing notification for GPS use.
This change improves upon the notification priority API
introduced in change I9e738cc4, allowing privileged clients
to set the priority of a notification when posting it
directly to INotificationManager. StatusBarTest is updated
to test this new feature.
The new LocationController in SystemUI uses this facility to
post a high-priority ongoing notification whenever GPS is in
use (replacing the functionality of the legacy GPS status
bar icon).
Also happens to fix http://b/3325472 (adding a log message
when notifications are dropped because of a missing icon).
Bug: 3412807
Change-Id: I523016ffa53bf979be98ddc4a2deb55a6270c68a
8 files changed, 197 insertions, 6 deletions
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 4d5238c..2420b84 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -33,6 +33,7 @@ interface INotificationManager void enqueueToast(String pkg, ITransientNotification callback, int duration); void cancelToast(String pkg, ITransientNotification callback); void enqueueNotificationWithTag(String pkg, String tag, int id, in Notification notification, inout int[] idReceived); + void enqueueNotificationWithTagPriority(String pkg, String tag, int id, int priority, in Notification notification, inout int[] idReceived); void cancelNotificationWithTag(String pkg, String tag, int id); } diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.java b/core/java/com/android/internal/statusbar/StatusBarNotification.java index cb791be..c03ff1a 100644 --- a/core/java/com/android/internal/statusbar/StatusBarNotification.java +++ b/core/java/com/android/internal/statusbar/StatusBarNotification.java @@ -63,8 +63,7 @@ public class StatusBarNotification implements Parcelable { this.initialPid = initialPid; this.notification = notification; - this.priority = ((notification.flags & Notification.FLAG_ONGOING_EVENT) != 0) - ? PRIORITY_ONGOING : PRIORITY_NORMAL; + this.priority = PRIORITY_NORMAL; } public StatusBarNotification(Parcel in) { diff --git a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml index 00b951e..7ba493d 100644 --- a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml +++ b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml @@ -22,4 +22,10 @@ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Eliminar todos"</string> <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sin conexión a Int."</string> <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"WiFi conectado"</string> + + <!-- manually translated --> + <string name="gps_notification_searching_text">Buscando señal de GPS</string> + + <!-- manually translated --> + <string name="gps_notification_found_text">Ubicación establecida por el GPS</string> </resources> diff --git a/packages/SystemUI/res/values-xlarge/strings.xml b/packages/SystemUI/res/values-xlarge/strings.xml index f7b642d..dfd5851 100644 --- a/packages/SystemUI/res/values-xlarge/strings.xml +++ b/packages/SystemUI/res/values-xlarge/strings.xml @@ -38,4 +38,9 @@ <!-- Separator for PLMN and SPN in network name. --> <string name="status_bar_network_name_separator" translatable="false">" – "</string> + <!-- Notification text: when GPS is getting a fix [CHAR LIMIT=50] --> + <string name="gps_notification_searching_text">Searching for GPS</string> + + <!-- Notification text: when GPS has found a fix [CHAR LIMIT=50] --> + <string name="gps_notification_found_text">Location set by GPS</string> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java new file mode 100644 index 0000000..76c05d2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 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.systemui.statusbar.policy; + +import java.util.ArrayList; + +import android.app.Notification; +import android.app.NotificationManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.location.LocationManager; +import android.util.Slog; +import android.view.View; +import android.widget.ImageView; + +// private NM API +import android.app.INotificationManager; +import com.android.internal.statusbar.StatusBarNotification; + +import com.android.systemui.R; + +public class LocationController extends BroadcastReceiver { + private static final String TAG = "StatusBar.LocationController"; + + private static final int GPS_NOTIFICATION_ID = 374203-122084; + + private Context mContext; + + private INotificationManager mNotificationService; + + public LocationController(Context context) { + mContext = context; + + IntentFilter filter = new IntentFilter(); + filter.addAction(LocationManager.GPS_ENABLED_CHANGE_ACTION); + filter.addAction(LocationManager.GPS_FIX_CHANGE_ACTION); + context.registerReceiver(this, filter); + + NotificationManager nm = (NotificationManager)context.getSystemService( + Context.NOTIFICATION_SERVICE); + mNotificationService = nm.getService(); + } + + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + final boolean enabled = intent.getBooleanExtra(LocationManager.EXTRA_GPS_ENABLED, false); + + boolean visible; + int iconId, textResId; + + if (action.equals(LocationManager.GPS_FIX_CHANGE_ACTION) && enabled) { + // GPS is getting fixes + iconId = com.android.internal.R.drawable.stat_sys_gps_on; + textResId = R.string.gps_notification_found_text; + visible = true; + } else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) && !enabled) { + // GPS is off + visible = false; + iconId = textResId = 0; + } else { + // GPS is on, but not receiving fixes + iconId = R.drawable.stat_sys_gps_acquiring_anim; + textResId = R.string.gps_notification_searching_text; + visible = true; + } + + try { + if (visible) { + Notification n = new Notification.Builder(mContext) + .setSmallIcon(iconId) + .setContentTitle(mContext.getText(textResId)) + .setOngoing(true) + .getNotification(); + + // Notification.Builder will helpfully fill these out for you no matter what you do + n.tickerView = null; + n.tickerText = null; + + int[] idOut = new int[1]; + mNotificationService.enqueueNotificationWithTagPriority( + mContext.getPackageName(), + null, + GPS_NOTIFICATION_ID, + StatusBarNotification.PRIORITY_SYSTEM, // !!!1!one!!! + n, + idOut); + } else { + mNotificationService.cancelNotification( + mContext.getPackageName(), + GPS_NOTIFICATION_ID); + } + } catch (android.os.RemoteException ex) { + // well, it was worth a shot + } + } +} + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index 4bac07f..7a13fde 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -65,6 +65,7 @@ import com.android.systemui.R; import com.android.systemui.statusbar.*; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BluetoothController; +import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.recent.RecentApplicationsActivity; @@ -135,6 +136,7 @@ public class TabletStatusBar extends StatusBar implements HeightReceiver mHeightReceiver; BatteryController mBatteryController; BluetoothController mBluetoothController; + LocationController mLocationController; NetworkController mNetworkController; View mBarContents; @@ -359,6 +361,8 @@ public class TabletStatusBar extends StatusBar implements mTicker = new TabletTicker(this); // The icons + mLocationController = new LocationController(mContext); // will post a notification + mBatteryController = new BatteryController(mContext); mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery)); mBluetoothController = new BluetoothController(mContext); diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index 0490190..47dce41 100755 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -156,10 +156,11 @@ public class NotificationManagerService extends INotificationManager.Stub final int id; final int uid; final int initialPid; + final int priority; final Notification notification; IBinder statusBarKey; - NotificationRecord(String pkg, String tag, int id, int uid, int initialPid, + NotificationRecord(String pkg, String tag, int id, int uid, int initialPid, int priority, Notification notification) { this.pkg = pkg; @@ -167,6 +168,7 @@ public class NotificationManagerService extends INotificationManager.Stub this.id = id; this.uid = uid; this.initialPid = initialPid; + this.priority = priority; this.notification = notification; } @@ -194,7 +196,9 @@ public class NotificationManagerService extends INotificationManager.Stub + Integer.toHexString(System.identityHashCode(this)) + " pkg=" + pkg + " id=" + Integer.toHexString(id) - + " tag=" + tag + "}"; + + " tag=" + tag + + " pri=" + priority + + "}"; } } @@ -649,11 +653,27 @@ public class NotificationManagerService extends INotificationManager.Stub tag, id, notification, idOut); } + public void enqueueNotificationWithTagPriority(String pkg, String tag, int id, int priority, + Notification notification, int[] idOut) + { + enqueueNotificationInternal(pkg, Binder.getCallingUid(), Binder.getCallingPid(), + tag, id, priority, notification, idOut); + } + // Not exposed via Binder; for system use only (otherwise malicious apps could spoof the // uid/pid of another application) public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid, String tag, int id, Notification notification, int[] idOut) { + enqueueNotificationInternal(pkg, callingUid, callingPid, tag, id, + ((notification.flags & Notification.FLAG_ONGOING_EVENT) != 0) + ? StatusBarNotification.PRIORITY_ONGOING + : StatusBarNotification.PRIORITY_NORMAL, + notification, idOut); + } + public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid, + String tag, int id, int priority, Notification notification, int[] idOut) + { checkIncomingCall(pkg); // Limit the number of notifications that any given package except the android @@ -695,8 +715,10 @@ public class NotificationManagerService extends INotificationManager.Stub } synchronized (mNotificationList) { - NotificationRecord r = new NotificationRecord(pkg, tag, id, - callingUid, callingPid, notification); + NotificationRecord r = new NotificationRecord(pkg, tag, id, + callingUid, callingPid, + priority, + notification); NotificationRecord old = null; int index = indexOfNotificationLocked(pkg, tag, id); @@ -722,6 +744,8 @@ public class NotificationManagerService extends INotificationManager.Stub if (notification.icon != 0) { StatusBarNotification n = new StatusBarNotification(pkg, id, tag, r.uid, r.initialPid, notification); + n.priority = r.priority; + if (old != null && old.statusBarKey != null) { r.statusBarKey = old.statusBarKey; long identity = Binder.clearCallingIdentity(); @@ -743,6 +767,7 @@ public class NotificationManagerService extends INotificationManager.Stub } sendAccessibilityEvent(notification, pkg); } else { + Slog.e(TAG, "Ignoring notification with icon==0: " + notification); if (old != null && old.statusBarKey != null) { long identity = Binder.clearCallingIdentity(); try { diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java index 90c2a1a..f463a19 100644 --- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java +++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java @@ -35,6 +35,10 @@ import android.widget.TextView; import android.widget.ProgressBar; import android.os.PowerManager; +// private NM API +import android.app.INotificationManager; +import com.android.internal.statusbar.StatusBarNotification; + public class NotificationTestList extends TestActivity { private final static String TAG = "NotificationTestList"; @@ -205,6 +209,15 @@ public class NotificationTestList extends TestActivity } }, + new Test("Null Icon #1 (when=now)") { + public void run() { + Notification n = new Notification(0, null, System.currentTimeMillis()); + n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", + "This is the same notification!!!", makeIntent()); + mNM.notify(1, n); + } + }, + new Test("Bad resource #1 (when=create)") { public void run() { Notification n = new Notification(R.drawable.icon2, @@ -752,6 +765,30 @@ public class NotificationTestList extends TestActivity } }, + new Test("System priority notification") { + public void run() { + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.notification1) + .setContentTitle("System priority") + .setContentText("This should appear before all others") + .getNotification(); + + int[] idOut = new int[1]; + try { + INotificationManager directLine = mNM.getService(); + directLine.enqueueNotificationWithTagPriority( + getPackageName(), + null, + 1, + StatusBarNotification.PRIORITY_SYSTEM, + n, + idOut); + } catch (android.os.RemoteException ex) { + // oh well + } + } + }, + new Test("Crash") { public void run() { |