3030import android .net .wifi .p2p .nsd .WifiP2pUpnpServiceInfo ;
3131import android .net .wifi .p2p .nsd .WifiP2pUpnpServiceResponse ;
3232import android .os .Binder ;
33+ import android .os .Bundle ;
3334import android .os .IBinder ;
3435import android .os .Handler ;
3536import android .os .Looper ;
@@ -265,6 +266,41 @@ public class WifiP2pManager {
265266 */
266267 public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice" ;
267268
269+ /**
270+ * The lookup key for a {@link #String} object.
271+ * Retrieve with {@link android.os.Bundle#getString(String)}.
272+ * @hide
273+ */
274+ public static final String APP_PKG_BUNDLE_KEY = "appPkgName" ;
275+
276+ /**
277+ * The lookup key for a {@link #Boolean} object.
278+ * Retrieve with {@link android.os.Bundle#getBoolean(String)}.
279+ * @hide
280+ */
281+ public static final String RESET_DIALOG_LISTENER_BUNDLE_KEY = "dialogResetFlag" ;
282+
283+ /**
284+ * The lookup key for a {@link #String} object.
285+ * Retrieve with {@link android.os.Bundle#getString(String)}.
286+ * @hide
287+ */
288+ public static final String WPS_PIN_BUNDLE_KEY = "wpsPin" ;
289+
290+ /**
291+ * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDevice} object
292+ * Retrieve with {@link android.os.Bundle#getParcelable(String)}.
293+ * @hide
294+ */
295+ public static final String P2P_DEV_BUNDLE_KEY = "wifiP2pDevice" ;
296+
297+ /**
298+ * The lookup key for a {@link android.net.wifi.p2p.WifiP2pConfig} object
299+ * Retrieve with {@link android.os.Bundle#getParcelable(String)}.
300+ * @hide
301+ */
302+ public static final String P2P_CONFIG_BUNDLE_KEY = "wifiP2pConfig" ;
303+
268304 IWifiP2pManager mService ;
269305
270306 private static final int BASE = Protocol .BASE_WIFI_P2P_MANAGER ;
@@ -388,6 +424,18 @@ public class WifiP2pManager {
388424 /** @hide */
389425 public static final int SET_DEVICE_NAME_SUCCEEDED = BASE + 53 ;
390426
427+ /** @hide */
428+ public static final int SET_DIALOG_LISTENER = BASE + 54 ;
429+ /** @hide */
430+ public static final int DIALOG_LISTENER_DETACHED = BASE + 55 ;
431+ /** @hide */
432+ public static final int DIALOG_LISTENER_ATTACHED = BASE + 56 ;
433+
434+ /** @hide */
435+ public static final int CONNECTION_REQUESTED = BASE + 57 ;
436+ /** @hide */
437+ public static final int SHOW_PIN_REQUESTED = BASE + 58 ;
438+
391439 /**
392440 * Create a new WifiP2pManager instance. Applications use
393441 * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -427,6 +475,14 @@ public WifiP2pManager(IWifiP2pManager service) {
427475 */
428476 public static final int NO_SERVICE_REQUESTS = 3 ;
429477
478+ /**
479+ * Passed with {@link DialogListener#onDetached}.
480+ * Indicates that the registered listener was detached from the system because
481+ * the application went into background.
482+ * @hide
483+ */
484+ public static final int NOT_IN_FOREGROUND = 4 ;
485+
430486 /** Interface for callback invocation when framework channel is lost */
431487 public interface ChannelListener {
432488 /**
@@ -475,7 +531,7 @@ public interface GroupInfoListener {
475531 public void onGroupInfoAvailable (WifiP2pGroup group );
476532 }
477533
478- /**
534+ /**
479535 * Interface for callback invocation when service discovery response other than
480536 * Upnp or Bonjour is received
481537 */
@@ -558,16 +614,60 @@ public void onUpnpServiceAvailable(List<String> uniqueServiceNames,
558614 }
559615
560616
617+ /**
618+ * Interface for callback invocation when dialog events are received.
619+ * see {@link #setDialogListener}.
620+ * @hide
621+ */
622+ public interface DialogListener {
623+
624+ /**
625+ * Called by the system when a request to show WPS pin is received.
626+ *
627+ * @param pin WPS pin.
628+ */
629+ public void onShowPinRequested (String pin );
630+
631+ /**
632+ * Called by the system when a request to establish the connection is received.
633+ *
634+ * Application can then call {@link #connect} with the given config if the request
635+ * is acceptable.
636+ *
637+ * @param device the source device.
638+ * @param config p2p configuration.
639+ */
640+ public void onConnectionRequested (WifiP2pDevice device , WifiP2pConfig config );
641+
642+ /**
643+ * Called by the system when this listener was attached to the system.
644+ */
645+ public void onAttached ();
646+
647+ /**
648+ * Called by the system when this listener was detached from the system or
649+ * failed to attach.
650+ *
651+ * Application can request again using {@link #setDialogListener} when it is
652+ * in the foreground.
653+ *
654+ * @param reason The reason for failure could be one of {@link #ERROR},
655+ * {@link #BUSY}, {@link #P2P_UNSUPPORTED} or {@link #NOT_IN_FOREGROUND}
656+ */
657+ public void onDetached (int reason );
658+ }
659+
561660 /**
562661 * A channel that connects the application to the Wifi p2p framework.
563662 * Most p2p operations require a Channel as an argument. An instance of Channel is obtained
564663 * by doing a call on {@link #initialize}
565664 */
566665 public static class Channel {
567- Channel (Looper looper , ChannelListener l ) {
666+ Channel (Context context , Looper looper , ChannelListener l ) {
568667 mAsyncChannel = new AsyncChannel ();
569668 mHandler = new P2pHandler (looper );
570669 mChannelListener = l ;
670+ mContext = context ;
571671 }
572672 private final static int INVALID_LISTENER_KEY = 0 ;
573673 private ChannelListener mChannelListener ;
@@ -578,9 +678,11 @@ public static class Channel {
578678 private HashMap <Integer , Object > mListenerMap = new HashMap <Integer , Object >();
579679 private Object mListenerMapLock = new Object ();
580680 private int mListenerKey = 0 ;
681+ private DialogListener mDialogListener ;
581682
582- AsyncChannel mAsyncChannel ;
583- P2pHandler mHandler ;
683+ private AsyncChannel mAsyncChannel ;
684+ private P2pHandler mHandler ;
685+ Context mContext ;
584686 class P2pHandler extends Handler {
585687 P2pHandler (Looper looper ) {
586688 super (looper );
@@ -656,6 +758,34 @@ public void handleMessage(Message message) {
656758 WifiP2pServiceResponse resp = (WifiP2pServiceResponse ) message .obj ;
657759 handleServiceResponse (resp );
658760 break ;
761+ case WifiP2pManager .CONNECTION_REQUESTED :
762+ if (mDialogListener != null ) {
763+ Bundle bundle = message .getData ();
764+ mDialogListener .onConnectionRequested (
765+ (WifiP2pDevice )bundle .getParcelable (
766+ P2P_DEV_BUNDLE_KEY ),
767+ (WifiP2pConfig )bundle .getParcelable (
768+ P2P_CONFIG_BUNDLE_KEY ));
769+ }
770+ break ;
771+ case WifiP2pManager .SHOW_PIN_REQUESTED :
772+ if (mDialogListener != null ) {
773+ Bundle bundle = message .getData ();
774+ mDialogListener .onShowPinRequested (
775+ bundle .getString (WPS_PIN_BUNDLE_KEY ));
776+ }
777+ break ;
778+ case WifiP2pManager .DIALOG_LISTENER_ATTACHED :
779+ if (mDialogListener != null ) {
780+ mDialogListener .onAttached ();
781+ }
782+ break ;
783+ case WifiP2pManager .DIALOG_LISTENER_DETACHED :
784+ if (mDialogListener != null ) {
785+ mDialogListener .onDetached (message .arg1 );
786+ mDialogListener = null ;
787+ }
788+ break ;
659789 default :
660790 Log .d (TAG , "Ignored " + message );
661791 break ;
@@ -721,6 +851,10 @@ private Object getListener(int key) {
721851 return mListenerMap .remove (key );
722852 }
723853 }
854+
855+ private void setDialogListener (DialogListener listener ) {
856+ mDialogListener = listener ;
857+ }
724858 }
725859
726860 private static void checkChannel (Channel c ) {
@@ -748,7 +882,7 @@ public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener
748882 Messenger messenger = getMessenger ();
749883 if (messenger == null ) return null ;
750884
751- Channel c = new Channel (srcLooper , listener );
885+ Channel c = new Channel (srcContext , srcLooper , listener );
752886 if (c .mAsyncChannel .connectSync (srcContext , c .mHandler , messenger )
753887 == AsyncChannel .STATUS_SUCCESSFUL ) {
754888 return c ;
@@ -1126,6 +1260,41 @@ public void setDeviceName(Channel c, String devName, ActionListener listener) {
11261260 }
11271261
11281262
1263+ /**
1264+ * Set dialog listener to over-ride system dialogs on p2p events. This function
1265+ * allows an application to receive notifications on connection requests from
1266+ * peers so that it can customize the user experience for connection with
1267+ * peers.
1268+ *
1269+ * <p> The function call immediately returns after sending a request
1270+ * to the framework. The application is notified of a success or failure to attach
1271+ * to the system through listener callbacks {@link DialogListener#onAttached} or
1272+ * {@link DialogListener#onDetached}.
1273+ *
1274+ * <p> Note that only foreground application will be successful in overriding the
1275+ * system dialogs.
1276+ * @hide
1277+ *
1278+ * @param c is the channel created at {@link #initialize}
1279+ * @param listener for callback on a dialog event.
1280+ */
1281+ public void setDialogListener (Channel c , DialogListener listener ) {
1282+ checkChannel (c );
1283+ c .setDialogListener (listener );
1284+
1285+ /**
1286+ * mAsyncChannel should always stay private and inaccessible from the app
1287+ * to prevent an app from sending a message with a fake app name to gain
1288+ * control over the dialogs
1289+ */
1290+ Message msg = Message .obtain ();
1291+ Bundle bundle = new Bundle ();
1292+ bundle .putString (APP_PKG_BUNDLE_KEY , c .mContext .getPackageName ());
1293+ bundle .putBoolean (RESET_DIALOG_LISTENER_BUNDLE_KEY , listener == null );
1294+ msg .what = SET_DIALOG_LISTENER ;
1295+ msg .setData (bundle );
1296+ c .mAsyncChannel .sendMessage (msg );
1297+ }
11291298
11301299 /**
11311300 * Get a reference to WifiP2pService handler. This is used to establish
0 commit comments