Skip to content
4 changes: 4 additions & 0 deletions core/java/android/app/ActivityThreadHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.content.Context;
import android.content.pm.GosPackageState;
import android.content.pm.SrtPermissions;
import android.ext.carrierinfo.HideCarrierInfo;
import android.ext.dcl.DynCodeLoading;
import android.location.HookedLocationManager;
import android.os.Bundle;
Expand Down Expand Up @@ -42,6 +43,8 @@ static Bundle onBind(Context appContext, ActivityThread.AppBindData appBindData)

DynCodeLoading.handleAppBindFlags(flags[AppBindArgs.FLAGS_IDX_DYN_CODE_LOADING]);

HideCarrierInfo.handleAppBindFlags(flags[AppBindArgs.FLAGS_IDX_HIDE_CARRIER_INFO]);

return args;
}

Expand All @@ -59,6 +62,7 @@ static void onGosPackageStateChanged(Context ctx, GosPackageState state, boolean
if (!Process.isIsolated()) {
StorageScopesAppHooks.maybeEnable(state);
ContactScopes.maybeEnable(ctx, state);
HideCarrierInfo.onGosPackageStateChanged(ctx, state);
}
}

Expand Down
1 change: 1 addition & 0 deletions core/java/android/app/AppBindArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public interface AppBindArgs {
int FLAGS_IDX_SPECIAL_RUNTIME_PERMISSIONS = 0;
int FLAGS_IDX_HOOKED_LOCATION_MANAGER = 1;
int FLAGS_IDX_DYN_CODE_LOADING = 2;
int FLAGS_IDX_HIDE_CARRIER_INFO = 3;

int FLAGS_ARRAY_LEN = 10;
}
2 changes: 2 additions & 0 deletions core/java/android/app/IActivityManager.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -1071,4 +1071,6 @@ interface IActivityManager {
* Unregisters the listener previously registered for ANR warning.
*/
void unregisterAnrWarningListener(in IAnrWarningCallback callback);

boolean shouldHideCarrierInfoForUid(int targetUid, String apiName);
}
5 changes: 5 additions & 0 deletions core/java/android/content/pm/GosPackageStateFlag.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ 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;
// flag 29 was used mic spoofing feature (not merged yet)
/** @hide */ int HIDE_CARRIER_INFO_NON_DEFAULT = 30;
/** @hide */ int HIDE_CARRIER_INFO = 31;

