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 import com.android.bips.util.PriorityLock; 27 28 import java.io.IOException; 29 import java.net.InetAddress; 30 import java.net.InetSocketAddress; 31 import java.net.Socket; 32 import java.net.UnknownHostException; 33 34 /** A background task that queries a specific URI for its complete capabilities */ 35 public class GetCapabilitiesTask extends AsyncTask<Void, Void, LocalPrinterCapabilities> { 36 private static final String TAG = GetCapabilitiesTask.class.getSimpleName(); 37 private static final boolean DEBUG = false; 38 39 /** Lock to ensure we don't issue multiple simultaneous capability requests */ 40 private static final PriorityLock sLock = new PriorityLock(); 41 42 private final Backend mBackend; 43 private final Uri mUri; 44 private final long mTimeout; 45 private final boolean mPriority; 46 private volatile Socket mSocket; 47 GetCapabilitiesTask(Backend backend, Uri uri, long timeout, boolean priority)48 GetCapabilitiesTask(Backend backend, Uri uri, long timeout, boolean priority) { 49 mUri = uri; 50 mBackend = backend; 51 mTimeout = timeout; 52 mPriority = priority; 53 } 54 isDeviceOnline(Uri uri)55 private boolean isDeviceOnline(Uri uri) { 56 try (Socket socket = new Socket()) { 57 mSocket = socket; 58 InetSocketAddress a = new InetSocketAddress(uri.getHost(), uri.getPort()); 59 socket.connect(a, (int) mTimeout); 60 return true; 61 } catch (IOException e) { 62 return false; 63 } finally { 64 mSocket = null; 65 } 66 } 67 68 /** Forcibly cancel this task, including stopping any socket that was opened */ forceCancel()69 public void forceCancel() { 70 cancel(true); 71 Socket socket = mSocket; 72 if (socket != null) { 73 try { 74 socket.close(); 75 } catch (IOException e) { 76 // Ignored 77 } 78 } 79 } 80 81 @Override doInBackground(Void... dummy)82 protected LocalPrinterCapabilities doInBackground(Void... dummy) { 83 long start = System.currentTimeMillis(); 84 85 LocalPrinterCapabilities printerCaps = new LocalPrinterCapabilities(); 86 try { 87 printerCaps.inetAddress = InetAddress.getByName(mUri.getHost()); 88 } catch (UnknownHostException e) { 89 return null; 90 } 91 92 boolean online = isDeviceOnline(mUri); 93 if (DEBUG) { 94 Log.d(TAG, "isDeviceOnline uri=" + mUri + " online=" + online 95 + " (" + (System.currentTimeMillis() - start) + "ms)"); 96 } 97 98 if (!online || isCancelled()) { 99 return null; 100 } 101 102 // Do not permit more than a single call to this API or crashes may result 103 try { 104 // Always allow priority capability requests to execute first 105 sLock.lock(mPriority ? 1 : 0); 106 } catch (InterruptedException e) { 107 return null; 108 } 109 int status = -1; 110 start = System.currentTimeMillis(); 111 try { 112 if (isCancelled()) { 113 return null; 114 } 115 status = mBackend.nativeGetCapabilities(Backend.getIp(mUri.getHost()), 116 mUri.getPort(), mUri.getPath(), mUri.getScheme(), mTimeout, printerCaps); 117 } finally { 118 sLock.unlock(); 119 } 120 121 if (DEBUG) { 122 Log.d(TAG, "callNativeGetCapabilities uri=" + mUri + " status=" + status 123 + " (" + (System.currentTimeMillis() - start) + "ms)"); 124 } 125 126 return status == BackendConstants.STATUS_OK ? printerCaps : null; 127 } 128 } 129