From e6c051fee4c3a39b1daacceaee02f6a40ad0d39e Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Wed, 14 Sep 2022 17:26:32 -0300
Subject: [PATCH] Require location for hotspot on Android 12+

This seems to be necessary. Without the location turned on, the hotspot does not start showing a p2p error.
---
 .../android/hotspot/ConditionManager29.java   | 39 +++++++++++++++----
 .../briar/android/util/UiUtils.java           | 11 +++++-
 briar-android/src/main/res/values/strings.xml |  3 ++
 3 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager29.java b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager29.java
index 071fbeeb65..866f9cc917 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager29.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager29.java
@@ -1,6 +1,7 @@
 package org.briarproject.briar.android.hotspot;
 
 import android.content.Intent;
+import android.location.LocationManager;
 import android.provider.Settings;
 
 import org.briarproject.briar.R;
@@ -17,11 +18,13 @@ import androidx.annotation.RequiresApi;
 import androidx.core.util.Consumer;
 
 import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.os.Build.VERSION.SDK_INT;
 import static androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale;
 import static java.lang.Boolean.TRUE;
 import static java.util.logging.Level.INFO;
 import static java.util.logging.Logger.getLogger;
 import static org.briarproject.briar.android.util.UiUtils.getGoToSettingsListener;
+import static org.briarproject.briar.android.util.UiUtils.showLocationDialog;
 
 /**
  * This class ensures that the conditions to open a hotspot are fulfilled on
@@ -63,13 +66,16 @@ class ConditionManager29 extends AbstractConditionManager {
 
 	private boolean areEssentialPermissionsGranted() {
 		boolean isWifiEnabled = wifiManager.isWifiEnabled();
+		boolean isLocationEnabled = isLocationEnabled();
 		if (LOG.isLoggable(INFO)) {
 			LOG.info(String.format("areEssentialPermissionsGranted(): " +
 							"locationPermission? %s, " +
-							"wifiManager.isWifiEnabled()? %b",
-					locationPermission, isWifiEnabled));
+							"wifiManager.isWifiEnabled()? %b" +
+							"isLocationEnabled? %b",
+					locationPermission, isWifiEnabled, isLocationEnabled));
 		}
-		return locationPermission == Permission.GRANTED && isWifiEnabled;
+		return locationPermission == Permission.GRANTED && isWifiEnabled &&
+				isLocationEnabled;
 	}
 
 	@Override
@@ -77,15 +83,22 @@ class ConditionManager29 extends AbstractConditionManager {
 		if (areEssentialPermissionsGranted()) return true;
 
 		if (locationPermission == Permission.UNKNOWN) {
-			locationRequest.launch(ACCESS_FINE_LOCATION);
+			requestPermissions();
+			return false;
+		}
+		// ensure location is enabled (if needed on this device)
+		if (!isLocationEnabled()) {
+			showLocationDialog(ctx, false);
 			return false;
 		}
 
 		// If the location permission has been permanently denied, ask the
 		// user to change the setting
 		if (locationPermission == Permission.PERMANENTLY_DENIED) {
-			showDenialDialog(ctx, R.string.permission_location_title,
-					R.string.permission_hotspot_location_denied_body,
+			int res = SDK_INT >= 31 ?
+					R.string.permission_hotspot_location_denied_precise_body :
+					R.string.permission_hotspot_location_denied_body;
+			showDenialDialog(ctx, R.string.permission_location_title, res,
 					getGoToSettingsListener(ctx),
 					() -> permissionUpdateCallback.accept(false));
 			return false;
@@ -93,8 +106,10 @@ class ConditionManager29 extends AbstractConditionManager {
 
 		// Should we show the rationale for location permission?
 		if (locationPermission == Permission.SHOW_RATIONALE) {
-			showRationale(ctx, R.string.permission_location_title,
-					R.string.permission_hotspot_location_request_body,
+			int res = SDK_INT >= 31 ?
+					R.string.permission_hotspot_location_request_precise_body :
+					R.string.permission_hotspot_location_request_body;
+			showRationale(ctx, R.string.permission_location_title, res,
 					this::requestPermissions,
 					() -> permissionUpdateCallback.accept(false));
 			return false;
@@ -134,4 +149,12 @@ class ConditionManager29 extends AbstractConditionManager {
 		wifiRequest.launch(new Intent(Settings.Panel.ACTION_WIFI));
 	}
 
+	private boolean isLocationEnabled() {
+		if (SDK_INT >= 31) {
+			LocationManager lm = ctx.getSystemService(LocationManager.class);
+			return lm.isLocationEnabled();
+		}
+		return true;
+	}
+
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
index b97ee36e3a..d3bcaa11fc 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
@@ -529,10 +529,19 @@ public class UiUtils {
 	}
 
 	public static void showLocationDialog(Context ctx) {
+		showLocationDialog(ctx, true);
+	}
+
+	public static void showLocationDialog(Context ctx, boolean forBluetooth) {
 		AlertDialog.Builder builder =
 				new AlertDialog.Builder(ctx, R.style.BriarDialogTheme);
 		builder.setTitle(R.string.permission_location_setting_title);
-		builder.setMessage(R.string.permission_location_setting_body);
+		if (forBluetooth) {
+			builder.setMessage(R.string.permission_location_setting_body);
+		} else {
+			builder.setMessage(
+					R.string.permission_location_setting_hotspot_body);
+		}
 		builder.setNegativeButton(R.string.cancel, null);
 		builder.setPositiveButton(R.string.permission_location_setting_button,
 				(dialog, which) -> {
diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml
index 0d31049867..f01f4257b9 100644
--- a/briar-android/src/main/res/values/strings.xml
+++ b/briar-android/src/main/res/values/strings.xml
@@ -781,6 +781,7 @@
 	<string name="permission_location_denied_body">You have denied access to your location, but Briar needs this permission to discover Bluetooth devices.\n\nPlease consider granting access.</string>
 	<string name="permission_location_setting_title">Location setting</string>
 	<string name="permission_location_setting_body">Your device\'s location setting must be turned on to find other devices via Bluetooth. Please enable location to continue. You can disable it again afterwards.</string>
+	<string name="permission_location_setting_hotspot_body">Your device\'s location setting must be turned on to create a Wi-Fi hotspot. Please enable location to continue. You can disable it again afterwards.</string>
 	<string name="permission_location_setting_button">Enable location</string>
 	<string name="permission_bluetooth_title">Nearby devices permission</string>
 	<string name="permission_bluetooth_body">To use Bluetooth communication, Briar needs permission to find and connect to nearby devices.</string>
@@ -812,7 +813,9 @@
 	<string name="hotspot_button_connected">Next</string>
 
 	<string name="permission_hotspot_location_request_body">To create a Wi-Fi hotspot, Briar needs permission to access your location.\n\nBriar does not store your location or share it with anyone.</string>
+	<string name="permission_hotspot_location_request_precise_body">To create a Wi-Fi hotspot, Briar needs permission to access your precise location.\n\nBriar does not store your location or share it with anyone.</string>
 	<string name="permission_hotspot_location_denied_body">You have denied access to your location, but Briar needs this permission to create a Wi-Fi hotspot.\n\nPlease consider granting access.</string>
+	<string name="permission_hotspot_location_denied_precise_body">You have denied access to your precise location, but Briar needs this permission to create a Wi-Fi hotspot.\n\nPlease consider granting access.</string>
 	<string name="wifi_settings_title">Wi-Fi setting</string>
 	<string name="wifi_settings_request_enable_body">To create a Wi-Fi hotspot, Briar needs to use Wi-Fi. Please enable it.</string>
 
-- 
GitLab