Home | History | Annotate | Download | only in ipp
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  * Copyright (C) 2016 Mopria Alliance, Inc.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.bips.ipp;
     19 
     20 import android.net.Uri;
     21 import android.os.AsyncTask;
     22 import android.util.Log;
     23 
     24 import com.android.bips.jni.BackendConstants;
     25 import com.android.bips.jni.LocalPrinterCapabilities;
     26 
     27 import java.io.IOException;
     28 import java.net.InetAddress;
     29 import java.net.InetSocketAddress;
     30 import java.net.Socket;
     31 import java.net.UnknownHostException;
     32 import java.util.concurrent.locks.Lock;
     33 import java.util.concurrent.locks.ReentrantLock;
     34 
     35 /** A background task that queries a specific URI for its complete capabilities */
     36 class GetCapabilitiesTask extends AsyncTask<Void, Void, LocalPrinterCapabilities> {
     37     private static final String TAG = GetCapabilitiesTask.class.getSimpleName();
     38     private static final boolean DEBUG = false;
     39 
     40     /** Lock to ensure we don't issue multiple simultaneous capability requests */
     41     private static final Lock sJniLock = new ReentrantLock();
     42 
     43     private final Backend mBackend;
     44     private final Uri mUri;
     45     private final long mTimeout;
     46 
     47     GetCapabilitiesTask(Backend backend, Uri uri, long timeout) {
     48         mUri = uri;
     49         mBackend = backend;
     50         mTimeout = timeout;
     51     }
     52 
     53     private boolean isDeviceOnline(Uri uri) {
     54         try (Socket socket = new Socket()) {
     55             InetSocketAddress a = new InetSocketAddress(uri.getHost(), uri.getPort());
     56             socket.connect(a, (int) mTimeout);
     57             return true;
     58         } catch (IOException e) {
     59             return false;
     60         }
     61     }
     62 
     63     @Override
     64     protected LocalPrinterCapabilities doInBackground(Void... dummy) {
     65         long start = System.currentTimeMillis();
     66 
     67         LocalPrinterCapabilities printerCaps = new LocalPrinterCapabilities();
     68         try {
     69             printerCaps.inetAddress = InetAddress.getByName(mUri.getHost());
     70         } catch (UnknownHostException e) {
     71             return null;
     72         }
     73 
     74         boolean online = isDeviceOnline(mUri);
     75         if (DEBUG) {
     76             Log.d(TAG, "isDeviceOnline uri=" + mUri + " online=" + online +
     77                     " (" + (System.currentTimeMillis() - start) + "ms)");
     78         }
     79 
     80         if (!online || isCancelled()) return null;
     81 
     82         // Do not permit more than a single call to this API or crashes may result
     83         sJniLock.lock();
     84         int status = -1;
     85         start = System.currentTimeMillis();
     86         try {
     87             if (isCancelled()) return null;
     88             status = mBackend.nativeGetCapabilities(Backend.getIp(mUri.getHost()),
     89                     mUri.getPort(), mUri.getPath(), mUri.getScheme(), mTimeout, printerCaps);
     90         } finally {
     91             sJniLock.unlock();
     92         }
     93 
     94         if (DEBUG) {
     95             Log.d(TAG, "callNativeGetCapabilities uri=" + mUri + " status=" + status +
     96                     " (" + (System.currentTimeMillis() - start) + "ms)");
     97         }
     98 
     99         return status == BackendConstants.STATUS_OK ? printerCaps : null;
    100     }
    101 }