Merge ab/7061308 into stage.
Bug: 180401296
Merged-In: I47ef91d9d55cf89777dee5020f8aa310dced8557
Change-Id: I211e42f1fee337ce51d432786fe514444e66ce66
diff --git a/Android.bp b/Android.bp
index 1ef830f..4ffb195 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
android_app {
name: "BuiltInPrintService",
privileged: true,
diff --git a/OWNERS b/OWNERS
index 9d8c08e..e2a1aec 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,2 +1 @@
-moltmann@google.com
svetoslavganov@google.com
diff --git a/jni/Android.bp b/jni/Android.bp
index 82bf3d6..c25eb46 100644
--- a/jni/Android.bp
+++ b/jni/Android.bp
@@ -13,6 +13,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_shared {
name: "libwfds",
diff --git a/jni/ipphelper/ipphelper.c b/jni/ipphelper/ipphelper.c
index 27a4090..7daf8af 100644
--- a/jni/ipphelper/ipphelper.c
+++ b/jni/ipphelper/ipphelper.c
@@ -1051,6 +1051,15 @@
capabilities->faceDownTray = 0;
}
}
+ if ((attrptr = ippFindAttribute(response, "printer-output-tray", IPP_TAG_STRING)) != NULL) {
+ for (i = 0; i < ippGetCount(attrptr); i++) {
+ int length = 0;
+ const char *tray_str = ippGetOctetString(attrptr, i, &length);
+ if (strstr(tray_str, "faceUp") != NULL) {
+ capabilities->faceDownTray = 0;
+ }
+ }
+ }
// Determine supported document format details
if ((attrptr = ippFindAttribute(response, "document-format-details-supported",
diff --git a/jni/ipphelper/ippstatus_capabilities.c b/jni/ipphelper/ippstatus_capabilities.c
index 9c596cb..f6c8ea7 100644
--- a/jni/ipphelper/ippstatus_capabilities.c
+++ b/jni/ipphelper/ippstatus_capabilities.c
@@ -56,6 +56,7 @@
"output-bin-supported",
"print-color-mode-supported",
"print-quality-supported",
+ "printer-output-tray",
"printer-resolution-supported",
"sides-supported",
"printer-device-id",
diff --git a/jni/lib/printable_area.c b/jni/lib/printable_area.c
index 358bd95..ee6781b 100644
--- a/jni/lib/printable_area.c
+++ b/jni/lib/printable_area.c
@@ -41,10 +41,10 @@
job_params->page_height = SupportedMediaSizes[i].HeightInInches / 1000;
}
}
- // don't adjust for margins if job is borderless and PCLm. dimensions of image will not
+ // don't adjust for margins if job is PCLm. dimensions of image will not
// match (will be bigger than) the dimensions of the page size and a corrupt image will render
// in genPCLm
- if (job_params->borderless && job_params->pcl_type == PCLm) {
+ if (job_params->pcl_type == PCLm) {
job_params->printable_area_width = (unsigned int) _MI_TO_PIXELS(
job_params->page_width * 1000, job_params->pixel_units);
job_params->printable_area_height = (unsigned int) _MI_TO_PIXELS(
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 46b5ce4..f309c88 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -111,10 +111,18 @@
<!-- Channel name for connection-related notifications [CHAR LIMIT=40] -->
<string name="connections">Connections</string>
- <!-- Message shown in dialog, toast, or notification if the service cannot get Wi-Fi Direct permissions [CHAR LIMIT=UNLIMITED] -->
+ <!-- Message shown in notification if there is a problem accessing Wi-Fi Direct [CHAR LIMIT=UNLIMITED] -->
+ <string name="wifi_direct_problem">Default Print Service cannot find Wi-Fi Direct printers</string>
+ <!-- Button with negative response to permissions or location request, disabling Wi-Fi Direct [CHAR LIMIT=20] -->
+ <string name="disable_wifi_direct">Disable Wi-Fi Direct</string>
+ <!-- Message shown in dialog or toast if the service cannot get Wi-Fi Direct permissions [CHAR LIMIT=UNLIMITED] -->
<string name="wifi_direct_permission_rationale">Default Print Service needs location permission to find nearby devices.</string>
<!-- Button label in a notification or dialog. This button leads to a request to grant permissions [CHAR LIMIT=20] -->
<string name="fix">Review permission</string>
+ <!-- Message shown in dialog or toast if location is required but disabled [CHAR LIMIT=UNLIMITED] -->
+ <string name="wifi_direct_location_rationale">Default Print Service needs location services enabled to find nearby devices.</string>
+ <!-- Button label in a notification or dialog. This button leads to location settings [CHAR LIMIT=20] -->
+ <string name="enable_location">Enable location</string>
<!-- Share-to-print label [CHAR LIMIT=20] -->
<string name="print">Print</string>
diff --git a/src/com/android/bips/BuiltInPrintService.java b/src/com/android/bips/BuiltInPrintService.java
index f9931a5..aa8aafa 100644
--- a/src/com/android/bips/BuiltInPrintService.java
+++ b/src/com/android/bips/BuiltInPrintService.java
@@ -68,6 +68,8 @@
BuiltInPrintService.class.getCanonicalName() + ".CERTIFICATE_REJECT";
public static final String ACTION_P2P_PERMISSION_CANCEL =
BuiltInPrintService.class.getCanonicalName() + ".P2P_PERMISSION_CANCEL";
+ public static final String ACTION_P2P_DISABLE =
+ BuiltInPrintService.class.getCanonicalName() + ".ACTION_P2P_DISABLE";
private static final String EXTRA_CERTIFICATE = "certificate";
private static final String EXTRA_PRINTER_ID = "printer-id";
private static final String EXTRA_PRINTER_UUID = "printer-uuid";
@@ -377,6 +379,8 @@
} else if (ACTION_P2P_PERMISSION_CANCEL.equals(intent.getAction())) {
// Inform p2pPermissionManager the user canceled the notification (non-permanent)
mP2pPermissionManager.applyPermissionChange(false);
+ } else if (ACTION_P2P_DISABLE.equals(intent.getAction())) {
+ mP2pPermissionManager.applyPermissionChange(true);
}
return START_NOT_STICKY;
}
diff --git a/src/com/android/bips/P2pPermissionManager.java b/src/com/android/bips/P2pPermissionManager.java
index d055a22..e9be8c2 100644
--- a/src/com/android/bips/P2pPermissionManager.java
+++ b/src/com/android/bips/P2pPermissionManager.java
@@ -25,11 +25,12 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
+import android.location.LocationManager;
+import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
@@ -45,6 +46,7 @@
private static final String CHANNEL_ID_CONNECTIONS = "connections";
public static final int REQUEST_P2P_PERMISSION_CODE = 1000;
+ public static final int REQUEST_LOCATION_ENABLE = 1001;
private static final String STATE_KEY = "state";
@@ -73,7 +75,7 @@
* Update the current P2P permissions request state.
*/
public void setState(State state) {
- if (DEBUG) Log.d(TAG, "Setting state=" + state);
+ if (DEBUG) Log.d(TAG, "State from " + mPrefs.getString(STATE_KEY, "?") + " to " + state);
mPrefs.edit().putString(STATE_KEY, state.name()).apply();
}
@@ -91,11 +93,15 @@
closeNotification();
if (hasP2pPermission()) {
setState(State.ALLOWED);
- } else {
- // Inform the user and don't try again for the rest of this session.
- setState(permanent ? State.DISABLED : State.TEMPORARILY_DISABLED);
- Toast.makeText(mContext, R.string.wifi_direct_permission_rationale, Toast.LENGTH_LONG)
- .show();
+ } else if (getState() != State.DISABLED) {
+ if (permanent) {
+ setState(State.DISABLED);
+ } else {
+ // Inform the user and don't try again for the rest of this session.
+ setState(State.TEMPORARILY_DISABLED);
+ Toast.makeText(mContext, R.string.wifi_direct_permission_rationale,
+ Toast.LENGTH_LONG).show();
+ }
}
}
@@ -133,10 +139,15 @@
if (mContext instanceof Activity) {
Activity activity = (Activity) mContext;
- if (explain && activity.shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
- explain(activity);
- } else {
- request(activity);
+ if (!isLocationEnabled()) {
+ requestLocation(activity);
+ } else if (!hasP2pPermission()) {
+ if (explain && activity.shouldShowRequestPermissionRationale(
+ ACCESS_FINE_LOCATION)) {
+ explain(activity);
+ } else {
+ request(activity);
+ }
}
} else {
showNotification();
@@ -159,18 +170,30 @@
private void explain(Activity activity) {
// User denied, but asked us to use P2P, so explain and redirect to settings
- DialogInterface.OnClickListener clickListener = (dialog, which) -> {
- if (which == DialogInterface.BUTTON_POSITIVE) {
- request(activity);
- }
- };
-
new AlertDialog.Builder(activity, android.R.style.Theme_DeviceDefault_Light_Dialog_Alert)
.setMessage(mContext.getString(R.string.wifi_direct_permission_rationale))
- .setPositiveButton(R.string.fix, clickListener)
+ .setPositiveButton(R.string.fix, (dialog, which) -> request(activity))
.show();
}
+ /**
+ * Request location services be enabled globally.
+ */
+ private void requestLocation(Activity activity) {
+ new AlertDialog.Builder(activity, android.R.style.Theme_DeviceDefault_Light_Dialog_Alert)
+ .setMessage(mContext.getString(R.string.wifi_direct_location_rationale))
+ .setPositiveButton(R.string.enable_location, (dialog, which) ->
+ activity.startActivityForResult(new Intent(
+ Settings.ACTION_LOCATION_SOURCE_SETTINGS), REQUEST_LOCATION_ENABLE)
+ )
+ .setOnCancelListener(dialog -> {
+ if (getState() == State.DENIED) {
+ setState(State.TEMPORARILY_DISABLED);
+ }
+ })
+ .show();
+ }
+
private SharedPreferences.OnSharedPreferenceChangeListener listenForPreferenceChanges(
P2pPermissionListener listener) {
SharedPreferences.OnSharedPreferenceChangeListener preferenceListener =
@@ -212,19 +235,26 @@
PendingIntent cancelPendingIndent = PendingIntent.getService(mContext,
BuiltInPrintService.P2P_PERMISSION_REQUEST_ID, cancelIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
- Notification.Action cancelAction = new Notification.Action.Builder(
+
+ Intent disableIntent = new Intent(mContext, BuiltInPrintService.class)
+ .setAction(BuiltInPrintService.ACTION_P2P_DISABLE);
+ PendingIntent disablePendingIndent = PendingIntent.getService(mContext,
+ BuiltInPrintService.P2P_PERMISSION_REQUEST_ID, disableIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ Notification.Action disableAction = new Notification.Action.Builder(
Icon.createWithResource(mContext, R.drawable.ic_printservice),
- mContext.getString(android.R.string.cancel), cancelPendingIndent).build();
+ mContext.getString(R.string.disable_wifi_direct), disablePendingIndent).build();
Notification notification = new Notification.Builder(mContext, CHANNEL_ID_CONNECTIONS)
.setSmallIcon(R.drawable.ic_printservice)
+ .setContentText(mContext.getString(R.string.wifi_direct_problem))
.setStyle(new Notification.BigTextStyle().bigText(
- mContext.getString(R.string.wifi_direct_permission_rationale)))
+ mContext.getString(R.string.wifi_direct_problem)))
.setAutoCancel(true)
.setContentIntent(proceedPendingIntent)
.setDeleteIntent(cancelPendingIndent)
.addAction(fixAction)
- .addAction(cancelAction)
+ .addAction(disableAction)
.build();
mNotificationManager.notify(BuiltInPrintService.P2P_PERMISSION_REQUEST_ID, notification);
@@ -243,12 +273,12 @@
return state;
}
- boolean hasPermission = hasP2pPermission();
- if (hasPermission && state != State.ALLOWED) {
+ boolean allowed = isLocationEnabled() && hasP2pPermission();
+ if (allowed && state != State.ALLOWED) {
// Upgrade state if now allowed
state = State.ALLOWED;
setState(state);
- } else if (!hasPermission && state == State.ALLOWED) {
+ } else if (!allowed && state == State.ALLOWED) {
state = State.DENIED;
setState(state);
}
@@ -256,6 +286,15 @@
}
/**
+ * Return true if location services are enabled.
+ */
+ private boolean isLocationEnabled() {
+ LocationManager manager = (LocationManager) mContext.getSystemService(
+ Context.LOCATION_SERVICE);
+ return manager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER);
+ }
+
+ /**
* Close any outstanding notification.
*/
void closeNotification() {
diff --git a/src/com/android/bips/ui/AddPrintersFragment.java b/src/com/android/bips/ui/AddPrintersFragment.java
index e122cad..1bb3703 100644
--- a/src/com/android/bips/ui/AddPrintersFragment.java
+++ b/src/com/android/bips/ui/AddPrintersFragment.java
@@ -16,6 +16,7 @@
package com.android.bips.ui;
+import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
@@ -96,8 +97,8 @@
mP2pPermissionManager.request(false, approve -> {
updateP2pPreferences();
if (!approve) {
- // The user is choosing to disable by denying Location.
- mP2pPermissionManager.setState(P2pPermissionManager.State.DISABLED);
+ // Try again next time
+ mP2pPermissionManager.setState(P2pPermissionManager.State.TEMPORARILY_DISABLED);
}
});
}
@@ -149,9 +150,11 @@
if (mP2pPermissionManager.isP2pEnabled()) {
mP2pEnablePreference.setChecked(true);
getPreferenceScreen().addPreference(mFindP2pPrintersPreference);
- if (getActivity().getIntent().getBooleanExtra(EXTRA_FIX_P2P_PERMISSION, false)) {
+ Activity activity = getActivity();
+ if (activity != null && activity.getIntent().getBooleanExtra(EXTRA_FIX_P2P_PERMISSION,
+ false)) {
// If we were only here to enable P2P permissions, go back to the print now.
- getActivity().finish();
+ activity.finish();
}
} else {
mP2pEnablePreference.setChecked(false);