Merge "Add a notification icon when connected to wireless display." into jb-mr1-dev

This commit is contained in:
Jeff Brown
2012-10-17 18:42:25 -07:00
committed by Android (Google) Code Review
6 changed files with 143 additions and 16 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -3821,6 +3821,13 @@
<!-- Title text to show within the overlay. [CHAR LIMIT=50] -->
<string name="display_manager_overlay_display_title"><xliff:g id="name">%1$s</xliff:g>: <xliff:g id="width">%2$d</xliff:g>x<xliff:g id="height">%3$d</xliff:g>, <xliff:g id="dpi">%4$d</xliff:g> dpi</string>
<!-- Title of the notification to indicate an active wifi display connection. [CHAR LIMIT=50] -->
<string name="wifi_display_notification_title">Wireless display is connected</string>
<!-- Message of the notification to indicate an active wifi display connection. [CHAR LIMIT=80] -->
<string name="wifi_display_notification_message">This screen is showing on another device</string>
<!-- Label of a button to disconnect an active wifi display connection. [CHAR LIMIT=25] -->
<string name="wifi_display_notification_disconnect">Disconnect</string>
<!-- Keyguard strings -->
<!-- Label shown on emergency call button in keyguard -->
<string name="kg_emergency_call_label">Emergency call</string>

View File

@@ -1486,6 +1486,7 @@
<java-symbol type="bool" name="show_ongoing_ime_switcher" />
<java-symbol type="color" name="config_defaultNotificationColor" />
<java-symbol type="drawable" name="ic_notification_ime_default" />
<java-symbol type="drawable" name="ic_notify_wifidisplay" />
<java-symbol type="drawable" name="stat_notify_car_mode" />
<java-symbol type="drawable" name="stat_notify_disabled" />
<java-symbol type="drawable" name="stat_notify_disk_full" />
@@ -1621,6 +1622,9 @@
<java-symbol type="string" name="vpn_lockdown_error" />
<java-symbol type="string" name="vpn_lockdown_reset" />
<java-symbol type="string" name="wallpaper_binding_label" />
<java-symbol type="string" name="wifi_display_notification_title" />
<java-symbol type="string" name="wifi_display_notification_message" />
<java-symbol type="string" name="wifi_display_notification_disconnect" />
<java-symbol type="style" name="Theme.Dialog.AppError" />
<java-symbol type="style" name="Theme.Toast" />
<java-symbol type="xml" name="storage_list" />

View File

