1 /*
2  * Copyright (C) 2017 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.bips.discovery;
18 
19 import android.net.Uri;
20 import android.net.wifi.p2p.WifiP2pDevice;
21 import android.util.Log;
22 
23 import com.android.bips.BuiltInPrintService;
24 import com.android.bips.P2pPermissionManager;
25 import com.android.bips.p2p.P2pPeerListener;
26 
27 /**
28  * Discover previously-added P2P devices, if any.
29  */
30 public class P2pDiscovery extends SavedDiscovery implements P2pPeerListener {
31     public static final String SCHEME_P2P = "p2p";
32     private static final String TAG = P2pDiscovery.class.getSimpleName();
33     private static final boolean DEBUG = false;
34 
35     private boolean mDiscoveringPeers = false;
36     private P2pPermissionManager.P2pPermissionRequest mP2pPermissionRequest;
37 
P2pDiscovery(BuiltInPrintService printService)38     public P2pDiscovery(BuiltInPrintService printService) {
39         super(printService);
40     }
41 
42     /** Convert a peer device to a debug representation */
toPrinter(WifiP2pDevice device)43     public static DiscoveredPrinter toPrinter(WifiP2pDevice device) {
44         Uri path = toPath(device);
45         String deviceName = device.deviceName;
46         if (deviceName.trim().isEmpty()) {
47             deviceName = device.deviceAddress;
48         }
49         return new DiscoveredPrinter(path, deviceName, path, null);
50     }
51 
52     /** Convert a peer device address to a Uri-based path */
toPath(WifiP2pDevice device)53     public static Uri toPath(WifiP2pDevice device) {
54         return Uri.parse(SCHEME_P2P + "://" + device.deviceAddress.replace(":", "-"));
55     }
56 
57     @Override
onStart()58     void onStart() {
59         if (DEBUG) Log.d(TAG, "onStart()");
60         startPeerDiscovery();
61     }
62 
63     @Override
onStop()64     void onStop() {
65         if (DEBUG) Log.d(TAG, "onStop()");
66         if (mP2pPermissionRequest != null) {
67             mP2pPermissionRequest.close();
68             mP2pPermissionRequest = null;
69         }
70         if (mDiscoveringPeers) {
71             mDiscoveringPeers = false;
72             getPrintService().getP2pMonitor().stopDiscover(this);
73             allPrintersLost();
74         }
75     }
76 
startPeerDiscovery()77     private void startPeerDiscovery() {
78         // Ignore if already started or no known P2P printers exist
79         if (mDiscoveringPeers || getSavedPrinters().isEmpty()) {
80             return;
81         }
82 
83         // Only begin discovery if the user has granted permissions
84         P2pPermissionManager permissionManager = getPrintService().getP2pPermissionManager();
85         mP2pPermissionRequest = permissionManager.request(true, approved -> {
86             if (approved) {
87                 mDiscoveringPeers = true;
88                 getPrintService().getP2pMonitor().discover(this);
89             }
90             mP2pPermissionRequest = null;
91         });
92     }
93 
94     @Override
onPeerFound(WifiP2pDevice peer)95     public void onPeerFound(WifiP2pDevice peer) {
96         DiscoveredPrinter printer = toPrinter(peer);
97         if (DEBUG) Log.d(TAG, "onPeerFound " + printer);
98 
99         // Only find saved printers
100         for (DiscoveredPrinter saved : getSavedPrinters()) {
101             if (saved.path.equals(printer.path)) {
102                 printerFound(saved);
103             }
104         }
105     }
106 
107     @Override
onPeerLost(WifiP2pDevice peer)108     public void onPeerLost(WifiP2pDevice peer) {
109         DiscoveredPrinter printer = toPrinter(peer);
110         if (DEBUG) Log.d(TAG, "onPeerLost " + printer);
111         printerLost(printer.getUri());
112     }
113 
114     /** Adds a known, P2P-discovered, valid printer */
addValidPrinter(DiscoveredPrinter printer)115     public void addValidPrinter(DiscoveredPrinter printer) {
116         if (addSavedPrinter(printer)) {
117             printerFound(printer);
118             if (isStarted()) {
119                 startPeerDiscovery();
120             }
121         }
122     }
123 }
124