• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi.p2p;
18 
19 import android.annotation.NonNull;
20 import android.net.wifi.CoexUnsafeChannel;
21 import android.net.wifi.ScanResult;
22 import android.net.wifi.p2p.WifiP2pConfig;
23 import android.net.wifi.p2p.WifiP2pGroup;
24 import android.net.wifi.p2p.WifiP2pGroupList;
25 import android.net.wifi.p2p.WifiP2pManager;
26 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
27 import android.util.Log;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 import com.android.server.wifi.WifiGlobals;
31 
32 import java.util.List;
33 import java.util.Set;
34 
35 public class SupplicantP2pIfaceHal {
36     private static final String TAG = "SupplicantP2pIfaceHal";
37     private final Object mLock = new Object();
38     private static boolean sVerboseLoggingEnabled = true;
39     private static boolean sHalVerboseLoggingEnabled = true;
40     private final WifiP2pMonitor mMonitor;
41     private final WifiGlobals mWifiGlobals;
42 
43     // HAL interface object - might be implemented by HIDL or AIDL
44     private ISupplicantP2pIfaceHal mP2pIfaceHal;
45 
SupplicantP2pIfaceHal(WifiP2pMonitor monitor, WifiGlobals wifiGlobals)46     public SupplicantP2pIfaceHal(WifiP2pMonitor monitor, WifiGlobals wifiGlobals) {
47         mMonitor = monitor;
48         mWifiGlobals = wifiGlobals;
49         mP2pIfaceHal = createP2pIfaceHalMockable();
50         if (mP2pIfaceHal == null) {
51             Log.wtf(TAG, "Failed to get internal ISupplicantP2pIfaceHal instance.");
52         }
53     }
54 
55     /**
56      * Enable verbose logging for all sub modules.
57      *
58      * @param verboseEnabled Verbose flag set in overlay XML.
59      * @param halVerboseEnabled Verbose flag set by the user.
60      */
enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled)61     public static void enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled) {
62         sVerboseLoggingEnabled = verboseEnabled;
63         sHalVerboseLoggingEnabled = halVerboseEnabled;
64         SupplicantP2pIfaceHalHidlImpl.enableVerboseLogging(verboseEnabled, halVerboseEnabled);
65         SupplicantP2pIfaceHalAidlImpl.enableVerboseLogging(verboseEnabled, halVerboseEnabled);
66     }
67 
68     /**
69      * Set the debug log level for wpa_supplicant
70      *
71      * @param turnOnVerbose Whether to turn on verbose logging or not.
72      * @return true if request is sent successfully, false otherwise.
73      */
setLogLevel(boolean turnOnVerbose)74     public boolean setLogLevel(boolean turnOnVerbose) {
75         synchronized (mLock) {
76             String methodStr = "setLogLevel";
77             if (mP2pIfaceHal == null) {
78                 return handleNullHal(methodStr);
79             }
80             return mP2pIfaceHal.setLogLevel(turnOnVerbose,
81                     mWifiGlobals.getShowKeyVerboseLoggingModeEnabled());
82         }
83     }
84 
85     /**
86      * Initialize the P2P Iface HAL. Creates the internal ISupplicantP2pIfaceHal
87      * object and calls its initialize method.
88      *
89      * @return true if the initialization succeeded
90      */
initialize()91     public boolean initialize() {
92         synchronized (mLock) {
93             if (sVerboseLoggingEnabled) {
94                 Log.i(TAG, "Initializing SupplicantP2pIfaceHal.");
95             }
96             if (mP2pIfaceHal == null) {
97                 Log.wtf(TAG, "Internal ISupplicantP2pIfaceHal instance does not exist.");
98                 return false;
99             }
100             if (!mP2pIfaceHal.initialize()) {
101                 Log.e(TAG, "Failed to init ISupplicantP2pIfaceHal, stopping startup.");
102                 return false;
103             }
104             setLogLevel(sHalVerboseLoggingEnabled);
105             return true;
106         }
107     }
108 
109     /**
110      * Wrapper function to create the ISupplicantP2pIfaceHal object.
111      * Created to be mockable in unit tests.
112      */
113     @VisibleForTesting
createP2pIfaceHalMockable()114     protected ISupplicantP2pIfaceHal createP2pIfaceHalMockable() {
115         synchronized (mLock) {
116             // Prefer AIDL implementation if service is declared.
117             if (SupplicantP2pIfaceHalAidlImpl.serviceDeclared()) {
118                 Log.i(TAG, "Initializing SupplicantP2pIfaceHal using AIDL implementation.");
119                 return new SupplicantP2pIfaceHalAidlImpl(mMonitor);
120 
121             } else if (SupplicantP2pIfaceHalHidlImpl.serviceDeclared()) {
122                 Log.i(TAG, "Initializing SupplicantP2pIfaceHal using HIDL implementation.");
123                 return new SupplicantP2pIfaceHalHidlImpl(mMonitor);
124             }
125             Log.e(TAG, "No HIDL or AIDL service available for SupplicantP2pIfaceHal.");
126             return null;
127         }
128     }
129 
130     /**
131      * Setup the P2P iface.
132      *
133      * @param ifaceName Name of the interface.
134      * @return true on success, false otherwise.
135      */
setupIface(@onNull String ifaceName)136     public boolean setupIface(@NonNull String ifaceName) {
137         synchronized (mLock) {
138             String methodStr = "setupIface";
139             if (mP2pIfaceHal == null) {
140                 return handleNullHal(methodStr);
141             }
142             return mP2pIfaceHal.setupIface(ifaceName);
143         }
144     }
145 
146     /**
147      * Teardown the P2P interface.
148      *
149      * @param ifaceName Name of the interface.
150      * @return true on success, false otherwise.
151      */
teardownIface(@onNull String ifaceName)152     public boolean teardownIface(@NonNull String ifaceName) {
153         synchronized (mLock) {
154             String methodStr = "teardownIface";
155             if (mP2pIfaceHal == null) {
156                 return handleNullHal(methodStr);
157             }
158             return mP2pIfaceHal.teardownIface(ifaceName);
159         }
160     }
161 
162     /**
163      * Signals whether initialization started successfully.
164      */
isInitializationStarted()165     public boolean isInitializationStarted() {
166         synchronized (mLock) {
167             String methodStr = "isInitializationStarted";
168             if (mP2pIfaceHal == null) {
169                 return handleNullHal(methodStr);
170             }
171             return mP2pIfaceHal.isInitializationStarted();
172         }
173     }
174 
175     /**
176      * Signals whether Initialization completed successfully. Only necessary for testing, is not
177      * needed to guard calls etc.
178      */
isInitializationComplete()179     public boolean isInitializationComplete() {
180         synchronized (mLock) {
181             String methodStr = "isInitializationComplete";
182             if (mP2pIfaceHal == null) {
183                 return handleNullHal(methodStr);
184             }
185             return mP2pIfaceHal.isInitializationComplete();
186         }
187     }
188 
189     /**
190      * Initiate a P2P service discovery with a (optional) timeout.
191      *
192      * @param timeout Max time to be spent is performing discovery.
193      *        Set to 0 to indefinitely continue discovery until an explicit
194      *        |stopFind| is sent.
195      * @return boolean value indicating whether operation was successful.
196      */
find(int timeout)197     public boolean find(int timeout) {
198         synchronized (mLock) {
199             String methodStr = "find";
200             if (mP2pIfaceHal == null) {
201                 return handleNullHal(methodStr);
202             }
203             return mP2pIfaceHal.find(timeout);
204         }
205     }
206 
207     /**
208      * Initiate a P2P device discovery with a scan type, a (optional) frequency, and a (optional)
209      * timeout.
210      *
211      * @param type indicates what channels to scan.
212      *        Valid values are {@link WifiP2pManager#WIFI_P2P_SCAN_FULL} for doing full P2P scan,
213      *        {@link WifiP2pManager#WIFI_P2P_SCAN_SOCIAL} for scanning social channels,
214      *        {@link WifiP2pManager#WIFI_P2P_SCAN_SINGLE_FREQ} for scanning a specified frequency.
215      * @param freq is the frequency to be scanned.
216      *        The possible values are:
217      *        <ul>
218      *        <li> A valid frequency for {@link WifiP2pManager#WIFI_P2P_SCAN_SINGLE_FREQ}</li>
219      *        <li> {@link WifiP2pManager#WIFI_P2P_SCAN_FREQ_UNSPECIFIED} for
220      *          {@link WifiP2pManager#WIFI_P2P_SCAN_FULL} and
221      *          {@link WifiP2pManager#WIFI_P2P_SCAN_SOCIAL}</li>
222      *        </ul>
223      * @param timeout Max time to be spent is performing discovery.
224      *        Set to 0 to indefinitely continue discovery until an explicit
225      *        |stopFind| is sent.
226      * @return boolean value indicating whether operation was successful.
227      */
find(@ifiP2pManager.WifiP2pScanType int type, int freq, int timeout)228     public boolean find(@WifiP2pManager.WifiP2pScanType int type, int freq, int timeout) {
229         synchronized (mLock) {
230             String methodStr = "find";
231             if (mP2pIfaceHal == null) {
232                 return handleNullHal(methodStr);
233             }
234             return mP2pIfaceHal.find(type, freq, timeout);
235         }
236     }
237 
238     /**
239      * Stop an ongoing P2P service discovery.
240      *
241      * @return boolean value indicating whether operation was successful.
242      */
stopFind()243     public boolean stopFind() {
244         synchronized (mLock) {
245             String methodStr = "stopFind";
246             if (mP2pIfaceHal == null) {
247                 return handleNullHal(methodStr);
248             }
249             return mP2pIfaceHal.stopFind();
250         }
251     }
252 
253     /**
254      * Flush P2P peer table and state.
255      *
256      * @return boolean value indicating whether operation was successful.
257      */
flush()258     public boolean flush() {
259         synchronized (mLock) {
260             String methodStr = "flush";
261             if (mP2pIfaceHal == null) {
262                 return handleNullHal(methodStr);
263             }
264             return mP2pIfaceHal.flush();
265         }
266     }
267 
268     /**
269      * This command can be used to flush all services from the
270      * device.
271      *
272      * @return boolean value indicating whether operation was successful.
273      */
serviceFlush()274     public boolean serviceFlush() {
275         synchronized (mLock) {
276             String methodStr = "serviceFlush";
277             if (mP2pIfaceHal == null) {
278                 return handleNullHal(methodStr);
279             }
280             return mP2pIfaceHal.serviceFlush();
281         }
282     }
283 
284     /**
285      * Turn on/off power save mode for the interface.
286      *
287      * @param groupIfName Group interface name to use.
288      * @param enable Indicate if power save is to be turned on/off.
289      *
290      * @return boolean value indicating whether operation was successful.
291      */
setPowerSave(String groupIfName, boolean enable)292     public boolean setPowerSave(String groupIfName, boolean enable) {
293         synchronized (mLock) {
294             String methodStr = "setPowerSave";
295             if (mP2pIfaceHal == null) {
296                 return handleNullHal(methodStr);
297             }
298             return mP2pIfaceHal.setPowerSave(groupIfName, enable);
299         }
300     }
301 
302     /**
303      * Set the Maximum idle time in seconds for P2P groups.
304      * This value controls how long a P2P group is maintained after there
305      * is no other members in the group. As a group owner, this means no
306      * associated stations in the group. As a P2P client, this means no
307      * group owner seen in scan results.
308      *
309      * @param groupIfName Group interface name to use.
310      * @param timeoutInSec Timeout value in seconds.
311      *
312      * @return boolean value indicating whether operation was successful.
313      */
setGroupIdle(String groupIfName, int timeoutInSec)314     public boolean setGroupIdle(String groupIfName, int timeoutInSec) {
315         synchronized (mLock) {
316             String methodStr = "setGroupIdle";
317             if (mP2pIfaceHal == null) {
318                 return handleNullHal(methodStr);
319             }
320             return mP2pIfaceHal.setGroupIdle(groupIfName, timeoutInSec);
321         }
322     }
323 
324     /**
325      * Set the postfix to be used for P2P SSID's.
326      *
327      * @param postfix String to be appended to SSID.
328      *
329      * @return boolean value indicating whether operation was successful.
330      */
setSsidPostfix(String postfix)331     public boolean setSsidPostfix(String postfix) {
332         synchronized (mLock) {
333             String methodStr = "setSsidPostfix";
334             if (mP2pIfaceHal == null) {
335                 return handleNullHal(methodStr);
336             }
337             return mP2pIfaceHal.setSsidPostfix(postfix);
338         }
339     }
340 
341     /**
342      * Start P2P group formation with a discovered P2P peer. This includes
343      * optional group owner negotiation, group interface setup, provisioning,
344      * and establishing data connection.
345      *
346      * @param config Configuration to use to connect to remote device.
347      * @param joinExistingGroup Indicates that this is a command to join an
348      *        existing group as a client. It skips the group owner negotiation
349      *        part. This must send a Provision Discovery Request message to the
350      *        target group owner before associating for WPS provisioning.
351      *
352      * @return String containing generated pin, if selected provision method
353      *        uses PIN.
354      */
connect(WifiP2pConfig config, boolean joinExistingGroup)355     public String connect(WifiP2pConfig config, boolean joinExistingGroup) {
356         synchronized (mLock) {
357             String methodStr = "connect";
358             if (mP2pIfaceHal == null) {
359                 handleNullHal(methodStr);
360                 return null;
361             }
362             return mP2pIfaceHal.connect(config, joinExistingGroup);
363         }
364     }
365 
366     /**
367      * Cancel an ongoing P2P group formation and joining-a-group related
368      * operation. This operation unauthorizes the specific peer device (if any
369      * had been authorized to start group formation), stops P2P find (if in
370      * progress), stops pending operations for join-a-group, and removes the
371      * P2P group interface (if one was used) that is in the WPS provisioning
372      * step. If the WPS provisioning step has been completed, the group is not
373      * terminated.
374      *
375      * @return boolean value indicating whether operation was successful.
376      */
cancelConnect()377     public boolean cancelConnect() {
378         synchronized (mLock) {
379             String methodStr = "cancelConnect";
380             if (mP2pIfaceHal == null) {
381                 return handleNullHal(methodStr);
382             }
383             return mP2pIfaceHal.cancelConnect();
384         }
385     }
386 
387     /**
388      * Send P2P provision discovery request to the specified peer. The
389      * parameters for this command are the P2P device address of the peer and the
390      * desired configuration method.
391      *
392      * @param config Config class describing peer setup.
393      *
394      * @return boolean value indicating whether operation was successful.
395      */
provisionDiscovery(WifiP2pConfig config)396     public boolean provisionDiscovery(WifiP2pConfig config) {
397         synchronized (mLock) {
398             String methodStr = "provisionDiscovery";
399             if (mP2pIfaceHal == null) {
400                 return handleNullHal(methodStr);
401             }
402             return mP2pIfaceHal.provisionDiscovery(config);
403         }
404     }
405 
406     /**
407      * Invite a device to a persistent group.
408      * If the peer device is the group owner of the persistent group, the peer
409      * parameter is not needed. Otherwise it is used to specify which
410      * device to invite. |goDeviceAddress| parameter may be used to override
411      * the group owner device address for Invitation Request should it not be
412      * known for some reason (this should not be needed in most cases).
413      *
414      * @param group Group object to use.
415      * @param peerAddress MAC address of the device to invite.
416      *
417      * @return boolean value indicating whether operation was successful.
418      */
invite(WifiP2pGroup group, String peerAddress)419     public boolean invite(WifiP2pGroup group, String peerAddress) {
420         synchronized (mLock) {
421             String methodStr = "invite";
422             if (mP2pIfaceHal == null) {
423                 return handleNullHal(methodStr);
424             }
425             return mP2pIfaceHal.invite(group, peerAddress);
426         }
427     }
428 
429     /**
430      * Reject connection attempt from a peer (specified with a device
431      * address). This is a mechanism to reject a pending group owner negotiation
432      * with a peer and request to automatically block any further connection or
433      * discovery of the peer.
434      *
435      * @param peerAddress MAC address of the device to reject.
436      *
437      * @return boolean value indicating whether operation was successful.
438      */
reject(String peerAddress)439     public boolean reject(String peerAddress) {
440         synchronized (mLock) {
441             String methodStr = "reject";
442             if (mP2pIfaceHal == null) {
443                 return handleNullHal(methodStr);
444             }
445             return mP2pIfaceHal.reject(peerAddress);
446         }
447     }
448 
449     /**
450      * Gets the MAC address of the device.
451      *
452      * @return MAC address of the device.
453      */
getDeviceAddress()454     public String getDeviceAddress() {
455         synchronized (mLock) {
456             String methodStr = "getDeviceAddress";
457             if (mP2pIfaceHal == null) {
458                 handleNullHal(methodStr);
459                 return null;
460             }
461             return mP2pIfaceHal.getDeviceAddress();
462         }
463     }
464 
465     /**
466      * Gets the operational SSID of the device.
467      *
468      * @param address MAC address of the peer.
469      *
470      * @return SSID of the device.
471      */
getSsid(String address)472     public String getSsid(String address) {
473         synchronized (mLock) {
474             String methodStr = "getSsid";
475             if (mP2pIfaceHal == null) {
476                 handleNullHal(methodStr);
477                 return null;
478             }
479             return mP2pIfaceHal.getSsid(address);
480         }
481     }
482 
483     /**
484      * Reinvoke a device from a persistent group.
485      *
486      * @param networkId Used to specify the persistent group.
487      * @param peerAddress MAC address of the device to reinvoke.
488      *
489      * @return true, if operation was successful.
490      */
reinvoke(int networkId, String peerAddress)491     public boolean reinvoke(int networkId, String peerAddress) {
492         synchronized (mLock) {
493             String methodStr = "reinvoke";
494             if (mP2pIfaceHal == null) {
495                 return handleNullHal(methodStr);
496             }
497             return mP2pIfaceHal.reinvoke(networkId, peerAddress);
498         }
499     }
500 
501     /**
502      * Set up a P2P group owner manually (i.e., without group owner
503      * negotiation with a specific peer). This is also known as autonomous
504      * group owner.
505      *
506      * @param networkId Used to specify the restart of a persistent group.
507      * @param isPersistent Used to request a persistent group to be formed.
508      *
509      * @return true, if operation was successful.
510      */
groupAdd(int networkId, boolean isPersistent)511     public boolean groupAdd(int networkId, boolean isPersistent) {
512         synchronized (mLock) {
513             String methodStr = "groupAdd";
514             if (mP2pIfaceHal == null) {
515                 return handleNullHal(methodStr);
516             }
517             return mP2pIfaceHal.groupAdd(networkId, isPersistent);
518         }
519     }
520 
521     /**
522      * Set up a P2P group owner manually.
523      * This is a helper method that invokes groupAdd(networkId, isPersistent) internally.
524      *
525      * @param isPersistent Used to request a persistent group to be formed.
526      *
527      * @return true, if operation was successful.
528      */
groupAdd(boolean isPersistent)529     public boolean groupAdd(boolean isPersistent) {
530         synchronized (mLock) {
531             // Supplicant expects networkId to be -1 if not supplied.
532             return groupAdd(-1, isPersistent);
533         }
534     }
535 
536     /**
537      * Set up a P2P group as Group Owner or join a group with a configuration.
538      *
539      * @param networkName SSID of the group to be formed
540      * @param passphrase passphrase of the group to be formed
541      * @param isPersistent Used to request a persistent group to be formed.
542      * @param freq prefered frequencty or band of the group to be formed
543      * @param peerAddress peerAddress Group Owner MAC address, only applied for Group Client.
544      *        If the MAC is "00:00:00:00:00:00", the device will try to find a peer
545      *        whose SSID matches ssid.
546      * @param join join a group or create a group
547      *
548      * @return true, if operation was successful.
549      */
groupAdd(String networkName, String passphrase, boolean isPersistent, int freq, String peerAddress, boolean join)550     public boolean groupAdd(String networkName, String passphrase,
551             boolean isPersistent, int freq, String peerAddress, boolean join) {
552         synchronized (mLock) {
553             String methodStr = "groupAdd";
554             if (mP2pIfaceHal == null) {
555                 return handleNullHal(methodStr);
556             }
557             return mP2pIfaceHal.groupAdd(networkName, passphrase,
558                     isPersistent, freq, peerAddress, join);
559         }
560     }
561 
562     /**
563      * Terminate a P2P group. If a new virtual network interface was used for
564      * the group, it must also be removed. The network interface name of the
565      * group interface is used as a parameter for this command.
566      *
567      * @param groupName Group interface name to use.
568      *
569      * @return true, if operation was successful.
570      */
groupRemove(String groupName)571     public boolean groupRemove(String groupName) {
572         synchronized (mLock) {
573             String methodStr = "groupRemove";
574             if (mP2pIfaceHal == null) {
575                 return handleNullHal(methodStr);
576             }
577             return mP2pIfaceHal.groupRemove(groupName);
578         }
579     }
580 
581     /**
582      * Gets the capability of the group which the device is a
583      * member of.
584      *
585      * @param peerAddress MAC address of the peer.
586      *
587      * @return combination of |GroupCapabilityMask| values.
588      */
getGroupCapability(String peerAddress)589     public int getGroupCapability(String peerAddress) {
590         synchronized (mLock) {
591             String methodStr = "getGroupCapability";
592             if (mP2pIfaceHal == null) {
593                 handleNullHal(methodStr);
594                 return -1;
595             }
596             return mP2pIfaceHal.getGroupCapability(peerAddress);
597         }
598     }
599 
600     /**
601      * Configure Extended Listen Timing.
602      *
603      * If enabled, listen state must be entered every |intervalInMillis| for at
604      * least |periodInMillis|. Both values have acceptable range of 1-65535
605      * (with interval obviously having to be larger than or equal to duration).
606      * If the P2P module is not idle at the time the Extended Listen Timing
607      * timeout occurs, the Listen State operation must be skipped.
608      *
609      * @param enable Enables or disables listening.
610      * @param periodInMillis Period in milliseconds.
611      * @param intervalInMillis Interval in milliseconds.
612      *
613      * @return true, if operation was successful.
614      */
configureExtListen(boolean enable, int periodInMillis, int intervalInMillis)615     public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis) {
616         synchronized (mLock) {
617             String methodStr = "configureExtListen";
618             if (mP2pIfaceHal == null) {
619                 return handleNullHal(methodStr);
620             }
621             return mP2pIfaceHal.configureExtListen(enable, periodInMillis, intervalInMillis);
622         }
623     }
624 
625     /**
626      * Set P2P Listen channel.
627      *
628      * @param listenChannel Wifi channel. eg, 1, 6, 11.
629      *
630      * @return true, if operation was successful.
631      */
setListenChannel(int listenChannel)632     public boolean setListenChannel(int listenChannel) {
633         synchronized (mLock) {
634             String methodStr = "setListenChannel";
635             if (mP2pIfaceHal == null) {
636                 return handleNullHal(methodStr);
637             }
638             return mP2pIfaceHal.setListenChannel(listenChannel);
639         }
640     }
641 
642     /**
643      * Set P2P operating channel.
644      *
645      * @param operatingChannel the desired operating channel.
646      * @param unsafeChannels channels which p2p cannot use.
647      *
648      * @return true, if operation was successful.
649      */
setOperatingChannel(int operatingChannel, @NonNull List<CoexUnsafeChannel> unsafeChannels)650     public boolean setOperatingChannel(int operatingChannel,
651             @NonNull List<CoexUnsafeChannel> unsafeChannels) {
652         synchronized (mLock) {
653             String methodStr = "setOperatingChannel";
654             if (mP2pIfaceHal == null) {
655                 return handleNullHal(methodStr);
656             }
657             return mP2pIfaceHal.setOperatingChannel(operatingChannel, unsafeChannels);
658         }
659     }
660 
661     /**
662      * This command can be used to add a upnp/bonjour service.
663      *
664      * @param servInfo List of service queries.
665      *
666      * @return true, if operation was successful.
667      */
serviceAdd(WifiP2pServiceInfo servInfo)668     public boolean serviceAdd(WifiP2pServiceInfo servInfo) {
669         synchronized (mLock) {
670             String methodStr = "serviceAdd";
671             if (mP2pIfaceHal == null) {
672                 return handleNullHal(methodStr);
673             }
674             return mP2pIfaceHal.serviceAdd(servInfo);
675         }
676     }
677 
678     /**
679      * This command can be used to remove a upnp/bonjour service.
680      *
681      * @param servInfo List of service queries.
682      *
683      * @return true, if operation was successful.
684      */
serviceRemove(WifiP2pServiceInfo servInfo)685     public boolean serviceRemove(WifiP2pServiceInfo servInfo) {
686         synchronized (mLock) {
687             String methodStr = "serviceRemove";
688             if (mP2pIfaceHal == null) {
689                 return handleNullHal(methodStr);
690             }
691             return mP2pIfaceHal.serviceRemove(servInfo);
692         }
693     }
694 
695     /**
696      * Schedule a P2P service discovery request. The parameters for this command
697      * are the device address of the peer device (or 00:00:00:00:00:00 for
698      * wildcard query that is sent to every discovered P2P peer that supports
699      * service discovery) and P2P Service Query TLV(s) as hexdump.
700      *
701      * @param peerAddress MAC address of the device to discover.
702      * @param query Hex dump of the query data.
703      * @return identifier Identifier for the request. Can be used to cancel the
704      *         request.
705      */
requestServiceDiscovery(String peerAddress, String query)706     public String requestServiceDiscovery(String peerAddress, String query) {
707         synchronized (mLock) {
708             String methodStr = "requestServiceDiscovery";
709             if (mP2pIfaceHal == null) {
710                 handleNullHal(methodStr);
711                 return null;
712             }
713             return mP2pIfaceHal.requestServiceDiscovery(peerAddress, query);
714         }
715     }
716 
717     /**
718      * Cancel a previous service discovery request.
719      *
720      * @param identifier Identifier for the request to cancel.
721      * @return true, if operation was successful.
722      */
cancelServiceDiscovery(String identifier)723     public boolean cancelServiceDiscovery(String identifier) {
724         synchronized (mLock) {
725             String methodStr = "cancelServiceDiscovery";
726             if (mP2pIfaceHal == null) {
727                 return handleNullHal(methodStr);
728             }
729             return mP2pIfaceHal.cancelServiceDiscovery(identifier);
730         }
731     }
732 
733     /**
734      * Send driver command to set Miracast mode.
735      *
736      * @param mode Mode of Miracast.
737      * @return true, if operation was successful.
738      */
setMiracastMode(int mode)739     public boolean setMiracastMode(int mode) {
740         synchronized (mLock) {
741             String methodStr = "setMiracastMode";
742             if (mP2pIfaceHal == null) {
743                 return handleNullHal(methodStr);
744             }
745             return mP2pIfaceHal.setMiracastMode(mode);
746         }
747     }
748 
749     /**
750      * Initiate WPS Push Button setup.
751      * The PBC operation requires that a button is also pressed at the
752      * AP/Registrar at about the same time (2 minute window).
753      *
754      * @param groupIfName Group interface name to use.
755      * @param bssid BSSID of the AP. Use empty bssid to indicate wildcard.
756      * @return true, if operation was successful.
757      */
startWpsPbc(String groupIfName, String bssid)758     public boolean startWpsPbc(String groupIfName, String bssid) {
759         synchronized (mLock) {
760             String methodStr = "startWpsPbc";
761             if (mP2pIfaceHal == null) {
762                 return handleNullHal(methodStr);
763             }
764             return mP2pIfaceHal.startWpsPbc(groupIfName, bssid);
765         }
766     }
767 
768     /**
769      * Initiate WPS Pin Keypad setup.
770      *
771      * @param groupIfName Group interface name to use.
772      * @param pin 8 digit pin to be used.
773      * @return true, if operation was successful.
774      */
startWpsPinKeypad(String groupIfName, String pin)775     public boolean startWpsPinKeypad(String groupIfName, String pin) {
776         synchronized (mLock) {
777             String methodStr = "startWpsPinKeypad";
778             if (mP2pIfaceHal == null) {
779                 return handleNullHal(methodStr);
780             }
781             return mP2pIfaceHal.startWpsPinKeypad(groupIfName, pin);
782         }
783     }
784 
785     /**
786      * Initiate WPS Pin Display setup.
787      *
788      * @param groupIfName Group interface name to use.
789      * @param bssid BSSID of the AP. Use empty bssid to indicate wildcard.
790      * @return generated pin if operation was successful, null otherwise.
791      */
startWpsPinDisplay(String groupIfName, String bssid)792     public String startWpsPinDisplay(String groupIfName, String bssid) {
793         synchronized (mLock) {
794             String methodStr = "startWpsPinDisplay";
795             if (mP2pIfaceHal == null) {
796                 handleNullHal(methodStr);
797                 return null;
798             }
799             return mP2pIfaceHal.startWpsPinDisplay(groupIfName, bssid);
800         }
801     }
802 
803     /**
804      * Cancel any ongoing WPS operations.
805      *
806      * @param groupIfName Group interface name to use.
807      * @return true, if operation was successful.
808      */
cancelWps(String groupIfName)809     public boolean cancelWps(String groupIfName) {
810         synchronized (mLock) {
811             String methodStr = "cancelWps";
812             if (mP2pIfaceHal == null) {
813                 return handleNullHal(methodStr);
814             }
815             return mP2pIfaceHal.cancelWps(groupIfName);
816         }
817     }
818 
819     /**
820      * Enable/Disable Wifi Display.
821      *
822      * @param enable true to enable, false to disable.
823      * @return true, if operation was successful.
824      */
enableWfd(boolean enable)825     public boolean enableWfd(boolean enable) {
826         synchronized (mLock) {
827             String methodStr = "enableWfd";
828             if (mP2pIfaceHal == null) {
829                 return handleNullHal(methodStr);
830             }
831             return mP2pIfaceHal.enableWfd(enable);
832         }
833     }
834 
835     /**
836      * Set Wifi Display device info.
837      *
838      * @param info WFD device info as described in section 5.1.2 of WFD technical
839      *        specification v1.0.0.
840      * @return true, if operation was successful.
841      */
setWfdDeviceInfo(String info)842     public boolean setWfdDeviceInfo(String info) {
843         synchronized (mLock) {
844             String methodStr = "setWfdDeviceInfo";
845             if (mP2pIfaceHal == null) {
846                 return handleNullHal(methodStr);
847             }
848             return mP2pIfaceHal.setWfdDeviceInfo(info);
849         }
850     }
851 
852     /**
853      * Remove network with provided id.
854      *
855      * @param networkId Id of the network to lookup.
856      * @return true, if operation was successful.
857      */
removeNetwork(int networkId)858     public boolean removeNetwork(int networkId) {
859         synchronized (mLock) {
860             String methodStr = "removeNetwork";
861             if (mP2pIfaceHal == null) {
862                 return handleNullHal(methodStr);
863             }
864             return mP2pIfaceHal.removeNetwork(networkId);
865         }
866     }
867 
868     /**
869      * Get the persistent group list from wpa_supplicant's p2p mgmt interface
870      *
871      * @param groups WifiP2pGroupList to store persistent groups in
872      * @return true, if list has been modified.
873      */
loadGroups(WifiP2pGroupList groups)874     public boolean loadGroups(WifiP2pGroupList groups) {
875         synchronized (mLock) {
876             String methodStr = "loadGroups";
877             if (mP2pIfaceHal == null) {
878                 return handleNullHal(methodStr);
879             }
880             return mP2pIfaceHal.loadGroups(groups);
881         }
882     }
883 
884     /**
885      * Set WPS device name.
886      *
887      * @param name String to be set.
888      * @return true if request is sent successfully, false otherwise.
889      */
setWpsDeviceName(String name)890     public boolean setWpsDeviceName(String name) {
891         synchronized (mLock) {
892             String methodStr = "setWpsDeviceName";
893             if (mP2pIfaceHal == null) {
894                 return handleNullHal(methodStr);
895             }
896             return mP2pIfaceHal.setWpsDeviceName(name);
897         }
898     }
899 
900     /**
901      * Set WPS device type.
902      *
903      * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
904      * @return true if request is sent successfully, false otherwise.
905      */
setWpsDeviceType(String typeStr)906     public boolean setWpsDeviceType(String typeStr) {
907         synchronized (mLock) {
908             String methodStr = "setWpsDeviceType";
909             if (mP2pIfaceHal == null) {
910                 return handleNullHal(methodStr);
911             }
912             return mP2pIfaceHal.setWpsDeviceType(typeStr);
913         }
914     }
915 
916     /**
917      * Set WPS config methods
918      *
919      * @param configMethodsStr List of config methods.
920      * @return true if request is sent successfully, false otherwise.
921      */
setWpsConfigMethods(String configMethodsStr)922     public boolean setWpsConfigMethods(String configMethodsStr) {
923         synchronized (mLock) {
924             String methodStr = "setWpsConfigMethods";
925             if (mP2pIfaceHal == null) {
926                 return handleNullHal(methodStr);
927             }
928             return mP2pIfaceHal.setWpsConfigMethods(configMethodsStr);
929         }
930     }
931 
932     /**
933      * Get NFC handover request message.
934      *
935      * @return select message if created successfully, null otherwise.
936      */
getNfcHandoverRequest()937     public String getNfcHandoverRequest() {
938         synchronized (mLock) {
939             String methodStr = "getNfcHandoverRequest";
940             if (mP2pIfaceHal == null) {
941                 handleNullHal(methodStr);
942                 return null;
943             }
944             return mP2pIfaceHal.getNfcHandoverRequest();
945         }
946     }
947 
948     /**
949      * Get NFC handover select message.
950      *
951      * @return select message if created successfully, null otherwise.
952      */
getNfcHandoverSelect()953     public String getNfcHandoverSelect() {
954         synchronized (mLock) {
955             String methodStr = "getNfcHandoverSelect";
956             if (mP2pIfaceHal == null) {
957                 handleNullHal(methodStr);
958                 return null;
959             }
960             return mP2pIfaceHal.getNfcHandoverSelect();
961         }
962     }
963 
964     /**
965      * Report NFC handover select message.
966      *
967      * @return true if reported successfully, false otherwise.
968      */
initiatorReportNfcHandover(String selectMessage)969     public boolean initiatorReportNfcHandover(String selectMessage) {
970         synchronized (mLock) {
971             String methodStr = "initiatorReportNfcHandover";
972             if (mP2pIfaceHal == null) {
973                 return handleNullHal(methodStr);
974             }
975             return mP2pIfaceHal.initiatorReportNfcHandover(selectMessage);
976         }
977     }
978 
979     /**
980      * Report NFC handover request message.
981      *
982      * @return true if reported successfully, false otherwise.
983      */
responderReportNfcHandover(String requestMessage)984     public boolean responderReportNfcHandover(String requestMessage) {
985         synchronized (mLock) {
986             String methodStr = "responderReportNfcHandover";
987             if (mP2pIfaceHal == null) {
988                 return handleNullHal(methodStr);
989             }
990             return mP2pIfaceHal.responderReportNfcHandover(requestMessage);
991         }
992     }
993 
994     /**
995      * Set the client list for the provided network.
996      *
997      * @param networkId Id of the network.
998      * @param clientListStr Space separated list of clients.
999      * @return true, if operation was successful.
1000      */
setClientList(int networkId, String clientListStr)1001     public boolean setClientList(int networkId, String clientListStr) {
1002         synchronized (mLock) {
1003             String methodStr = "setClientList";
1004             if (mP2pIfaceHal == null) {
1005                 return handleNullHal(methodStr);
1006             }
1007             return mP2pIfaceHal.setClientList(networkId, clientListStr);
1008         }
1009     }
1010 
1011     /**
1012      * Set the client list for the provided network.
1013      *
1014      * @param networkId Id of the network.
1015      * @return Space separated list of clients if successful, null otherwise.
1016      */
getClientList(int networkId)1017     public String getClientList(int networkId) {
1018         synchronized (mLock) {
1019             String methodStr = "getClientList";
1020             if (mP2pIfaceHal == null) {
1021                 handleNullHal(methodStr);
1022                 return null;
1023             }
1024             return mP2pIfaceHal.getClientList(networkId);
1025         }
1026     }
1027 
1028     /**
1029      * Persist the current configurations to disk.
1030      *
1031      * @return true, if operation was successful.
1032      */
saveConfig()1033     public boolean saveConfig() {
1034         synchronized (mLock) {
1035             String methodStr = "saveConfig";
1036             if (mP2pIfaceHal == null) {
1037                 return handleNullHal(methodStr);
1038             }
1039             return mP2pIfaceHal.saveConfig();
1040         }
1041     }
1042 
1043     /**
1044      * Enable/Disable P2P MAC randomization.
1045      *
1046      * @param enable true to enable, false to disable.
1047      * @return true, if operation was successful.
1048      */
setMacRandomization(boolean enable)1049     public boolean setMacRandomization(boolean enable) {
1050         synchronized (mLock) {
1051             String methodStr = "setMacRandomization";
1052             if (mP2pIfaceHal == null) {
1053                 return handleNullHal(methodStr);
1054             }
1055             return mP2pIfaceHal.setMacRandomization(enable);
1056         }
1057     }
1058 
1059     /**
1060      * Set Wifi Display R2 device info.
1061      *
1062      * @param info WFD R2 device info as described in section 5.1.12 of WFD technical
1063      *        specification v2.1.
1064      * @return true, if operation was successful.
1065      */
setWfdR2DeviceInfo(String info)1066     public boolean setWfdR2DeviceInfo(String info) {
1067         synchronized (mLock) {
1068             String methodStr = "setWfdR2DeviceInfo";
1069             if (mP2pIfaceHal == null) {
1070                 return handleNullHal(methodStr);
1071             }
1072             return mP2pIfaceHal.setWfdR2DeviceInfo(info);
1073         }
1074     }
1075 
1076     /**
1077      * Remove the client with the MAC address from the group.
1078      *
1079      * @param peerAddress Mac address of the client.
1080      * @param isLegacyClient Indicate if client is a legacy client or not.
1081      * @return true if success
1082      */
removeClient(String peerAddress, boolean isLegacyClient)1083     public boolean removeClient(String peerAddress, boolean isLegacyClient) {
1084         synchronized (mLock) {
1085             String methodStr = "removeClient";
1086             if (mP2pIfaceHal == null) {
1087                 return handleNullHal(methodStr);
1088             }
1089             return mP2pIfaceHal.removeClient(peerAddress, isLegacyClient);
1090         }
1091     }
1092 
1093     /**
1094      * Set vendor-specific information elements to wpa_supplicant.
1095      *
1096      * @param vendorElements The list of vendor-specific information elements.
1097      *
1098      * @return boolean The value indicating whether operation was successful.
1099      */
setVendorElements(Set<ScanResult.InformationElement> vendorElements)1100     public boolean setVendorElements(Set<ScanResult.InformationElement> vendorElements) {
1101         synchronized (mLock) {
1102             String methodStr = "setVendorElements";
1103             if (mP2pIfaceHal == null) {
1104                 return handleNullHal(methodStr);
1105             }
1106             return mP2pIfaceHal.setVendorElements(vendorElements);
1107         }
1108     }
1109 
1110     /**
1111      * Get the supported features.
1112      *
1113      * @return  bitmask defined by WifiP2pManager.FEATURE_*
1114      */
getSupportedFeatures()1115     public long getSupportedFeatures() {
1116         if (mP2pIfaceHal instanceof SupplicantP2pIfaceHalHidlImpl) return 0L;
1117         return ((SupplicantP2pIfaceHalAidlImpl) mP2pIfaceHal).getSupportedFeatures();
1118     }
1119 
handleNullHal(String methodStr)1120     private boolean handleNullHal(String methodStr) {
1121         Log.e(TAG, "Cannot call " + methodStr + " because HAL object is null.");
1122         return false;
1123     }
1124 }
1125