From a7f9c966bc90e52baaf0cf0c165463e5f44354c5 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Wed, 17 Oct 2012 15:15:12 -0700 Subject: [PATCH] Add a notification icon when connected to wireless display. Bug: 7350174 Change-Id: I18481e2a1445b0aa3340e5d9b02511394521e50e --- .../drawable-hdpi/ic_notify_wifidisplay.png | Bin 0 -> 941 bytes .../drawable-mdpi/ic_notify_wifidisplay.png | Bin 0 -> 721 bytes .../drawable-xhdpi/ic_notify_wifidisplay.png | Bin 0 -> 1096 bytes core/res/res/values/strings.xml | 7 + core/res/res/values/symbols.xml | 4 + .../server/display/WifiDisplayAdapter.java | 148 ++++++++++++++++-- 6 files changed, 143 insertions(+), 16 deletions(-) create mode 100644 core/res/res/drawable-hdpi/ic_notify_wifidisplay.png create mode 100644 core/res/res/drawable-mdpi/ic_notify_wifidisplay.png create mode 100644 core/res/res/drawable-xhdpi/ic_notify_wifidisplay.png diff --git a/core/res/res/drawable-hdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-hdpi/ic_notify_wifidisplay.png new file mode 100644 index 0000000000000000000000000000000000000000..35f27df17260ced48bcfa57c102153a7af95894a GIT binary patch literal 941 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBSkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+eS5K)hhiu0R{01Y44~ zy9>jA5L~c#`DCC7XMsm#F_88EW4Dvpb_@(mwVp1HArXh)PPgsx2^2YA|NN|UqVaCo zRu}b&8WUECa7`5D>UD8hdD&CMuF7TOqHBwm1YQjA2yt01bkTELK!kMJ_p`QL)$e9o zoBuvjA@7{>@8sFJ)$jKd|9f9^_j5v@6=rOnkH&2vd@>C8SPeba?RCi5k@<| zzbTh=-Wi!;Um#JD_GHtO+`29g?Z)(9MbTm}D+6j6E132$^fAUaZayGwUA{^ym!~+G zqcP4)!@on8J&u{bQTjkuN!T@(;$mTL*2r1&mao(7`K$Usxj^^^Cyykn-KtsF)?5?d zII1S1Y{2l2;eA7KkI@DbfAJ-oa=#tvSSe`DU~}~Nb-_hO7mk$HJ89T)ACcL>vxj}% zt+@O!F)zU_TpQZ>zf{zxwaDB{wVf^h;O_SuCwA(^Ov~T={LNeEu)QqnnDcu*b|eK{ zz4lmRt)a7<<6p@g9CJ*J6q#cyc6f8Mo~(UfT_7I8Xr_GWuwLg9v0EE{3Knq0*XuDq z@677&DDh&`Sp7~e)K*Gs!z#WjkGHKA57~PE(T&uia3B8&Z#|_Iue9vuI=iucUvqnp zrjqMi@pVQ`58bQ8ZuM_`W0=HRaO|5{=vChCBwa@B^2kZCLA3fR&;->JBA1vuPyo9rFh6LE8X zdEE6`NlJUU%*`CN_x_am&r`?vJ~*`|)NE}TFh#1CxJHzuB$lLFB^RXvDF!10LnB>7 z16@P25JOWdLvt$=3tapM_`B*=!~{Irtt#G+IN j$CUh}R0Yr6#Prml)Wnp^!jq|>Y{TH`>gTe~DWM4feKc}> literal 0 HcmV?d00001 diff --git a/core/res/res/drawable-mdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-mdpi/ic_notify_wifidisplay.png new file mode 100644 index 0000000000000000000000000000000000000000..f9c8678f7f644922472396a865a8359d866d543f GIT binary patch literal 721 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaL-l0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YPV z+ueoXKL{?^yL>WGgtNdSvKUBvfU(=jY&)Rw3q4&NLp+XOox0agBv9mdeRKQ%zZcF9Eo8FwO3#gbh z+xYuA+xY*V3m?`mXIXI1Dw=8MjxI|jj{{O0HZ8cv^n-Us`zH}aTc&;OjY)hvSZ*C) zxWV?T(u;GeX#3lMe@qsgwZS^V1&lUqc8r#c=U4r5tzBDog?a1hMP_{tzKWYy{tGe> z;YeLRtz^l&kW*J<&OWNXb;>Ev+jbpKis>7Md5rfP`VU-g@I5f)(vi^1h0K?7TKJRS zGTJw6pZH_u1F7@{i^4uIMX>TUJ}DSr1<%~X^wgl##FWaylc}Jj O#o+1c=d#Wzp$Py1Z5Cz# literal 0 HcmV?d00001 diff --git a/core/res/res/drawable-xhdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-xhdpi/ic_notify_wifidisplay.png new file mode 100644 index 0000000000000000000000000000000000000000..4cc0ee83faf896e950cd5673826a7e0c24e9946b GIT binary patch literal 1096 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTCmUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)pVryh>nTu$sZZAYL$MSD+10f-TA0 z-G$*l2rk&Wd@@jkv%n*=7)X17vD?XPI|c@32~QWtkc@k8XYTJ7b`&{ouP?n=-2b7C zpw1CD?bX^x?p^ zUAE|jSr^V1*a<3K@O;2oAaCLLOujQedS&F(i?crIaCrXxTls*sfHmUdSFYrcxAMs+ zW?t}^EI9jWwWoNK{}HvX^DEz;Xz3CV+aY4XcZYQz%akY5$k<*v6q4(O2s`J zT#a|hi=RK-wv+YE!M8{DF}D|5Z?f7pW%U8^IX~CUij1E$b7qqIzn7=QBGt6+bXj-3 zTfOD~hjod8&1M3A56{H+@7eVuMqlaoLQ56#;3g z?MX>Q8F=^>0o4?!QgH3eFhuw@BU>OJ#|8XVtQme}}>9 z{~9VirVM=#H{GkbAo2NXCzH}~xz`WuXFtiwo;T5B$A3nVdyyv!mjxQ%H@NfW{N)z5 zi4BL^tZz`N!wRN`@K#XKk>M%x`Aneb#<_hUQi#7P vNstY}`DrEPiAAXljw$&`sS2LCiRr09sfj6-g(p)%Ihw)K)z4*}Q$iB}CZNqY literal 0 HcmV?d00001 diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 72de22c8f3843..f8dbd84da82c8 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3821,6 +3821,13 @@ %1$s: %2$dx%3$d, %4$d dpi + + Wireless display is connected + + This screen is showing on another device + + Disconnect + Emergency call diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e76b67b7dc951..b3af161612e70 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1486,6 +1486,7 @@ + @@ -1621,6 +1622,9 @@ + + + diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java index c441b02110a7b..66eac88a1f55c 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/java/com/android/server/display/WifiDisplayAdapter.java @@ -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; + } + } + } }