summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Sandler <dsandler@google.com>2011-02-03 14:51:35 -0500
committerDaniel Sandler <dsandler@google.com>2011-02-03 21:11:46 -0500
commite40451a89dc91dfd636af7cb32a23b4a4cc93fdc (patch)
tree875a847a9a638ce36310887dc7818e02e8cb96dc
parent8275c6087897e8fd614681d1cd12db62e6b9fcd5 (diff)
downloadframeworks_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
-rw-r--r--core/java/android/app/INotificationManager.aidl1
-rw-r--r--core/java/com/android/internal/statusbar/StatusBarNotification.java3
-rw-r--r--packages/SystemUI/res/values-es-rUS-xlarge/strings.xml6
-rw-r--r--packages/SystemUI/res/values-xlarge/strings.xml5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java114
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java4
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java33
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java37
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()
{