summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-10-09 19:07:14 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-10-09 19:07:14 +0000
commit03fdbfec7eebf0b6b531f60843c0d292fd92cf2e (patch)
tree0a9f28c75e0bfefcd9a85a52ef2ed3ac25cfc947
parentcdd3884381797ebb7f41dd263aaa5a10ff499cca (diff)
parent4269b06f671107ac0ac88cfa9a92e937e2e18706 (diff)
downloadBuiltInPrintService-oreo-m2-s3-release.tar.gz
Change-Id: I62fe7788181800dd4d55b99be8a466f60acd1c83
-rw-r--r--jni/include/ifc_print_job.h2
-rw-r--r--jni/include/lib_wprint.h2
-rw-r--r--jni/ipphelper/ipp_print.c17
-rw-r--r--jni/ipphelper/ipphelper.c11
-rw-r--r--jni/ipphelper/ipphelper.h3
-rw-r--r--jni/lib/lib_wprint.c15
-rw-r--r--jni/lib/printer.c2
-rw-r--r--jni/lib/wprintJNI.c6
-rw-r--r--src/com/android/bips/discovery/MdnsDiscovery.java100
-rw-r--r--src/com/android/bips/ipp/Backend.java3
-rw-r--r--src/com/android/bips/ipp/StartJobTask.java2
11 files changed, 130 insertions, 33 deletions
diff --git a/jni/include/ifc_print_job.h b/jni/include/ifc_print_job.h
index 1efaf45..0c0fc2a 100644
--- a/jni/include/ifc_print_job.h
+++ b/jni/include/ifc_print_job.h
@@ -29,7 +29,7 @@ typedef struct ifc_print_job_st {
* Initializes print job handle with given connection params.
*/
status_t (*init)(const struct ifc_print_job_st *this_p, const char *printer_address, int port,
- const char *printer_uri);
+ const char *printer_uri, bool use_secure_uri);
/*
* Validates job and connection params, updating parameters as necessary.
diff --git a/jni/include/lib_wprint.h b/jni/include/lib_wprint.h
index 3703a3d..006f6c1 100644
--- a/jni/include/lib_wprint.h
+++ b/jni/include/lib_wprint.h
@@ -292,7 +292,7 @@ status_t wprintGetFinalJobParams(wprint_job_params_t *job_param,
wJob_t wprintStartJob(const char *printer_addr, port_t port_num,
const wprint_job_params_t *job_params, const printer_capabilities_t *printer_cap,
const char *mime_type, const char *pathname, wprint_status_cb_t cb_fn,
- const char *debugDir);
+ const char *debugDir, const char *scheme);
/*
* Sent once per job at the end of the job. A current print job must end for the next one
diff --git a/jni/ipphelper/ipp_print.c b/jni/ipphelper/ipp_print.c
index 3bcc0bb..57914b3 100644
--- a/jni/ipphelper/ipp_print.c
+++ b/jni/ipphelper/ipp_print.c
@@ -26,7 +26,7 @@
#define TAG "ipp_print"
static status_t _init(const ifc_print_job_t *this_p, const char *printer_address, int port,
- const char *printer_uri);
+ const char *printer_uri, bool use_secure_uri);
static status_t _validate_job(const ifc_print_job_t *this_p, wprint_job_params_t *job_params);
@@ -75,7 +75,7 @@ const ifc_print_job_t *ipp_get_print_ifc(const ifc_wprint_t *wprint_ifc) {
}
static status_t _init(const ifc_print_job_t *this_p, const char *printer_address, int port,
- const char *printer_uri) {
+ const char *printer_uri, bool use_secure_uri) {
LOGD("_init: Enter");
ipp_print_job_t *ipp_job;
const char *ipp_scheme;
@@ -95,12 +95,21 @@ static status_t _init(const ifc_print_job_t *this_p, const char *printer_address
int ippPortNumber = ((port == IPP_PORT) ? ippPort() : port);
LOGD("Normal URI for %s:%d", printer_address, ippPortNumber);
- ipp_scheme = IPP_PREFIX;
+ ipp_scheme = (use_secure_uri) ? IPPS_PREFIX : IPP_PREFIX;
httpAssembleURIf(HTTP_URI_CODING_ALL, ipp_job->printer_uri, sizeof(ipp_job->printer_uri),
ipp_scheme, NULL, printer_address, ippPortNumber, printer_uri);
getResourceFromURI(ipp_job->printer_uri, ipp_job->http_resource, 1024);
- ipp_job->http = httpConnect(printer_address, ippPortNumber);
+ if (use_secure_uri) {
+ ipp_job->http = httpConnectEncrypt(printer_address, ippPortNumber, HTTP_ENCRYPTION_ALWAYS);
+
+ // If ALWAYS doesn't work, fall back to REQUIRED
+ if (ipp_job->http == NULL) {
+ ipp_job->http = httpConnectEncrypt(printer_address, ippPortNumber, HTTP_ENCRYPT_REQUIRED);
+ }
+ } else {
+ ipp_job->http = httpConnectEncrypt(printer_address, ippPortNumber, HTTP_ENCRYPTION_IF_REQUESTED);
+ }
httpSetTimeout(ipp_job->http, DEFAULT_IPP_TIMEOUT, NULL, 0);
diff --git a/jni/ipphelper/ipphelper.c b/jni/ipphelper/ipphelper.c
index 2b16ed3..bbe484e 100644
--- a/jni/ipphelper/ipphelper.c
+++ b/jni/ipphelper/ipphelper.c
@@ -1425,7 +1425,16 @@ http_t *ipp_cups_connect(const wprint_connect_info_t *connect_info, char *printe
int ippPortNumber = ((connect_info->port_num == IPP_PORT) ? ippPort() : connect_info->port_num);
- curl_http = httpConnect(connect_info->printer_addr, ippPortNumber);
+ if (strstr(connect_info->uri_scheme,IPPS_PREFIX) != NULL) {
+ curl_http = httpConnectEncrypt(connect_info->printer_addr, ippPortNumber, HTTP_ENCRYPTION_ALWAYS);
+
+ // If ALWAYS doesn't work, fall back to REQUIRED
+ if (curl_http == NULL) {
+ curl_http = httpConnectEncrypt(connect_info->printer_addr, ippPortNumber, HTTP_ENCRYPT_REQUIRED);
+ }
+ } else {
+ curl_http = httpConnectEncrypt(connect_info->printer_addr, ippPortNumber, HTTP_ENCRYPTION_IF_REQUESTED);
+ }
httpSetTimeout(curl_http, (double)connect_info->timeout / 1000, NULL, 0);
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, uriLength, connect_info->uri_scheme, NULL,
diff --git a/jni/ipphelper/ipphelper.h b/jni/ipphelper/ipphelper.h
index 15bd26a..bd93741 100644
--- a/jni/ipphelper/ipphelper.h
+++ b/jni/ipphelper/ipphelper.h
@@ -145,10 +145,11 @@ http_t *ipp_cups_connect(const wprint_connect_info_t *info, char *printer_uri,
ipp_t *ipp_doCupsRequest(http_t *http, ipp_t *request, char *http_resource, char *printer_uri);
#define IPP_PREFIX "ipp"
+#define IPPS_PREFIX "ipps"
#define DEFAULT_IPP_URI_RESOURCE "/ipp/print"
#ifdef __cplusplus
}
#endif // __cplusplus
-#endif // !_IPP_HELPER_H_ \ No newline at end of file
+#endif // !_IPP_HELPER_H_
diff --git a/jni/lib/lib_wprint.c b/jni/lib/lib_wprint.c
index d905d86..e7aebfe 100644
--- a/jni/lib/lib_wprint.c
+++ b/jni/lib/lib_wprint.c
@@ -147,6 +147,7 @@ typedef struct {
wprint_job_params_t job_params;
bool cancel_ok;
+ bool use_secure_uri;
const ifc_status_monitor_t *status_ifc;
char debug_path[MAX_PATHNAME_LENGTH + 1];
@@ -740,7 +741,11 @@ static void *_job_thread(void *param) {
connect_info.printer_addr = jq->printer_addr;
connect_info.uri_path = jq->printer_uri;
connect_info.port_num = jq->port_num;
- connect_info.uri_scheme = IPP_PREFIX;
+ if (jq->use_secure_uri) {
+ connect_info.uri_scheme = IPPS_PREFIX;
+ } else {
+ connect_info.uri_scheme = IPP_PREFIX;
+ }
connect_info.timeout = DEFAULT_IPP_TIMEOUT;
jq->status_ifc->init(jq->status_ifc, &connect_info);
}
@@ -835,7 +840,7 @@ static void *_job_thread(void *param) {
if (job_result == OK) {
if (jq->print_ifc) {
job_result = jq->print_ifc->init(jq->print_ifc, jq->printer_addr,
- jq->port_num, jq->printer_uri);
+ jq->port_num, jq->printer_uri, jq->use_secure_uri);
if (job_result == ERROR) {
jq->blocked_reasons = BLOCKED_REASON_UNABLE_TO_CONNECT;
}
@@ -1727,7 +1732,7 @@ status_t wprintGetFinalJobParams(wprint_job_params_t *job_params,
wJob_t wprintStartJob(const char *printer_addr, port_t port_num,
const wprint_job_params_t *job_params, const printer_capabilities_t *printer_cap,
const char *mime_type, const char *pathname, wprint_status_cb_t cb_fn,
- const char *debugDir) {
+ const char *debugDir, const char *scheme) {
wJob_t job_handle = WPRINT_BAD_JOB_HANDLE;
_msg_t msg;
struct stat stat_buf;
@@ -1810,6 +1815,8 @@ wJob_t wprintStartJob(const char *printer_addr, port_t port_num,
memcpy((char *) &(jq->job_params), job_params, sizeof(wprint_job_params_t));
+ jq->use_secure_uri = (strstr(scheme, IPPS_PREFIX) != NULL);
+
size_t useragent_len = strlen(USERAGENT_PREFIX) + strlen(jq->job_params.docCategory) + 1;
char *useragent = (char *) malloc(useragent_len);
if (useragent != NULL) {
@@ -2111,4 +2118,4 @@ void wprintSetSourceInfo(const char *appName, const char *appVersion, const char
}
LOGI("App Name: '%s', Version: '%s', OS: '%s'", g_appName, g_appVersion, g_osName);
-} \ No newline at end of file
+}
diff --git a/jni/lib/printer.c b/jni/lib/printer.c
index 2ae0d7a..55eca67 100644
--- a/jni/lib/printer.c
+++ b/jni/lib/printer.c
@@ -45,7 +45,7 @@ typedef struct {
static long int _wprint_timeout_msec = DEFAULT_TIMEOUT;
static status_t _init(const ifc_print_job_t *this_p, const char *printer_addr, int port,
- const char *printer_uri) {
+ const char *printer_uri, bool use_secure_uri) {
_print_job_t *print_job = IMPL(_print_job_t, ifc, this_p);
if (!print_job) return ERROR;
diff --git a/jni/lib/wprintJNI.c b/jni/lib/wprintJNI.c
index 1dbddb8..913198a 100644
--- a/jni/lib/wprintJNI.c
+++ b/jni/lib/wprintJNI.c
@@ -1227,7 +1227,7 @@ JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeGetFinalJobParame
*/
JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeStartJob(
JNIEnv *env, jobject obj, jstring address, jint port, jstring mimeType, jobject jobParams,
- jobject printerCaps, jobject fileArray, jstring jobDebugDir) {
+ jobject printerCaps, jobject fileArray, jstring jobDebugDir, jstring scheme) {
LOGI("nativeStartJob, JNIenv is %p", env);
jint result = ERROR;
wJob_t job_handle = ERROR;
@@ -1245,6 +1245,7 @@ JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeStartJob(
const char *addressStr = (*env)->GetStringUTFChars(env, address, NULL);
const char *mimeTypeStr = (*env)->GetStringUTFChars(env, mimeType, NULL);
const char *dataDirStr = (*env)->GetStringUTFChars(env, _fakeDir, NULL);
+ const char *schemeStr = (*env)->GetStringUTFChars(env, scheme, NULL);
jsize len = 0;
jobjectArray array;
@@ -1309,7 +1310,7 @@ JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeStartJob(
jobDebugDirStr = (*env)->GetStringUTFChars(env, jobDebugDir, NULL);
}
result = wprintStartJob(addressStr, port, &params, &caps, (char *) mimeTypeStr,
- (char *) dataDirStr, _wprint_callback_fn, jobDebugDirStr);
+ (char *) dataDirStr, _wprint_callback_fn, jobDebugDirStr, schemeStr);
if (result == ERROR) {
LOGE("failed to start job: error code :%d", errno);
}
@@ -1362,6 +1363,7 @@ JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeStartJob(
(*env)->ReleaseStringUTFChars(env, mimeType, mimeTypeStr);
(*env)->ReleaseStringUTFChars(env, address, addressStr);
(*env)->ReleaseStringUTFChars(env, _fakeDir, dataDirStr);
+ (*env)->ReleaseStringUTFChars(env, scheme, schemeStr);
return job_handle;
}
diff --git a/src/com/android/bips/discovery/MdnsDiscovery.java b/src/com/android/bips/discovery/MdnsDiscovery.java
index fddffed..cfb334c 100644
--- a/src/com/android/bips/discovery/MdnsDiscovery.java
+++ b/src/com/android/bips/discovery/MdnsDiscovery.java
@@ -28,8 +28,11 @@ import android.util.Log;
import com.android.bips.BuiltInPrintService;
import java.net.Inet4Address;
+import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
/**
* Search the local network for devices advertising IPP print services
@@ -37,6 +40,7 @@ import java.util.Map;
public class MdnsDiscovery extends Discovery {
private static final String TAG = MdnsDiscovery.class.getSimpleName();
private static final boolean DEBUG = false;
+ private static final long IPPS_DELAY = 150;
// Prepend this to a UUID to create a proper URN
private static final String PREFIX_URN_UUID = "urn:uuid:";
@@ -49,7 +53,11 @@ public class MdnsDiscovery extends Discovery {
private static final String VALUE_PRINT_WFDS_OPT_OUT = "F";
// Service name of interest
- private static final String SERVICE_IPP = "_ipp._tcp";
+ private static final String SERVICE_IPP = "_ipp._tcp";
+ private static final String SERVICE_IPPS = "_ipps._tcp";
+
+ private static final String SCHEME_IPP = "ipp";
+ private static final String SCHEME_IPPS = "ipps";
/** Network Service Discovery Manager */
private final NsdManager mNsdManager;
@@ -58,7 +66,10 @@ public class MdnsDiscovery extends Discovery {
private final Handler mMainHandler;
/** Handle to listener when registered */
- private NsdServiceListener mServiceListener;
+ private NsdServiceListener mIppServiceListener;
+ private NsdServiceListener mIppsServiceListener;
+
+ private Map<Uri, IppsDelay> mIppsDelays = new HashMap<>();
public MdnsDiscovery(BuiltInPrintService printService) {
this(printService, (NsdManager) printService.getSystemService(Context.NSD_SERVICE));
@@ -102,8 +113,9 @@ public class MdnsDiscovery extends Discovery {
return null;
}
- Uri path = Uri.parse("ipp://" + info.getHost().getHostAddress() +
- ":" + info.getPort() + "/" + resourcePath);
+ String scheme = info.getServiceType().contains(SERVICE_IPPS) ? SCHEME_IPPS : SCHEME_IPP;
+ Uri path = Uri.parse(scheme + "://" + info.getHost().getHostAddress() + ":" + info.getPort() + "/" +
+ resourcePath);
String location = getStringAttribute(info, ATTRIBUTE_NOTE);
return new DiscoveredPrinter(uuidUri, info.getServiceName(), path, location);
@@ -123,18 +135,44 @@ public class MdnsDiscovery extends Discovery {
@Override
void onStart() {
if (DEBUG) Log.d(TAG, "onStart()");
- mServiceListener = new NsdServiceListener();
- mNsdManager.discoverServices(SERVICE_IPP, NsdManager.PROTOCOL_DNS_SD, mServiceListener);
+ mIppServiceListener = new NsdServiceListener() {
+ @Override
+ public void onStartDiscoveryFailed(String s, int i) {
+ mIppServiceListener = null;
+ }
+ };
+
+ mNsdManager.discoverServices(SERVICE_IPP, NsdManager.PROTOCOL_DNS_SD, mIppServiceListener);
+
+ mIppsServiceListener = new NsdServiceListener() {
+ @Override
+ public void onStartDiscoveryFailed(String s, int i) {
+ mIppServiceListener = null;
+ }
+ };
+ mNsdManager.discoverServices(SERVICE_IPPS, NsdManager.PROTOCOL_DNS_SD, mIppsServiceListener);
}
@Override
void onStop() {
if (DEBUG) Log.d(TAG, "onStop()");
- if (mServiceListener != null) {
- mNsdManager.stopServiceDiscovery(mServiceListener);
- mServiceListener = null;
+ NsdResolveQueue.getInstance(getPrintService()).clear();
+ for (IppsDelay ippsDelay : mIppsDelays.values()) {
+ mMainHandler.removeCallbacks(ippsDelay);
+ }
+ mIppsDelays.clear();
+
+ if (mIppServiceListener != null) {
+ mNsdManager.stopServiceDiscovery(mIppServiceListener);
+ mIppServiceListener = null;
+ }
+
+ if (mIppsServiceListener != null) {
+ mNsdManager.stopServiceDiscovery(mIppsServiceListener);
+ mIppsServiceListener = null;
}
+
mMainHandler.removeCallbacksAndMessages(null);
NsdResolveQueue.getInstance(getPrintService()).clear();
}
@@ -142,13 +180,8 @@ public class MdnsDiscovery extends Discovery {
/**
* Manage notifications from NsdManager
*/
- private class NsdServiceListener implements NsdManager.DiscoveryListener,
+ private abstract class NsdServiceListener implements NsdManager.DiscoveryListener,
NsdManager.ResolveListener {
- @Override
- public void onStartDiscoveryFailed(String serviceType, int errorCode) {
- Log.w(TAG, "onStartDiscoveryFailed: " + errorCode);
- mServiceListener = null;
- }
@Override
public void onStopDiscoveryFailed(String s, int errorCode) {
@@ -182,6 +215,7 @@ public class MdnsDiscovery extends Discovery {
mMainHandler.post(() -> {
for (DiscoveredPrinter printer : getPrinters()) {
if (TextUtils.equals(printer.name, info.getServiceName())) {
+ cancelIppsDelay(printer.getUri());
printerLost(printer.getUri());
return;
}
@@ -201,7 +235,41 @@ public class MdnsDiscovery extends Discovery {
return;
}
+ Uri printerUri = printer.getUri();
+ if (printer.path.getScheme().equals(SCHEME_IPPS)) {
+ DiscoveredPrinter oldPrinter = getPrinter(printerUri);
+ IppsDelay ippsDelay = mIppsDelays.get(printerUri);
+ if (oldPrinter == null && ippsDelay == null) {
+ // This IPPS printer is not known yet so delay a short time to see if IPP arrives
+ mIppsDelays.put(printerUri, new IppsDelay(printer));
+ }
+ return;
+ } else {
+ // IPP discovered, so cancel any outstanding IPPS delay
+ cancelIppsDelay(printerUri);
+ }
+
mMainHandler.post(() -> printerFound(printer));
}
}
-} \ No newline at end of file
+
+ private void cancelIppsDelay(Uri printerUri) {
+ IppsDelay ippsDelay = mIppsDelays.get(printerUri);
+ mMainHandler.removeCallbacks(ippsDelay);
+ mIppsDelays.remove(printerUri);
+ }
+
+ private class IppsDelay implements Runnable {
+ final DiscoveredPrinter printer;
+
+ IppsDelay(DiscoveredPrinter printer) {
+ this.printer = printer;
+ mMainHandler.postDelayed(this, IPPS_DELAY);
+ }
+
+ @Override
+ public void run() {
+ printerFound(printer);
+ }
+ }
+}
diff --git a/src/com/android/bips/ipp/Backend.java b/src/com/android/bips/ipp/Backend.java
index ef0c722..d089012 100644
--- a/src/com/android/bips/ipp/Backend.java
+++ b/src/com/android/bips/ipp/Backend.java
@@ -301,10 +301,11 @@ public class Backend implements JobCallback {
* @param capabilities printer capabilities for the printer being used
* @param fileList list of files to be provided of the given MIME type
* @param debugDir directory to receive debugging information, if any
+ * @param scheme URI scheme (e.g. ipp/ipps)
* @return {@link BackendConstants#STATUS_OK} or an error code.
*/
native int nativeStartJob(String address, int port, String mime_type, LocalJobParams jobParams,
- LocalPrinterCapabilities capabilities, String[] fileList, String debugDir);
+ LocalPrinterCapabilities capabilities, String[] fileList, String debugDir, String scheme);
/**
* Request cancellation of the identified job.
diff --git a/src/com/android/bips/ipp/StartJobTask.java b/src/com/android/bips/ipp/StartJobTask.java
index 1e1355b..0cbfa3f 100644
--- a/src/com/android/bips/ipp/StartJobTask.java
+++ b/src/com/android/bips/ipp/StartJobTask.java
@@ -167,7 +167,7 @@ class StartJobTask extends AsyncTask<Void, Void, Integer> {
}
// Initiate job
result = mBackend.nativeStartJob(Backend.getIp(address), mDestination.getPort(),
- MIME_TYPE_PDF, mJobParams, mCapabilities, files, null);
+ MIME_TYPE_PDF, mJobParams, mCapabilities, files, null, mDestination.getScheme());
if (result < 0) {
Log.w(TAG, "nativeStartJob failure: " + result);
return Backend.ERROR_UNKNOWN;