@@ -16,17 +16,28 @@
package com.android.server.display;
import com.android.internal.R;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.hardware.display.DisplayManager;
import android.hardware.display.WifiDisplay;
import android.hardware.display.WifiDisplayStatus;
import android.media.RemoteDisplay;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
import android.view.Surface;
@@ -52,8 +63,18 @@ final class WifiDisplayAdapter extends DisplayAdapter {
private static final boolean DEBUG = false;
private static final int MSG_SEND_STATUS_CHANGE_BROADCAST = 1;
private static final int MSG_UPDATE_NOTIFICATION = 2;
private static final String ACTION_DISCONNECT = "android.server.display.wfd.DISCONNECT";
private final WifiDisplayHandler mHandler;
private final PersistentDataStore mPersistentDataStore;
private final boolean mSupportsProtectedBuffers;
private final NotificationManager mNotificationManager;
private final PendingIntent mSettingsPendingIntent;
private final PendingIntent mDisconnectPendingIntent;
private WifiDisplayController mDisplayController;
private WifiDisplayDevice mDisplayDevice;
@@ -67,14 +88,32 @@ final class WifiDisplayAdapter extends DisplayAdapter {
private WifiDisplay[] mRememberedDisplays = WifiDisplay.EMPTY_ARRAY;
private boolean mPendingStatusChangeBroadcast;
private boolean mPendingNotificationUpdate;
public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener,
PersistentDataStore persistentDataStore) {
super(syncRoot, context, handler, listener, TAG);
mHandler = new WifiDisplayHandler(handler.getLooper());
mPersistentDataStore = persistentDataStore;
mSupportsProtectedBuffers = context.getResources().getBoolean(
com.android.internal.R.bool.config_wifiDisplaySupportsProtectedBuffers);
mNotificationManager = (NotificationManager)context.getSystemService(
Context.NOTIFICATION_SERVICE);
Intent settingsIntent = new Intent(Settings.ACTION_WIFI_DISPLAY_SETTINGS);
settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
mSettingsPendingIntent = PendingIntent.getActivityAsUser(
context, 0, settingsIntent, 0, null, UserHandle.CURRENT);
Intent disconnectIntent = new Intent(ACTION_DISCONNECT);
mDisconnectPendingIntent = PendingIntent.getBroadcastAsUser(
context, 0, disconnectIntent, 0, UserHandle.CURRENT);
context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
new IntentFilter(ACTION_DISCONNECT), null, mHandler);
}
@Override
@@ -89,6 +128,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
pw.println("mAvailableDisplays=" + Arrays.toString(mAvailableDisplays));
pw.println("mRememberedDisplays=" + Arrays.toString(mRememberedDisplays));
pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast);
pw.println("mPendingNotificationUpdate=" + mPendingNotificationUpdate);
pw.println("mSupportsProtectedBuffers=" + mSupportsProtectedBuffers);
// Try to dump the controller state.
@@ -266,6 +306,8 @@ final class WifiDisplayAdapter extends DisplayAdapter {
mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height,
refreshRate, deviceFlags, surface);
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED);
scheduleUpdateNotificationLocked();
}
private void handleDisconnectLocked() {
@@ -273,6 +315,8 @@ final class WifiDisplayAdapter extends DisplayAdapter {
mDisplayDevice.clearSurfaceLocked();
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
mDisplayDevice = null;
scheduleUpdateNotificationLocked();
}
}
@@ -280,28 +324,81 @@ final class WifiDisplayAdapter extends DisplayAdapter {
mCurrentStatus = null;
if (!mPendingStatusChangeBroadcast) {
mPendingStatusChangeBroadcast = true;
getHandler().post(mStatusChangeBroadcast);
mHandler.sendEmptyMessage(MSG_SEND_STATUS_CHANGE_BROADCAST);
}
}
private final Runnable mStatusChangeBroadcast = new Runnable() {
@Override
public void run() {
final Intent intent;
synchronized (getSyncRoot()) {
if (!mPendingStatusChangeBroadcast) {
return;
}
private void scheduleUpdateNotificationLocked() {
if (!mPendingNotificationUpdate) {
mPendingNotificationUpdate = true;
mHandler.sendEmptyMessage(MSG_UPDATE_NOTIFICATION);
}
}
mPendingStatusChangeBroadcast = false;
intent = new Intent(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(DisplayManager.EXTRA_WIFI_DISPLAY_STATUS,
getWifiDisplayStatusLocked());
// Runs on the handler.
private void handleSendStatusChangeBroadcast() {
final Intent intent;
synchronized (getSyncRoot()) {
if (!mPendingStatusChangeBroadcast) {
return;
}
// Send protected broadcast about wifi display status to registered receivers.
getContext().sendBroadcast(intent);
mPendingStatusChangeBroadcast = false;
intent = new Intent(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(DisplayManager.EXTRA_WIFI_DISPLAY_STATUS,
getWifiDisplayStatusLocked());
}
// Send protected broadcast about wifi display status to registered receivers.
getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
}
// Runs on the handler.
private void handleUpdateNotification() {
final boolean isConnected;
synchronized (getSyncRoot()) {
if (!mPendingNotificationUpdate) {
return;
}
mPendingNotificationUpdate = false;
isConnected = (mDisplayDevice != null);
}
mNotificationManager.cancelAsUser(null,
R.string.wifi_display_notification_title, UserHandle.ALL);
if (isConnected) {
Context context = getContext();
Resources r = context.getResources();
Notification notification = new Notification.Builder(context)
.setContentTitle(r.getString(
R.string.wifi_display_notification_title))
.setContentText(r.getString(
R.string.wifi_display_notification_message))
.setContentIntent(mSettingsPendingIntent)
.setSmallIcon(R.drawable.ic_notify_wifidisplay)
.setOngoing(true)
.addAction(android.R.drawable.ic_menu_close_clear_cancel,
r.getString(R.string.wifi_display_notification_disconnect),
mDisconnectPendingIntent)
.build();
mNotificationManager.notifyAsUser(null,
R.string.wifi_display_notification_title,
notification, UserHandle.ALL);
}
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_DISCONNECT)) {
synchronized (getSyncRoot()) {
requestDisconnectLocked();
}
}
}
};
@@ -454,4 +551,23 @@ final class WifiDisplayAdapter extends DisplayAdapter {
return mInfo;
}
}
private final class WifiDisplayHandler extends Handler {
public WifiDisplayHandler(Looper looper) {
super(looper, null, true /*async*/);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SEND_STATUS_CHANGE_BROADCAST:
handleSendStatusChangeBroadcast();
break;
case MSG_UPDATE_NOTIFICATION:
handleUpdateNotification();
break;
}
}
}
}