Home | History | Annotate | Download | only in ui
      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.ui;
     18 
     19 import android.Manifest;
     20 import android.content.ComponentName;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.ServiceConnection;
     24 import android.content.pm.PackageManager;
     25 import android.net.Uri;
     26 import android.net.wifi.p2p.WifiP2pDevice;
     27 import android.os.Bundle;
     28 import android.os.IBinder;
     29 import android.preference.Preference;
     30 import android.preference.PreferenceCategory;
     31 import android.preference.PreferenceFragment;
     32 import android.util.Log;
     33 
     34 import com.android.bips.BuiltInPrintService;
     35 import com.android.bips.R;
     36 import com.android.bips.discovery.DiscoveredPrinter;
     37 import com.android.bips.discovery.P2pDiscovery;
     38 import com.android.bips.p2p.P2pMonitor;
     39 import com.android.bips.p2p.P2pPeerListener;
     40 
     41 /**
     42  * Present a list of previously-saved printers, and allow them to be removed
     43  */
     44 public class FindP2pPrintersFragment extends PreferenceFragment implements ServiceConnection,
     45         AddPrintersActivity.OnPermissionChangeListener {
     46     private static final String TAG = FindP2pPrintersFragment.class.getSimpleName();
     47     private static final boolean DEBUG = false;
     48 
     49     private static final String KEY_AVAILABLE = "available";
     50     private static final int REQUEST_PERMISSION = 1;
     51 
     52     private BuiltInPrintService mPrintService;
     53     private P2pListener mPeerDiscoveryListener;
     54     private PreferenceCategory mAvailableCategory;
     55 
     56     @Override
     57     public void onCreate(Bundle savedInstanceState) {
     58         super.onCreate(savedInstanceState);
     59         addPreferencesFromResource(R.xml.find_p2p_prefs);
     60         mAvailableCategory = (PreferenceCategory) getPreferenceScreen()
     61                 .findPreference(KEY_AVAILABLE);
     62     }
     63 
     64     @Override
     65     public void onStart() {
     66         super.onStart();
     67         if (DEBUG) Log.d(TAG, "onStart");
     68         getActivity().setTitle(R.string.wifi_direct_printers);
     69         getContext().bindService(new Intent(getContext(), BuiltInPrintService.class), this,
     70                 Context.BIND_AUTO_CREATE);
     71     }
     72 
     73     @Override
     74     public void onStop() {
     75         super.onStop();
     76         if (DEBUG) Log.d(TAG, "onStop");
     77         if (mPeerDiscoveryListener != null) {
     78             mPrintService.getP2pMonitor().stopDiscover(mPeerDiscoveryListener);
     79             mPeerDiscoveryListener = null;
     80         }
     81         getContext().unbindService(this);
     82         mPrintService = null;
     83     }
     84 
     85     @Override
     86     public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
     87         if (DEBUG) Log.d(TAG, "onServiceConnected");
     88         mPrintService = BuiltInPrintService.getInstance();
     89         if (mPrintService == null) {
     90             return;
     91         }
     92 
     93         // If we do not yet have permissions, ask.
     94         if (getContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
     95                 != PackageManager.PERMISSION_GRANTED) {
     96             getActivity().requestPermissions(
     97                     new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
     98                     REQUEST_PERMISSION);
     99         } else {
    100             startP2pDiscovery();
    101         }
    102     }
    103 
    104     private void startP2pDiscovery() {
    105         if (mPrintService != null && mPeerDiscoveryListener == null) {
    106             mPeerDiscoveryListener = new P2pListener();
    107             mPrintService.getP2pMonitor().discover(mPeerDiscoveryListener);
    108         }
    109     }
    110 
    111     @Override
    112     public void onPermissionChange() {
    113         // P2P discovery requires dangerous ACCESS_COARSE_LOCATION
    114         if (getContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
    115                 == PackageManager.PERMISSION_GRANTED) {
    116             startP2pDiscovery();
    117         } else {
    118             // Wind back out of this fragment
    119             getActivity().onBackPressed();
    120         }
    121     }
    122 
    123     @Override
    124     public void onServiceDisconnected(ComponentName componentName) {
    125         mPrintService = null;
    126     }
    127 
    128     /** Handle discovered P2P printers */
    129     private class P2pListener implements P2pPeerListener {
    130         @Override
    131         public void onPeerFound(WifiP2pDevice peer) {
    132             if (DEBUG) Log.d(TAG, "onPeerFound: " + P2pMonitor.toString(peer));
    133             if (mPrintService == null) {
    134                 return;
    135             }
    136 
    137             DiscoveredPrinter printer = P2pDiscovery.toPrinter(peer);
    138 
    139             // Ignore printers we have already added
    140             for (DiscoveredPrinter prior : mPrintService.getP2pDiscovery().getSavedPrinters()) {
    141                 if (prior.path.equals(printer.path)) {
    142                     return;
    143                 }
    144             }
    145 
    146             // Install a preference so the user can add this printer
    147             PrinterPreference pref = getPrinterPreference(printer.getUri());
    148             if (pref != null) {
    149                 pref.updatePrinter(printer);
    150             } else {
    151                 pref = new PrinterPreference(getContext(), mPrintService, printer, true);
    152                 pref.setOnPreferenceClickListener(preference -> {
    153                     if (DEBUG) Log.d(TAG, "add " + P2pDiscovery.toPrinter(peer));
    154                     new AddP2pPrinterDialog(FindP2pPrintersFragment.this, mPrintService, peer)
    155                             .show();
    156                     return true;
    157                 });
    158                 mAvailableCategory.addPreference(pref);
    159             }
    160         }
    161 
    162         @Override
    163         public void onPeerLost(WifiP2pDevice peer) {
    164             if (DEBUG) Log.d(TAG, "onPeerLost: " + P2pMonitor.toString(peer));
    165             if (mPrintService == null) {
    166                 return;
    167             }
    168 
    169             DiscoveredPrinter printer = P2pDiscovery.toPrinter(peer);
    170 
    171             // Remove this preference because the printer is no longer available
    172             PrinterPreference pref = getPrinterPreference(printer.path);
    173             if (pref != null) {
    174                 mAvailableCategory.removePreference(pref);
    175             }
    176         }
    177 
    178         private PrinterPreference getPrinterPreference(Uri printerPath) {
    179             for (int i = 0; i < mAvailableCategory.getPreferenceCount(); i++) {
    180                 Preference pref = mAvailableCategory.getPreference(i);
    181                 if (pref instanceof PrinterPreference
    182                         && ((PrinterPreference) pref).getPrinter().path.equals(printerPath)) {
    183                     return (PrinterPreference) pref;
    184                 }
    185             }
    186             return null;
    187         }
    188     }
    189 }
    190