/** @hide */
@IntDef(value = {
Expand Down Expand Up @@ -64,6 +67,8 @@ public interface GosPackageStateFlag {
PLAY_INTEGRITY_API_USED_AT_LEAST_ONCE,
SUPPRESS_PLAY_INTEGRITY_API_NOTIF,
BLOCK_PLAY_INTEGRITY_API,
HIDE_CARRIER_INFO_NON_DEFAULT,
HIDE_CARRIER_INFO,
})
@Retention(RetentionPolicy.SOURCE)
@interface Enum {}
Expand Down
1 change: 1 addition & 0 deletions core/java/android/ext/SettingsIntents.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class SettingsIntents {
public static final String APP_MEMORY_DYN_CODE_LOADING = "android.settings.OPEN_APP_MEMORY_DYN_CODE_LOADING_SETTINGS";
public static final String APP_STORAGE_DYN_CODE_LOADING = "android.settings.OPEN_APP_STORAGE_DYN_CODE_LOADING_SETTINGS";
public static final String APP_MANAGE_PLAY_INTEGRITY_API = "android.settings.OPEN_APP_MANAGE_PLAY_INTEGRITY_API_SETTINGS";
public static final String APP_HIDE_CARRIER_INFO = "android.settings.OPEN_APP_HIDE_CARRIER_INFO_SETTINGS";

public static Intent getAppIntent(Context ctx, String action, String pkgName) {
var i = new Intent(action);
Expand Down
47 changes: 47 additions & 0 deletions core/java/android/ext/carrierinfo/HideCarrierInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package android.ext.carrierinfo;

import android.app.AppGlobals;
import android.app.Application;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.GosPackageState;
import android.ext.settings.app.AswHideCarrierInfo;
import android.os.UserHandle;

/** @hide */
public class HideCarrierInfo {
/** @hide */
public static final int FLAG_HIDE_CARRIER_INFO = 1;

private static volatile int flags;

/** @hide */
public static int getAppBindFlags(Context ctx, int userId, ApplicationInfo appInfo,
GosPackageState gosPs) {
if (AswHideCarrierInfo.I.get(ctx, userId, appInfo, gosPs)) {
return FLAG_HIDE_CARRIER_INFO;
}
return 0;
}

/** @hide */
public static void handleAppBindFlags(int v) {
flags = v;
}

/** @hide */
public static void onGosPackageStateChanged(Context ctx, GosPackageState gosPs) {
Application app = AppGlobals.getInitialApplication();
if (app == null) {
return;
}
flags = getAppBindFlags(ctx, UserHandle.myUserId(), app.getApplicationInfo(), gosPs);
}

/** @hide */
public static boolean isEnabled() {
return (flags & FLAG_HIDE_CARRIER_INFO) != 0;
}

private HideCarrierInfo() {}
}
4 changes: 4 additions & 0 deletions core/java/android/ext/settings/ExtSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 HIDE_CARRIER_INFO_BY_DEFAULT = new BoolSetting(
Setting.Scope.GLOBAL, Settings.Global.HIDE_CARRIER_INFO_BY_DEFAULT,
defaultBool(R.bool.setting_default_hide_carrier_info));

private ExtSettings() {}

public static Function<Context, Boolean> defaultBool(@BoolRes int res) {
Expand Down
34 changes: 34 additions & 0 deletions core/java/android/ext/settings/app/AswHideCarrierInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package android.ext.settings.app;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.GosPackageState;
import android.content.pm.GosPackageStateFlag;
import android.ext.settings.ExtSettings;

/** @hide */
public class AswHideCarrierInfo extends AppSwitch {
public static final AswHideCarrierInfo I = new AswHideCarrierInfo();

private AswHideCarrierInfo() {
gosPsFlagNonDefault = GosPackageStateFlag.HIDE_CARRIER_INFO_NON_DEFAULT;
gosPsFlag = GosPackageStateFlag.HIDE_CARRIER_INFO;
}

@Override
public Boolean getImmutableValue(Context ctx, int userId, ApplicationInfo appInfo,
GosPackageState ps, StateInfo si) {
if (appInfo.isSystemApp()) {
si.immutabilityReason = IR_IS_SYSTEM_APP;
return false;
}
return null;
}

@Override
protected boolean getDefaultValueInner(Context ctx, int userId, ApplicationInfo appInfo,
GosPackageState ps, StateInfo si) {
si.defaultValueReason = DVR_DEFAULT_SETTING;
return ExtSettings.HIDE_CARRIER_INFO_BY_DEFAULT.get(ctx, userId);
}
}
4 changes: 4 additions & 0 deletions core/java/android/provider/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -14519,6 +14519,10 @@ public static final class Global extends NameValueTable {
KnownSystemPackage.SETUP_WIZARD})
public static final String GEOCODER = "geocoder";

/** @hide */
@Protected(readWrite = KnownSystemPackage.SETTINGS)
public static final String HIDE_CARRIER_INFO_BY_DEFAULT = "hide_carrier_info";

// ExtSettings END

// NOTE: If you add new settings here, be sure to add them to
Expand Down
19 changes: 15 additions & 4 deletions core/java/com/android/internal/os/ZygoteExtraArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.GosPackageState;
import android.ext.settings.app.AswHideCarrierInfo;

// Extra args for:
// - children of main zygote{,64}, including AppZygotes, but excluding WebViewZygote
Expand All @@ -13,17 +14,20 @@
// (see android.app.ZygotePreload).
public class ZygoteExtraArgs {
public final long selinuxFlags;
public final boolean bindMountExtendedSyspropOverrides;

public static final String PREFIX = "--flat-extra-args=";

public static final ZygoteExtraArgs DEFAULT = new ZygoteExtraArgs(0L);
public static final ZygoteExtraArgs DEFAULT = new ZygoteExtraArgs(0L, false);

public ZygoteExtraArgs(long selinuxFlags) {
public ZygoteExtraArgs(long selinuxFlags, boolean bindMountExtendedSyspropOverrides) {
this.selinuxFlags = selinuxFlags;
this.bindMountExtendedSyspropOverrides = bindMountExtendedSyspropOverrides;
}

private static final int IDX_SELINUX_FLAGS = 0;
private static final int ARR_LEN = 1;
private static final int IDX_BIND_MOUNT_EXTENDED_SYSPROP_OVERRIDES = 1;
private static final int ARR_LEN = 2;
private static final String SEPARATOR = "\t";

public static String createFlat(Context ctx, int userId, ApplicationInfo appInfo,
Expand All @@ -33,6 +37,8 @@ public static String createFlat(Context ctx, int userId, ApplicationInfo appInfo
arr[IDX_SELINUX_FLAGS] = Long.toHexString(
SELinuxFlags.get(ctx, userId, appInfo, ps, isIsolatedProcess)
);
arr[IDX_BIND_MOUNT_EXTENDED_SYSPROP_OVERRIDES] =
AswHideCarrierInfo.I.get(ctx, userId, appInfo, ps) ? "1" : "0";
return PREFIX + String.join(SEPARATOR, arr);
}

Expand All @@ -42,19 +48,24 @@ public static String createFlatForWebviewProcess(Context ctx, int userId,
arr[IDX_SELINUX_FLAGS] = Long.toHexString(
SELinuxFlags.getForWebViewProcess(ctx, userId, callerAppInfo, callerPs)
);
arr[IDX_BIND_MOUNT_EXTENDED_SYSPROP_OVERRIDES] = "0";
return PREFIX + String.join(SEPARATOR, arr);
}

static ZygoteExtraArgs parse(String flat) {
String[] arr = flat.split(SEPARATOR);
long selinuxFlags = Long.parseLong(arr[IDX_SELINUX_FLAGS], 16);
return new ZygoteExtraArgs(selinuxFlags);
boolean bindMountExtendedSyspropOverrides =
arr.length > IDX_BIND_MOUNT_EXTENDED_SYSPROP_OVERRIDES
&& "1".equals(arr[IDX_BIND_MOUNT_EXTENDED_SYSPROP_OVERRIDES]);
return new ZygoteExtraArgs(selinuxFlags, bindMountExtendedSyspropOverrides);
}

// keep in sync with ExtraArgs struct in core/jni/com_android_internal_os_Zygote.cpp
public long[] makeJniLongArray() {
long[] res = new long[ARR_LEN];
res[IDX_SELINUX_FLAGS] = selinuxFlags;
res[IDX_BIND_MOUNT_EXTENDED_SYSPROP_OVERRIDES] = bindMountExtendedSyspropOverrides ? 1L : 0L;
return res;
}
}
13 changes: 11 additions & 2 deletions core/jni/com_android_internal_os_Zygote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,14 +362,16 @@ enum RuntimeFlags : uint32_t {

struct ExtraArgs {
uint64_t selinux_flags = 0;
bool bind_mount_extended_sysprop_overrides = false;

ExtraArgs() {}

ExtraArgs(JNIEnv* env, jlongArray jlongArgs) {
const size_t num_jlong_args = 1;
const size_t num_jlong_args = 2;
jlong jlong_arr[num_jlong_args];
env->GetLongArrayRegion(jlongArgs, 0, num_jlong_args, (jlong *) &jlong_arr);
selinux_flags = (uint64_t) jlong_arr[0];
bind_mount_extended_sysprop_overrides = (jlong_arr[1] != 0);
}
};

Expand Down Expand Up @@ -1753,6 +1755,11 @@ static void BindMountSyspropOverride(fail_fn_t fail_fn, JNIEnv* env) {
// TODO: when ReloadBuildJavaConstants is needed, make it skip reloading of unaffected constants
}

static void BindMountExtendedSyspropOverride(fail_fn_t fail_fn, JNIEnv* env) {
__system_properties_enable_extended_override();
// see the TODO above BindMountSyspropOverride
}

static void BindMountStorageToLowerFs(const userid_t user_id, const uid_t uid,
const char* dir_name, const char* package, fail_fn_t fail_fn) {
bool hasSdcardFs = IsSdcardfsUsed();
Expand Down Expand Up @@ -1978,7 +1985,9 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
fail_fn);
}

if (mount_sysprop_overrides) {
if (extra_args.bind_mount_extended_sysprop_overrides) {
BindMountExtendedSyspropOverride(fail_fn, env);
} else if (mount_sysprop_overrides) {
BindMountSyspropOverride(fail_fn, env);
}

Expand Down
3 changes: 3 additions & 0 deletions core/res/res/values/config_ext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@
</string-array>
<java-symbol type="array" name="read_additional_security_state_known_signers" />

<bool name="setting_default_hide_carrier_info">false</bool>
<java-symbol type="bool" name="setting_default_hide_carrier_info" />

</resources>
Loading