diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 5aec7caaa5ae6..19db58cb3cb8c 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -5462,6 +5462,14 @@ package android.ext.settings { } +package android.ext.settings.app { + + public final class VpnDisguiseGetter { + method public static boolean getVpnDisguiseSettingForPackage(@NonNull android.content.Context, int, @NonNull String); + } + +} + package android.graphics.fonts { public final class FontFamilyUpdateRequest { diff --git a/core/java/android/content/pm/GosPackageStateFlag.java b/core/java/android/content/pm/GosPackageStateFlag.java index 21abe5f9398d0..3d0a6bdf76ff9 100644 --- a/core/java/android/content/pm/GosPackageStateFlag.java +++ b/core/java/android/content/pm/GosPackageStateFlag.java @@ -36,6 +36,8 @@ public interface GosPackageStateFlag { /** @hide */ int PLAY_INTEGRITY_API_USED_AT_LEAST_ONCE = 26; /** @hide */ int SUPPRESS_PLAY_INTEGRITY_API_NOTIF = 27; /** @hide */ int BLOCK_PLAY_INTEGRITY_API = 28; + /** @hide */ int VPN_DISGUISE_NON_DEFAULT = 29; + /** @hide */ int VPN_DISGUISE = 30; /** @hide */ @IntDef(value = { @@ -64,6 +66,8 @@ public interface GosPackageStateFlag { PLAY_INTEGRITY_API_USED_AT_LEAST_ONCE, SUPPRESS_PLAY_INTEGRITY_API_NOTIF, BLOCK_PLAY_INTEGRITY_API, + VPN_DISGUISE_NON_DEFAULT, + VPN_DISGUISE, }) @Retention(RetentionPolicy.SOURCE) @interface Enum {} diff --git a/core/java/android/ext/settings/ExtSettings.java b/core/java/android/ext/settings/ExtSettings.java index 821f3d2384ce2..d09bbfc7a8020 100644 --- a/core/java/android/ext/settings/ExtSettings.java +++ b/core/java/android/ext/settings/ExtSettings.java @@ -100,6 +100,10 @@ public class ExtSettings { public static final BoolSetting DISALLOW_DELAYED_LOCKING_ON_USER_STOP = new BoolSetting( Setting.Scope.PER_USER, Settings.Secure.DISALLOW_DELAYED_LOCKING_ON_USER_STOP, false); + public static final BoolSetting VPN_DISGUISE_BY_DEFAULT = new BoolSetting( + Setting.Scope.PER_USER, Settings.Secure.VPN_DISGUISE_BY_DEFAULT, + false); + private ExtSettings() {} public static Function defaultBool(@BoolRes int res) { diff --git a/core/java/android/ext/settings/app/VpnDisguise.java b/core/java/android/ext/settings/app/VpnDisguise.java new file mode 100644 index 0000000000000..1af15a7b865a9 --- /dev/null +++ b/core/java/android/ext/settings/app/VpnDisguise.java @@ -0,0 +1,37 @@ +package android.ext.settings.app; + +import android.annotation.SystemApi; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.GosPackageState; +import android.content.pm.GosPackageStateFlag; +import android.ext.settings.ExtSettings; +import android.util.ArraySet; + +import com.android.internal.R; + +/** @hide */ +public class VpnDisguise extends AppSwitch { + public static final VpnDisguise I = new VpnDisguise(); + + private VpnDisguise() { + gosPsFlagNonDefault = GosPackageStateFlag.VPN_DISGUISE_NON_DEFAULT; + gosPsFlag = GosPackageStateFlag.VPN_DISGUISE; + } + + @Override + public Boolean getImmutableValue(Context ctx, int userId, ApplicationInfo appInfo, + GosPackageState ps, StateInfo si) { + return null; + } + + @Override + protected boolean getDefaultValueInner(Context ctx, int userId, ApplicationInfo appInfo, + GosPackageState ps, StateInfo si) { + if (appInfo.isSystemApp()) { + return false; + } else { + return ExtSettings.VPN_DISGUISE_BY_DEFAULT.get(ctx, userId); + } + } +} diff --git a/core/java/android/ext/settings/app/VpnDisguiseGetter.java b/core/java/android/ext/settings/app/VpnDisguiseGetter.java new file mode 100644 index 0000000000000..d75e8919b7afe --- /dev/null +++ b/core/java/android/ext/settings/app/VpnDisguiseGetter.java @@ -0,0 +1,60 @@ +package android.ext.settings.app; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.GosPackageState; +import android.content.pm.GosPackageStateFlag; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.IPackageManager; +import android.ext.settings.ExtSettings; +import android.os.Binder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.ArraySet; +import android.util.Log; + +import com.android.internal.R; + +/** @hide */ +@SystemApi +public final class VpnDisguiseGetter { + private static final String TAG = "VpnDisguiseGetter"; + private VpnDisguiseGetter() {} + static public final boolean getVpnDisguiseSettingForPackage(@NonNull Context ctxt, int userId, @NonNull String pkg) { + IPackageManager pmi = IPackageManager.Stub.asInterface(ServiceManager.checkService("package")); + GosPackageState ps; + if (pmi == null) { + Log.e(TAG, "Couldn't get package service"); + return false; + } + long oldId = Binder.clearCallingIdentity(); + try { + ps = pmi.getGosPackageState(pkg, userId); + } catch (RemoteException e) { + Log.e(TAG, "Couldn't get GOS package state", e); + return false; + } finally { + Binder.restoreCallingIdentity(oldId); + } + + if (!ps.hasFlag(GosPackageStateFlag.VPN_DISGUISE_NON_DEFAULT)) { + ApplicationInfo appInfo; + try { + appInfo = ctxt.getPackageManager().getApplicationInfo(pkg, 0); + } catch (NameNotFoundException e) { + Log.e(TAG, "Couldn't get package info", e); + return false; + } + if (appInfo.isSystemApp()) { + return false; + } else { + return ExtSettings.VPN_DISGUISE_BY_DEFAULT.get(ctxt, userId); + } + } else { + return ps.hasFlag(GosPackageStateFlag.VPN_DISGUISE); + } + } +} diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a4c920d56066f..1c6cbaf205474 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7352,6 +7352,10 @@ public static final class Secure extends NameValueTable { @Protected(readWrite = KnownSystemPackage.SETTINGS) public static final String DISALLOW_DELAYED_LOCKING_ON_USER_STOP = "disallow_delayed_locking_on_user_stop"; + /** @hide */ + @Protected(readWrite = KnownSystemPackage.SETTINGS) + public static final String VPN_DISGUISE_BY_DEFAULT = "vpn_disguise"; + // ExtSettings END // NOTE: If you add new settings here, be sure to add them to diff --git a/services/core/java/com/android/server/pm/GosPackageStatePermissions.java b/services/core/java/com/android/server/pm/GosPackageStatePermissions.java index 5c1348efce7f5..af0995b2058a2 100644 --- a/services/core/java/com/android/server/pm/GosPackageStatePermissions.java +++ b/services/core/java/com/android/server/pm/GosPackageStatePermissions.java @@ -40,6 +40,8 @@ import static android.content.pm.GosPackageStateFlag.RESTRICT_STORAGE_DYN_CODE_LOADING_SUPPRESS_NOTIF; import static android.content.pm.GosPackageStateFlag.RESTRICT_WEBVIEW_DYN_CODE_LOADING; import static android.content.pm.GosPackageStateFlag.RESTRICT_WEBVIEW_DYN_CODE_LOADING_NON_DEFAULT; +import static android.content.pm.GosPackageStateFlag.VPN_DISGUISE; +import static android.content.pm.GosPackageStateFlag.VPN_DISGUISE_NON_DEFAULT; import static android.content.pm.GosPackageStateFlag.STORAGE_SCOPES_ENABLED; import static android.content.pm.GosPackageStateFlag.SUPPRESS_PLAY_INTEGRITY_API_NOTIF; import static android.content.pm.GosPackageStateFlag.USE_EXTENDED_VA_SPACE; @@ -57,6 +59,7 @@ class GosPackageStatePermissions { // Permission that each package has for accessing its own GosPackageState private static GosPackageStatePermission selfAccessPermission; private static GosPackageStatePermission fullPermission; + private static GosPackageStatePermission systemPermission; private static int myPid; // Maps app's appId to its permission. // Written only during PackageManager init, no need to synchronize reads @@ -86,6 +89,11 @@ static void init(PackageManagerService pm) { GosPackageStatePermission full = GosPackageStatePermission.createFull(); fullPermission = full; + systemPermission = builder() + .readFlags(VPN_DISGUISE, VPN_DISGUISE_NON_DEFAULT) + .crossUserPermission(ALLOW_CROSS_USER_PROFILE_READS) + .create(); + grantedPermissions.put(Process.SHELL_UID, full); if (Build.isDebuggable()) { // for root adb @@ -141,6 +149,8 @@ static void init(PackageManagerService pm) { FORCE_MEMTAG, FORCE_MEMTAG_SUPPRESS_NOTIF, ENABLE_EXPLOIT_PROTECTION_COMPAT_MODE, + VPN_DISGUISE_NON_DEFAULT, + VPN_DISGUISE, }; builder() .readWriteFlags(settingsReadWriteFlags)