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.InetSocketAddress; 29 import java.net.Socket; 30 import java.util.concurrent.locks.Lock; 31 import java.util.concurrent.locks.ReentrantLock; 32 33 /** A background task that queries a specific URI for its complete capabilities */ 34 class GetCapabilitiesTask extends AsyncTask<Void, Void, LocalPrinterCapabilities> { 35 private static final String TAG = GetCapabilitiesTask.class.getSimpleName(); 36 private static final boolean DEBUG = false; 37 38 /** Lock to ensure we don't issue multiple simultaneous capability requests */ 39 private static final Lock sJniLock = new ReentrantLock(); 40 41 /** Amount of time before giving up on the "online" check for printer */ 42 private static final int ONLINE_TIMEOUT_MILLIS = 6000; 43 44 private final Backend mBackend; 45 private final Uri mUri; 46 GetCapabilitiesTask(Backend backend, Uri uri)47 GetCapabilitiesTask(Backend backend, Uri uri) { 48 mUri = uri; 49 mBackend = backend; 50 } 51 isDeviceOnline(Uri uri)52 private static boolean isDeviceOnline(Uri uri) { 53 try (Socket socket = new Socket()) { 54 InetSocketAddress a = new InetSocketAddress(uri.getHost(), uri.getPort()); 55 socket.connect(a, ONLINE_TIMEOUT_MILLIS); 56 return true; 57 } catch (IOException e) { 58 return false; 59 } 60 } 61 62 @Override doInBackground(Void... dummy)63 protected LocalPrinterCapabilities doInBackground(Void... dummy) { 64 long start = System.currentTimeMillis(); 65 66 LocalPrinterCapabilities printerCaps = new LocalPrinterCapabilities(); 67 boolean online = isDeviceOnline(mUri); 68 if (DEBUG) { 69 Log.d(TAG, "isDeviceOnline uri=" + mUri + " online=" + online + 70 " (" + (System.currentTimeMillis() - start) + "ms)"); 71 } 72 73 if (!online) return null; 74 75 // Do not permit more than a single call to this API or crashes may result 76 sJniLock.lock(); 77 int status = -1; 78 start = System.currentTimeMillis(); 79 try { 80 status = mBackend.nativeGetCapabilities(Backend.getIp(mUri.getHost()), 81 mUri.getPort(), mUri.getPath(), mUri.getScheme(), printerCaps); 82 } finally { 83 sJniLock.unlock(); 84 } 85 86 if (DEBUG) { 87 Log.d(TAG, "callNativeGetCapabilities uri=" + mUri + " status=" + status + 88 " (" + (System.currentTimeMillis() - start) + "ms)"); 89 } 90 91 return status == BackendConstants.STATUS_OK ? printerCaps : null; 92 } 93 }