Commit 53330fb1 authored by Francois Beaufort's avatar Francois Beaufort Committed by Commit Bot

[WebNFC] Warn user when NFC is not supported

This CL makes sure a message is shown to the user when NFC is not
supported on the device while Web NFC access has been granted to a
website.
Messages show up in page info popup and site settings UI.

Screenshots: https://bugs.chromium.org/p/chromium/issues/detail?id=1058217#c2

Bug: 1035048, 1055216, 1058217
Change-Id: I4687a353feedd92e233ae1741738aef9bb774ad0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2077685
Commit-Queue: François Beaufort <beaufort.francois@gmail.com>
Reviewed-by: default avatarBoris Sazonov <bsazonov@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747186}
parent aea1645c
...@@ -94,33 +94,39 @@ class PermissionParamsListBuilder { ...@@ -94,33 +94,39 @@ class PermissionParamsListBuilder {
permissionParams.iconResource = getImageResourceForPermission(permission.type); permissionParams.iconResource = getImageResourceForPermission(permission.type);
if (permission.setting == ContentSettingValues.ALLOW) { if (permission.setting == ContentSettingValues.ALLOW) {
LocationUtils locationUtils = LocationUtils.getInstance(); LocationUtils locationUtils = LocationUtils.getInstance();
Intent intentOverride = null;
String[] androidPermissions = null;
if (permission.type == ContentSettingsType.GEOLOCATION if (permission.type == ContentSettingsType.GEOLOCATION
&& !locationUtils.isSystemLocationSettingEnabled()) { && !locationUtils.isSystemLocationSettingEnabled()) {
permissionParams.warningTextResource = R.string.page_info_android_location_blocked; permissionParams.warningTextResource = R.string.page_info_android_location_blocked;
intentOverride = locationUtils.getSystemLocationSettingsIntent(); permissionParams.clickCallback = createPermissionClickCallback(
locationUtils.getSystemLocationSettingsIntent(),
null /* androidPermissions */);
} else if (permission.type == ContentSettingsType.NFC
&& !NfcSystemLevelSetting.isNfcAccessPossible()) {
permissionParams.warningTextResource = R.string.page_info_android_nfc_unsupported;
} else if (permission.type == ContentSettingsType.NFC } else if (permission.type == ContentSettingsType.NFC
&& !NfcSystemLevelSetting.isNfcSystemLevelSettingEnabled()) { && !NfcSystemLevelSetting.isNfcSystemLevelSettingEnabled()) {
permissionParams.warningTextResource = permissionParams.warningTextResource =
R.string.page_info_android_permission_blocked; R.string.page_info_android_permission_blocked;
intentOverride = NfcSystemLevelSetting.getNfcSystemLevelSettingIntent(); permissionParams.clickCallback = createPermissionClickCallback(
NfcSystemLevelSetting.getNfcSystemLevelSettingIntent(),
null /* androidPermissions */);
} else if (shouldShowNotificationsDisabledWarning(permission)) { } else if (shouldShowNotificationsDisabledWarning(permission)) {
permissionParams.warningTextResource = permissionParams.warningTextResource =
R.string.page_info_android_permission_blocked; R.string.page_info_android_permission_blocked;
intentOverride = ApiCompatibilityUtils.getNotificationSettingsIntent(); permissionParams.clickCallback = createPermissionClickCallback(
ApiCompatibilityUtils.getNotificationSettingsIntent(),
null /* androidPermissions */);
} else if (!hasAndroidPermission(permission.type)) { } else if (!hasAndroidPermission(permission.type)) {
permissionParams.warningTextResource = permissionParams.warningTextResource =
R.string.page_info_android_permission_blocked; R.string.page_info_android_permission_blocked;
androidPermissions = permissionParams.clickCallback = createPermissionClickCallback(
PermissionUtil.getAndroidPermissionsForContentSetting(permission.type); null /* intentOverride */,
PermissionUtil.getAndroidPermissionsForContentSetting(permission.type));
} }
if (permissionParams.warningTextResource != 0) { if (permissionParams.warningTextResource != 0) {
permissionParams.iconResource = R.drawable.exclamation_triangle; permissionParams.iconResource = R.drawable.exclamation_triangle;
permissionParams.iconTintColorResource = R.color.default_icon_color_blue; permissionParams.iconTintColorResource = R.color.default_icon_color_blue;
permissionParams.clickCallback =
createPermissionClickCallback(intentOverride, androidPermissions);
} }
} }
......
...@@ -21,6 +21,16 @@ public class NfcCategory extends SiteSettingsCategory { ...@@ -21,6 +21,16 @@ public class NfcCategory extends SiteSettingsCategory {
super(Type.NFC, "" /* androidPermission*/); super(Type.NFC, "" /* androidPermission*/);
} }
@Override
protected boolean supportedGlobally() {
return NfcSystemLevelSetting.isNfcAccessPossible();
}
@Override
protected String getMessageIfNotSupported(Activity activity) {
return activity.getResources().getString(R.string.android_nfc_unsupported);
}
@Override @Override
protected boolean enabledGlobally() { protected boolean enabledGlobally() {
return NfcSystemLevelSetting.isNfcSystemLevelSettingEnabled(); return NfcSystemLevelSetting.isNfcSystemLevelSettingEnabled();
......
...@@ -22,6 +22,7 @@ import android.text.SpannableString; ...@@ -22,6 +22,7 @@ import android.text.SpannableString;
import android.text.style.ForegroundColorSpan; import android.text.style.ForegroundColorSpan;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.R; import org.chromium.chrome.R;
...@@ -335,6 +336,7 @@ public class SiteSettingsCategory { ...@@ -335,6 +336,7 @@ public class SiteSettingsCategory {
Intent globalIntent = getIntentToEnableOsGlobalPermission(activity); Intent globalIntent = getIntentToEnableOsGlobalPermission(activity);
String perAppMessage = getMessageForEnablingOsPerAppPermission(activity, !specificCategory); String perAppMessage = getMessageForEnablingOsPerAppPermission(activity, !specificCategory);
String globalMessage = getMessageForEnablingOsGlobalPermission(activity); String globalMessage = getMessageForEnablingOsGlobalPermission(activity);
String unsupportedMessage = getMessageIfNotSupported(activity);
Resources resources = activity.getResources(); Resources resources = activity.getResources();
int color = ApiCompatibilityUtils.getColor(resources, R.color.pref_accent_color); int color = ApiCompatibilityUtils.getColor(resources, R.color.pref_accent_color);
...@@ -351,7 +353,10 @@ public class SiteSettingsCategory { ...@@ -351,7 +353,10 @@ public class SiteSettingsCategory {
} }
} }
if (globalIntent != null) { if (!supportedGlobally()) {
osWarningExtra.setTitle(unsupportedMessage);
osWarningExtra.setIcon(getDisabledInAndroidIcon(activity));
} else if (globalIntent != null) {
SpannableString messageWithLink = SpanApplier.applySpans( SpannableString messageWithLink = SpanApplier.applySpans(
globalMessage, new SpanInfo("<link>", "</link>", linkSpan)); globalMessage, new SpanInfo("<link>", "</link>", linkSpan));
osWarningExtra.setTitle(messageWithLink); osWarningExtra.setTitle(messageWithLink);
...@@ -381,6 +386,22 @@ public class SiteSettingsCategory { ...@@ -381,6 +386,22 @@ public class SiteSettingsCategory {
return icon; return icon;
} }
/**
* Returns whether the permission is supported on this device. Some permissions
* like NFC are backed up by hardware support and may not be available.
*/
protected boolean supportedGlobally() {
return true;
}
/**
* Returns the message to display when permission is not supported.
*/
@Nullable
protected String getMessageIfNotSupported(Activity activity) {
return null;
}
/** /**
* Returns whether the permission is enabled in Android, both globally and per-app. If the * Returns whether the permission is enabled in Android, both globally and per-app. If the
* permission does not have a per-app setting or a global setting, true is assumed for either * permission does not have a per-app setting or a global setting, true is assumed for either
......
...@@ -629,6 +629,21 @@ public class SiteSettingsTest { ...@@ -629,6 +629,21 @@ public class SiteSettingsTest {
NfcSystemLevelSetting.setNfcSettingForTesting(null); NfcSystemLevelSetting.setNfcSettingForTesting(null);
} }
/**
* Tests system NFC support in Preferences.
*/
@Test
@SmallTest
@Feature({"Preferences"})
public void testSystemNfcSupport() {
String[] binaryToggleWithOsWarningExtra =
new String[] {"binary_toggle", "os_permissions_warning_extra"};
// Disable system nfc support and check for the right preferences.
NfcSystemLevelSetting.setNfcSupportForTesting(false);
checkPreferencesForCategory(SiteSettingsCategory.Type.NFC, binaryToggleWithOsWarningExtra);
}
/** /**
* Tests that {@link SingleWebsiteSettings#resetSite} doesn't crash * Tests that {@link SingleWebsiteSettings#resetSite} doesn't crash
* (see e.g. the crash on host names in issue 600232). * (see e.g. the crash on host names in issue 600232).
......
...@@ -28,10 +28,15 @@ import org.chromium.ui.base.WindowAndroid; ...@@ -28,10 +28,15 @@ import org.chromium.ui.base.WindowAndroid;
* This class should be used only on the UI thread. * This class should be used only on the UI thread.
*/ */
public class NfcSystemLevelSetting { public class NfcSystemLevelSetting {
private static Boolean sNfcSupportForTesting;
private static Boolean sSystemNfcSettingForTesting; private static Boolean sSystemNfcSettingForTesting;
@CalledByNative @CalledByNative
private static boolean isNfcAccessPossible() { public static boolean isNfcAccessPossible() {
if (sNfcSupportForTesting != null) {
return sNfcSupportForTesting;
}
Context context = ContextUtils.getApplicationContext(); Context context = ContextUtils.getApplicationContext();
int permission = int permission =
context.checkPermission(Manifest.permission.NFC, Process.myPid(), Process.myUid()); context.checkPermission(Manifest.permission.NFC, Process.myPid(), Process.myUid());
...@@ -90,6 +95,12 @@ public class NfcSystemLevelSetting { ...@@ -90,6 +95,12 @@ public class NfcSystemLevelSetting {
sSystemNfcSettingForTesting = enabled; sSystemNfcSettingForTesting = enabled;
} }
/** Disable/enable Android NFC support for testing use only. */
@VisibleForTesting
public static void setNfcSupportForTesting(Boolean enabled) {
sNfcSupportForTesting = enabled;
}
@NativeMethods @NativeMethods
interface Natives { interface Natives {
void onNfcSystemLevelPromptCompleted(long callback); void onNfcSystemLevelPromptCompleted(long callback);
......
...@@ -2190,6 +2190,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p ...@@ -2190,6 +2190,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_PAGE_INFO_ANDROID_LOCATION_BLOCKED" desc="The label used in the Page Info dialog to indicate that location has been been disabled for the device in Android settings"> <message name="IDS_PAGE_INFO_ANDROID_LOCATION_BLOCKED" desc="The label used in the Page Info dialog to indicate that location has been been disabled for the device in Android settings">
Turned off for this device Turned off for this device
</message> </message>
<message name="IDS_PAGE_INFO_ANDROID_NFC_UNSUPPORTED" desc="The label used in the Page Info dialog to indicate NFC is not supported by this device">
This device can't read NFC
</message>
<message name="IDS_PAGE_INFO_CONNECTION_OFFLINE" desc="Message to display in the page info bubble when viewing and offline page."> <message name="IDS_PAGE_INFO_CONNECTION_OFFLINE" desc="Message to display in the page info bubble when viewing and offline page.">
You are viewing an offline copy of this page from <ph name="CREATION_TIME">%1$s<ex>Feb 9, 2016</ex></ph> You are viewing an offline copy of this page from <ph name="CREATION_TIME">%1$s<ex>Feb 9, 2016</ex></ph>
</message> </message>
...@@ -4048,6 +4051,9 @@ Only you can see what your camera is looking at. The site can't see your camera' ...@@ -4048,6 +4051,9 @@ Only you can see what your camera is looking at. The site can't see your camera'
<message name="IDS_ANDROID_NFC_OFF_GLOBALLY" desc="The message to show when NFC has been turned off globally in Android. Contains a link to the settings menu to enable NFC."> <message name="IDS_ANDROID_NFC_OFF_GLOBALLY" desc="The message to show when NFC has been turned off globally in Android. Contains a link to the settings menu to enable NFC.">
NFC is off for this device. Turn it on in <ph name="BEGIN_LINK">&lt;link&gt;</ph>Android Settings<ph name="END_LINK">&lt;/link&gt;</ph>. NFC is off for this device. Turn it on in <ph name="BEGIN_LINK">&lt;link&gt;</ph>Android Settings<ph name="END_LINK">&lt;/link&gt;</ph>.
</message> </message>
<message name="IDS_ANDROID_NFC_UNSUPPORTED" desc="The message to show when NFC is not supported globally in Android">
This device can't read NFC
</message>
</messages> </messages>
</release> </release>
</grit> </grit>
de8d89e825d62bbad48c06f8b8eb1438b1dabd9a
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment