From 9731afd44cb6580c1199d396a2b86f62413bf10b Mon Sep 17 00:00:00 2001 From: kari-ts <135075563+kari-ts@users.noreply.github.com> Date: Fri, 20 Sep 2024 10:59:12 -0700 Subject: [PATCH] android: use PackageManager to determine install AppSourceChecker (#517) We were using MaybeGoogle to determine whether the app was installed from the Play Store, but this has not worked since the refactor. Fixes tailscale/tailscale#13442 Updates tailscale/corp#23283 Signed-off-by: kari-ts --- .../src/main/java/com/tailscale/ipn/App.kt | 2 +- .../com/tailscale/ipn/AppSourceChecker.kt | 34 ++++++++++++++++++ .../java/com/tailscale/ipn/MaybeGoogle.java | 35 ------------------- libtailscale/backend.go | 4 +-- libtailscale/interfaces.go | 5 ++- 5 files changed, 38 insertions(+), 42 deletions(-) create mode 100644 android/src/main/java/com/tailscale/ipn/AppSourceChecker.kt delete mode 100644 android/src/main/java/com/tailscale/ipn/MaybeGoogle.java diff --git a/android/src/main/java/com/tailscale/ipn/App.kt b/android/src/main/java/com/tailscale/ipn/App.kt index 753200c..f0dd06d 100644 --- a/android/src/main/java/com/tailscale/ipn/App.kt +++ b/android/src/main/java/com/tailscale/ipn/App.kt @@ -77,7 +77,7 @@ class App : UninitializedApp(), libtailscale.AppContext, ViewModelStoreOwner { override fun getPlatformDNSConfig(): String = dns.dnsConfigAsString - override fun isPlayVersion(): Boolean = MaybeGoogle.isGoogle() + override fun getInstallSource(): String = AppSourceChecker.getInstallSource(this) override fun shouldUseGoogleDNSFallback(): Boolean = BuildConfig.USE_GOOGLE_DNS_FALLBACK diff --git a/android/src/main/java/com/tailscale/ipn/AppSourceChecker.kt b/android/src/main/java/com/tailscale/ipn/AppSourceChecker.kt new file mode 100644 index 0000000..72e39fc --- /dev/null +++ b/android/src/main/java/com/tailscale/ipn/AppSourceChecker.kt @@ -0,0 +1,34 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause +package com.tailscale.ipn + +import android.content.Context +import android.os.Build +import android.util.Log + +object AppSourceChecker { + + const val TAG = "AppSourceChecker" + + fun getInstallSource(context: Context): String { + val packageManager = context.packageManager + val packageName = context.packageName + Log.d(TAG, "Package name: $packageName") + + val installerPackageName = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + packageManager.getInstallSourceInfo(packageName).installingPackageName + } else { + packageManager.getInstallerPackageName(packageName) + } + + Log.d(TAG, "Installer package name: $installerPackageName") + + return when (installerPackageName) { + "com.android.vending" -> "googleplay" + "org.fdroid.fdroid" -> "fdroid" + "com.amazon.venezia" -> "amazon" + null -> "unknown" + else -> "unknown($installerPackageName)" + } +} +} diff --git a/android/src/main/java/com/tailscale/ipn/MaybeGoogle.java b/android/src/main/java/com/tailscale/ipn/MaybeGoogle.java deleted file mode 100644 index 2eb3bac..0000000 --- a/android/src/main/java/com/tailscale/ipn/MaybeGoogle.java +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package com.tailscale.ipn; - -import android.app.Activity; - -import java.lang.reflect.Method; - -public class MaybeGoogle { - static boolean isGoogle() { - return getGoogle() != null; - } - - static String getIdTokenForActivity(Activity act) { - Class google = getGoogle(); - if (google == null) { - return ""; - } - try { - Method method = google.getMethod("getIdTokenForActivity", Activity.class); - return (String) method.invoke(null, act); - } catch (Exception e) { - return ""; - } - } - - private static Class getGoogle() { - try { - return Class.forName("com.tailscale.ipn.Google"); - } catch (ClassNotFoundException e) { - return null; - } - } -} diff --git a/libtailscale/backend.go b/libtailscale/backend.go index 908b7e2..247a802 100644 --- a/libtailscale/backend.go +++ b/libtailscale/backend.go @@ -105,9 +105,7 @@ type settingsFunc func(*router.Config, *dns.OSConfig) error func (a *App) runBackend(ctx context.Context) error { paths.AppSharedDir.Store(a.dataDir) hostinfo.SetOSVersion(a.osVersion()) - if !a.appCtx.IsPlayVersion() { - hostinfo.SetPackage("nogoogle") - } + hostinfo.SetPackage(a.appCtx.GetInstallSource()) deviceModel := a.modelName() if a.isChromeOS() { deviceModel = "ChromeOS: " + deviceModel diff --git a/libtailscale/interfaces.go b/libtailscale/interfaces.go index d168fef..7c05166 100644 --- a/libtailscale/interfaces.go +++ b/libtailscale/interfaces.go @@ -33,9 +33,8 @@ type AppContext interface { // GetModelName gets the Android device's model name. GetModelName() (string, error) - // IsPlayVersion reports whether this is the Google Play version of the app - // (as opposed to F-droid/sideloaded). - IsPlayVersion() bool + // GetInstallSource gets information about how the app was installed or updated. + GetInstallSource() string // ShouldUseGoogleDNSFallback reports whether or not to use Google for DNS fallback. ShouldUseGoogleDNSFallback() bool