Skip to content

Commit bfb27bb

Browse files
y-ikenagaisheriff
authored andcommitted
Allow override of p2p dialogs
By default, we show dialogs for connection requests and for user interaction for pin input from the framework. For applications, that want to make the experience more seamless we should allow automatic discovery and connection as long as one app can control it. We allow this for a foreground app alone right now. This will be a hidden API for now. Bug: 6411069 Change-Id: Id342e933073d30eb58bf5a03a47ca26a64df8ddb Signed-off-by: isheriff@google.com Signed-off-by: Yoshihiko Ikenaga <yoshihiko.ikenaga@jp.sony.com>
1 parent ca7086f commit bfb27bb

File tree

3 files changed

+474
-81
lines changed

3 files changed

+474
-81
lines changed

wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727
import java.util.HashMap;
2828

2929
/**
30-
* A class representing a Wi-Fi P2p device list
30+
* A class representing a Wi-Fi P2p device list.
3131
*
32+
* Note that the operations are not thread safe.
3233
* {@see WifiP2pManager}
3334
*/
3435
public class WifiP2pDeviceList implements Parcelable {
@@ -82,6 +83,13 @@ public void update(WifiP2pDevice device) {
8283
mDevices.put(device.deviceAddress, device);
8384
}
8485

86+
/** @hide */
87+
public void updateStatus(String deviceAddress, int status) {
88+
if (deviceAddress == null) return;
89+
WifiP2pDevice d = mDevices.get(deviceAddress);
90+
d.status = status;
91+
}
92+
8593
/** @hide */
8694
public WifiP2pDevice get(String deviceAddress) {
8795
if (deviceAddress == null) return null;

wifi/java/android/net/wifi/p2p/WifiP2pManager.java

Lines changed: 174 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
3131
import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceResponse;
3232
import android.os.Binder;
33+
import android.os.Bundle;
3334
import android.os.IBinder;
3435
import android.os.Handler;
3536
import 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

Comments
 (0)