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

* commit '23fa0320b88bd2141742d47eaf2626369cb03b22':
  Add a notification icon when connected to wireless display.
This commit is contained in:
Jeff Brown
2012-10-17 18:44:43 -07:00
committed by Android Git Automerger
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] --> <!-- 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> <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 --> <!-- Keyguard strings -->
<!-- Label shown on emergency call button in keyguard --> <!-- Label shown on emergency call button in keyguard -->
<string name="kg_emergency_call_label">Emergency call</string> <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="bool" name="show_ongoing_ime_switcher" />
<java-symbol type="color" name="config_defaultNotificationColor" /> <java-symbol type="color" name="config_defaultNotificationColor" />
<java-symbol type="drawable" name="ic_notification_ime_default" /> <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_car_mode" />
<java-symbol type="drawable" name="stat_notify_disabled" /> <java-symbol type="drawable" name="stat_notify_disabled" />
<java-symbol type="drawable" name="stat_notify_disk_full" /> <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_error" />
<java-symbol type="string" name="vpn_lockdown_reset" /> <java-symbol type="string" name="vpn_lockdown_reset" />
<java-symbol type="string" name="wallpaper_binding_label" /> <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.Dialog.AppError" />
<java-symbol type="style" name="Theme.Toast" /> <java-symbol type="style" name="Theme.Toast" />
<java-symbol type="xml" name="storage_list" /> <java-symbol type="xml" name="storage_list" />

View File

@@ -16,17 +16,28 @@
package com.android.server.display; package com.android.server.display;
import com.android.internal.R;
import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter; 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.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.hardware.display.WifiDisplay; import android.hardware.display.WifiDisplay;
import android.hardware.display.WifiDisplayStatus; import android.hardware.display.WifiDisplayStatus;
import android.media.RemoteDisplay; import android.media.RemoteDisplay;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; 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.util.Slog;
import android.view.Surface; import android.view.Surface;
@@ -52,8 +63,18 @@ final class WifiDisplayAdapter extends DisplayAdapter {
private static final boolean DEBUG = false; 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 PersistentDataStore mPersistentDataStore;
private final boolean mSupportsProtectedBuffers; private final boolean mSupportsProtectedBuffers;
private final NotificationManager mNotificationManager;
private final PendingIntent mSettingsPendingIntent;
private final PendingIntent mDisconnectPendingIntent;
private WifiDisplayController mDisplayController; private WifiDisplayController mDisplayController;
private WifiDisplayDevice mDisplayDevice; private WifiDisplayDevice mDisplayDevice;
@@ -67,14 +88,32 @@ final class WifiDisplayAdapter extends DisplayAdapter {
private WifiDisplay[] mRememberedDisplays = WifiDisplay.EMPTY_ARRAY; private WifiDisplay[] mRememberedDisplays = WifiDisplay.EMPTY_ARRAY;
private boolean mPendingStatusChangeBroadcast; private boolean mPendingStatusChangeBroadcast;
private boolean mPendingNotificationUpdate;
public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener, Context context, Handler handler, Listener listener,
PersistentDataStore persistentDataStore) { PersistentDataStore persistentDataStore) {
super(syncRoot, context, handler, listener, TAG); super(syncRoot, context, handler, listener, TAG);
mHandler = new WifiDisplayHandler(handler.getLooper());
mPersistentDataStore = persistentDataStore; mPersistentDataStore = persistentDataStore;
mSupportsProtectedBuffers = context.getResources().getBoolean( mSupportsProtectedBuffers = context.getResources().getBoolean(
com.android.internal.R.bool.config_wifiDisplaySupportsProtectedBuffers); 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 @Override
@@ -89,6 +128,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
pw.println("mAvailableDisplays=" + Arrays.toString(mAvailableDisplays)); pw.println("mAvailableDisplays=" + Arrays.toString(mAvailableDisplays));
pw.println("mRememberedDisplays=" + Arrays.toString(mRememberedDisplays)); pw.println("mRememberedDisplays=" + Arrays.toString(mRememberedDisplays));
pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast); pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast);
pw.println("mPendingNotificationUpdate=" + mPendingNotificationUpdate);
pw.println("mSupportsProtectedBuffers=" + mSupportsProtectedBuffers); pw.println("mSupportsProtectedBuffers=" + mSupportsProtectedBuffers);
// Try to dump the controller state. // Try to dump the controller state.
@@ -266,6 +306,8 @@ final class WifiDisplayAdapter extends DisplayAdapter {
mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height, mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height,
refreshRate, deviceFlags, surface); refreshRate, deviceFlags, surface);
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED);
scheduleUpdateNotificationLocked();
} }
private void handleDisconnectLocked() { private void handleDisconnectLocked() {
@@ -273,6 +315,8 @@ final class WifiDisplayAdapter extends DisplayAdapter {
mDisplayDevice.clearSurfaceLocked(); mDisplayDevice.clearSurfaceLocked();
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
mDisplayDevice = null; mDisplayDevice = null;
scheduleUpdateNotificationLocked();
} }
} }
@@ -280,28 +324,81 @@ final class WifiDisplayAdapter extends DisplayAdapter {
mCurrentStatus = null; mCurrentStatus = null;
if (!mPendingStatusChangeBroadcast) { if (!mPendingStatusChangeBroadcast) {
mPendingStatusChangeBroadcast = true; mPendingStatusChangeBroadcast = true;
getHandler().post(mStatusChangeBroadcast); mHandler.sendEmptyMessage(MSG_SEND_STATUS_CHANGE_BROADCAST);
} }
} }
private final Runnable mStatusChangeBroadcast = new Runnable() { private void scheduleUpdateNotificationLocked() {
@Override if (!mPendingNotificationUpdate) {
public void run() { mPendingNotificationUpdate = true;
final Intent intent; mHandler.sendEmptyMessage(MSG_UPDATE_NOTIFICATION);
synchronized (getSyncRoot()) { }
if (!mPendingStatusChangeBroadcast) { }
return;
}
mPendingStatusChangeBroadcast = false; // Runs on the handler.
intent = new Intent(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED); private void handleSendStatusChangeBroadcast() {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); final Intent intent;
intent.putExtra(DisplayManager.EXTRA_WIFI_DISPLAY_STATUS, synchronized (getSyncRoot()) {
getWifiDisplayStatusLocked()); if (!mPendingStatusChangeBroadcast) {
return;
} }
// Send protected broadcast about wifi display status to registered receivers. mPendingStatusChangeBroadcast = false;
getContext().sendBroadcast(intent); 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; 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;
}
}
}
} }