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