Loading core/api/current.txt +11 −0 Original line number Diff line number Diff line Loading @@ -38321,13 +38321,24 @@ package android.provider { } public static final class ContactsContract.Settings implements android.provider.ContactsContract.SettingsColumns { method @FlaggedApi("android.provider.new_account_attributes_api_enabled") @RequiresPermission(android.Manifest.permission.READ_CONTACTS) public static long getAccountAttributes(@NonNull android.content.ContentResolver, @Nullable android.accounts.Account, @Nullable String); method @Deprecated @FlaggedApi("android.provider.new_default_account_api_enabled") @Nullable public static android.accounts.Account getDefaultAccount(@NonNull android.content.ContentResolver); method @FlaggedApi("android.provider.new_account_attributes_api_enabled") @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) public static void setAccountAttributes(@NonNull android.content.ContentResolver, @Nullable android.accounts.Account, @Nullable String, long); field public static final String ACTION_SET_DEFAULT_ACCOUNT = "android.provider.action.SET_DEFAULT_ACCOUNT"; field public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/setting"; field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/setting"; field public static final android.net.Uri CONTENT_URI; } @FlaggedApi("android.provider.new_account_attributes_api_enabled") public static final class ContactsContract.Settings.AccountAttributes { field public static final long ATTRIBUTE_DATA_ORIGIN_CLOUD = 4L; // 0x4L field public static final long ATTRIBUTE_DATA_ORIGIN_LOCAL = 1L; // 0x1L field public static final long ATTRIBUTE_DATA_ORIGIN_SIM = 2L; // 0x2L field public static final long ATTRIBUTE_DATA_TYPE_CUSTOM_DECLARED = 32L; // 0x20L field public static final long ATTRIBUTE_SYNC_MODE_DOWN_SYNC = 16L; // 0x10L field public static final long ATTRIBUTE_SYNC_MODE_UP_SYNC = 8L; // 0x8L } protected static interface ContactsContract.SettingsColumns { field public static final String ACCOUNT_NAME = "account_name"; field public static final String ACCOUNT_TYPE = "account_type"; core/java/android/provider/ContactsContract.java +195 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.provider; import android.accounts.Account; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.LongDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; Loading Loading @@ -3018,8 +3019,6 @@ public final class ContactsContract { com.android.internal.R.string.config_rawContactsLocalAccountType)); } /** * Class containing utility methods around the default account. * New raw contacts requested to be inserted without a specified {@link Account} will be Loading Loading @@ -9252,6 +9251,18 @@ public final class ContactsContract { * @hide */ String IS_DEFAULT = "x_is_default"; /** * The attributes of account to which this row belongs. * @hide */ String ACCOUNT_ATTRIBUTES = HIDDEN_COLUMN_PREFIX + "account_attributes"; /** * Flag indicating if the account's owner has modifies the account attributes. * @hide */ String HAS_OWNER_SET_ATTRIBUTES = HIDDEN_COLUMN_PREFIX + "has_owner_set_attributes"; } /** Loading Loading @@ -9374,6 +9385,28 @@ public final class ContactsContract { */ public static final String KEY_DEFAULT_ACCOUNT = "key_default_account"; /** * The method to invoke in order to overwrite the account attributes. * * @hide */ public static final String SET_ACCOUNT_ATTRIBUTES_METHOD = "setAccountAttributes"; /** * The method to invoke in order to get the account attributes. * * @hide */ public static final String GET_ACCOUNT_ATTRIBUTES_METHOD = "getAccountAttributes"; /** * Key in the bundle for the account attributes. * * @hide */ public static final String KEY_ACCOUNT_ATTRIBUTES = "key_account_attributes"; /** * Get the account that is set as the default account for new contacts, which should be * initially selected when creating a new contact on contact management apps. Loading @@ -9383,7 +9416,6 @@ public final class ContactsContract { * @param resolver the ContentResolver to query. * @return the default account for new contacts, or null if it's not set or set to NULL * account. * * @deprecated This API is only supported up to Android version * * {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}. On later versions, * {@link ContactsContract.RawContacts.DefaultAccount#getDefaultAccountForNewContacts} Loading Loading @@ -9411,7 +9443,6 @@ public final class ContactsContract { * @param resolver the ContentResolver to query. * @param account the account to be set to default. * @hide * * @deprecated This API is only supported up to Android version * * {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}. On later versions, * {@link ContactsContract.RawContacts.DefaultAccount#setDefaultAccountForNewContacts} Loading @@ -9431,6 +9462,163 @@ public final class ContactsContract { resolver.call(ContactsContract.AUTHORITY_URI, SET_DEFAULT_ACCOUNT_METHOD, null, extras); } @FlaggedApi(Flags.FLAG_NEW_ACCOUNT_ATTRIBUTES_API_ENABLED) public static final class AccountAttributes { private AccountAttributes() {} /** * Indicates that the primary, canonical storage location and authoritative source * for contacts associated with this account is the local device. These contacts * are not synchronized with any external service. * An account can only have one of attributes among {@code ATTRIBUTE_DATA_ORIGIN_LOCAL}, * {@code ATTRIBUTE_DATA_ORIGIN_SIM} and {@code ATTRIBUTE_DATA_ORIGIN_CLOUD}. */ public static final long ATTRIBUTE_DATA_ORIGIN_LOCAL = 1L; /** * Indicates that contacts associated with this account are stored directly on the SIM * card. * * An account can only have one of attributes among * {@code ATTRIBUTE_DATA_ORIGIN_LOCAL}, * * {@code ATTRIBUTE_DATA_ORIGIN_SIM} and {@code ATTRIBUTE_DATA_ORIGIN_CLOUD}. */ public static final long ATTRIBUTE_DATA_ORIGIN_SIM = 1L << 1; /** * Indicates that the primary, canonical storage location and authoritative source * for contacts associated with this account is a cloud service. This applies * regardless of whether contacts were initially created on the device and then * synchronized to the cloud, or if they were created directly in the cloud and * downloaded to the device. The cloud serves as the central hub for persistence * and synchronization across devices. * An account can only have one of attributes among {@code ATTRIBUTE_DATA_ORIGIN_LOCAL}, * {@code ATTRIBUTE_DATA_ORIGIN_SIM} and {@code ATTRIBUTE_DATA_ORIGIN_CLOUD}. */ public static final long ATTRIBUTE_DATA_ORIGIN_CLOUD = 1 << 2; /** * Indicates that contacts associated with this account are synchronized * from the device to the cloud. Local changes (creations, edits, deletions) * are uploaded to the authoritative source. * A two-way sync accounts have both {@code ATTRIBUTE_SYNC_MODE_UP_SYNC} and * {@code ATTRIBUTE_SYNC_MODE_DOWN_SYNC} attributes. */ public static final long ATTRIBUTE_SYNC_MODE_UP_SYNC = 1L << 3; /** * Indicates that contacts associated with this account are * synchronized from a cloud account to the device. Local * changes (creations, edits, deletions) are generally not uploaded * to the cloud via this sync mechanism. * A two-way sync account has both {@code ATTRIBUTE_SYNC_MODE_UP_SYNC} and * {@code ATTRIBUTE_SYNC_MODE_DOWN_SYNC} attributes. */ public static final long ATTRIBUTE_SYNC_MODE_DOWN_SYNC = 1L << 4; /** * Indicates that this account has declared custom or non-standard * contact data fields (e.g., those defined via custom MIME types in `contacts.xml` * or other extensibility mechanisms). This data often provides supplementary * information and may not be directly user-editable via the standard Contacts app. */ public static final long ATTRIBUTE_DATA_TYPE_CUSTOM_DECLARED = 1L << 5; /** * @hide */ @LongDef(flag = true, value = { ATTRIBUTE_DATA_ORIGIN_LOCAL, ATTRIBUTE_DATA_ORIGIN_SIM, ATTRIBUTE_DATA_ORIGIN_CLOUD, ATTRIBUTE_SYNC_MODE_UP_SYNC, ATTRIBUTE_SYNC_MODE_DOWN_SYNC, ATTRIBUTE_DATA_TYPE_CUSTOM_DECLARED }) @Retention(RetentionPolicy.SOURCE) public @interface AttributeFlags { } } /** * Returns the attributes of a given account as a 64-bit bitmask. * * <p>A return value of {@code 0L} indicates the account exists but has no specific * attributes enabled or set. * * @param resolver The {@link ContentResolver} to use for the query. * @param account The account to query. If {@code null}, this will query the * attributes of the local, device-only account. * @param dataSet The data set specific to the account type, which may be {@code null}. * @return A {@code long} representing the attributes bitmask. * @throws IllegalStateException if the specified account does not exist or its * attributes could not be determined. */ @FlaggedApi(Flags.FLAG_NEW_ACCOUNT_ATTRIBUTES_API_ENABLED) @RequiresPermission(android.Manifest.permission.READ_CONTACTS) public static @AccountAttributes.AttributeFlags long getAccountAttributes( @NonNull ContentResolver resolver, @Nullable Account account, @Nullable String dataSet) { Bundle extras = new Bundle(); if (account != null) { extras.putString(ACCOUNT_NAME, account.name); extras.putString(ACCOUNT_TYPE, account.type); } if (!TextUtils.isEmpty(dataSet)) { extras.putString(DATA_SET, dataSet); } Bundle response = nullSafeCall(resolver, ContactsContract.AUTHORITY_URI, GET_ACCOUNT_ATTRIBUTES_METHOD, null, extras); if (response == null || !response.containsKey(KEY_ACCOUNT_ATTRIBUTES)) { throw new IllegalStateException(String.format( "Could not determine attributes for account: %s, data_set: %s", account, dataSet)); } return response.getLong(KEY_ACCOUNT_ATTRIBUTES); } /** * Sets the attributes for a given account with a new set of flags. * * <p><b>Warning:</b> This is a destructive operation. Any attributes previously * set on the account will be cleared and replaced by the provided {@code newAttributes}. * * <p>The provided bitmask must be valid and free of semantic conflicts (e.g., * containing more than one {@code DATA_ORIGIN} type). * * <h4>Security</h4> * <p> This method requires that the calling application to be the authenticator * for the account's type. * @see android.accounts.AccountManager#getAuthenticatorTypes() * * @param resolver The {@code ContentResolver} to use for the update. * @param account The target account. If {@code null}, this operation applies to the * local, device-only account. * @param dataSet The data set within the account, which may be {@code null}. * @param newAttributes The complete new bitmask of attributes to apply. * @throws IllegalArgumentException if {@code newAttributes} contains any undefined * bits, has semantic conflicts, or the account is * otherwise invalid. */ @FlaggedApi(Flags.FLAG_NEW_ACCOUNT_ATTRIBUTES_API_ENABLED) @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) public static void setAccountAttributes(@NonNull ContentResolver resolver, @Nullable Account account, @Nullable String dataSet, @AccountAttributes.AttributeFlags long newAttributes) { Bundle extras = new Bundle(); if (account != null) { extras.putString(ACCOUNT_NAME, account.name); extras.putString(ACCOUNT_TYPE, account.type); } if (!TextUtils.isEmpty(dataSet)) { extras.putString(DATA_SET, dataSet); } extras.putLong(KEY_ACCOUNT_ATTRIBUTES, newAttributes); nullSafeCall(resolver, ContactsContract.AUTHORITY_URI, SET_ACCOUNT_ATTRIBUTES_METHOD, null, extras); } } /** Loading core/java/android/provider/flags.aconfig +9 −0 Original line number Diff line number Diff line Loading @@ -87,3 +87,12 @@ flag { description: "Feature flag to expose SYSTEM_UPDATE_SETTINGS as a public API" bug: "417458670" } # OWNER = liefuliu flag { name: "new_account_attributes_api_enabled" is_exported: true namespace: "contacts" description: "Enable the new Account Attributes APIs for contacts" bug: "330326187" } No newline at end of file Loading
core/api/current.txt +11 −0 Original line number Diff line number Diff line Loading @@ -38321,13 +38321,24 @@ package android.provider { } public static final class ContactsContract.Settings implements android.provider.ContactsContract.SettingsColumns { method @FlaggedApi("android.provider.new_account_attributes_api_enabled") @RequiresPermission(android.Manifest.permission.READ_CONTACTS) public static long getAccountAttributes(@NonNull android.content.ContentResolver, @Nullable android.accounts.Account, @Nullable String); method @Deprecated @FlaggedApi("android.provider.new_default_account_api_enabled") @Nullable public static android.accounts.Account getDefaultAccount(@NonNull android.content.ContentResolver); method @FlaggedApi("android.provider.new_account_attributes_api_enabled") @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) public static void setAccountAttributes(@NonNull android.content.ContentResolver, @Nullable android.accounts.Account, @Nullable String, long); field public static final String ACTION_SET_DEFAULT_ACCOUNT = "android.provider.action.SET_DEFAULT_ACCOUNT"; field public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/setting"; field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/setting"; field public static final android.net.Uri CONTENT_URI; } @FlaggedApi("android.provider.new_account_attributes_api_enabled") public static final class ContactsContract.Settings.AccountAttributes { field public static final long ATTRIBUTE_DATA_ORIGIN_CLOUD = 4L; // 0x4L field public static final long ATTRIBUTE_DATA_ORIGIN_LOCAL = 1L; // 0x1L field public static final long ATTRIBUTE_DATA_ORIGIN_SIM = 2L; // 0x2L field public static final long ATTRIBUTE_DATA_TYPE_CUSTOM_DECLARED = 32L; // 0x20L field public static final long ATTRIBUTE_SYNC_MODE_DOWN_SYNC = 16L; // 0x10L field public static final long ATTRIBUTE_SYNC_MODE_UP_SYNC = 8L; // 0x8L } protected static interface ContactsContract.SettingsColumns { field public static final String ACCOUNT_NAME = "account_name"; field public static final String ACCOUNT_TYPE = "account_type";
core/java/android/provider/ContactsContract.java +195 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.provider; import android.accounts.Account; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.LongDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; Loading Loading @@ -3018,8 +3019,6 @@ public final class ContactsContract { com.android.internal.R.string.config_rawContactsLocalAccountType)); } /** * Class containing utility methods around the default account. * New raw contacts requested to be inserted without a specified {@link Account} will be Loading Loading @@ -9252,6 +9251,18 @@ public final class ContactsContract { * @hide */ String IS_DEFAULT = "x_is_default"; /** * The attributes of account to which this row belongs. * @hide */ String ACCOUNT_ATTRIBUTES = HIDDEN_COLUMN_PREFIX + "account_attributes"; /** * Flag indicating if the account's owner has modifies the account attributes. * @hide */ String HAS_OWNER_SET_ATTRIBUTES = HIDDEN_COLUMN_PREFIX + "has_owner_set_attributes"; } /** Loading Loading @@ -9374,6 +9385,28 @@ public final class ContactsContract { */ public static final String KEY_DEFAULT_ACCOUNT = "key_default_account"; /** * The method to invoke in order to overwrite the account attributes. * * @hide */ public static final String SET_ACCOUNT_ATTRIBUTES_METHOD = "setAccountAttributes"; /** * The method to invoke in order to get the account attributes. * * @hide */ public static final String GET_ACCOUNT_ATTRIBUTES_METHOD = "getAccountAttributes"; /** * Key in the bundle for the account attributes. * * @hide */ public static final String KEY_ACCOUNT_ATTRIBUTES = "key_account_attributes"; /** * Get the account that is set as the default account for new contacts, which should be * initially selected when creating a new contact on contact management apps. Loading @@ -9383,7 +9416,6 @@ public final class ContactsContract { * @param resolver the ContentResolver to query. * @return the default account for new contacts, or null if it's not set or set to NULL * account. * * @deprecated This API is only supported up to Android version * * {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}. On later versions, * {@link ContactsContract.RawContacts.DefaultAccount#getDefaultAccountForNewContacts} Loading Loading @@ -9411,7 +9443,6 @@ public final class ContactsContract { * @param resolver the ContentResolver to query. * @param account the account to be set to default. * @hide * * @deprecated This API is only supported up to Android version * * {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}. On later versions, * {@link ContactsContract.RawContacts.DefaultAccount#setDefaultAccountForNewContacts} Loading @@ -9431,6 +9462,163 @@ public final class ContactsContract { resolver.call(ContactsContract.AUTHORITY_URI, SET_DEFAULT_ACCOUNT_METHOD, null, extras); } @FlaggedApi(Flags.FLAG_NEW_ACCOUNT_ATTRIBUTES_API_ENABLED) public static final class AccountAttributes { private AccountAttributes() {} /** * Indicates that the primary, canonical storage location and authoritative source * for contacts associated with this account is the local device. These contacts * are not synchronized with any external service. * An account can only have one of attributes among {@code ATTRIBUTE_DATA_ORIGIN_LOCAL}, * {@code ATTRIBUTE_DATA_ORIGIN_SIM} and {@code ATTRIBUTE_DATA_ORIGIN_CLOUD}. */ public static final long ATTRIBUTE_DATA_ORIGIN_LOCAL = 1L; /** * Indicates that contacts associated with this account are stored directly on the SIM * card. * * An account can only have one of attributes among * {@code ATTRIBUTE_DATA_ORIGIN_LOCAL}, * * {@code ATTRIBUTE_DATA_ORIGIN_SIM} and {@code ATTRIBUTE_DATA_ORIGIN_CLOUD}. */ public static final long ATTRIBUTE_DATA_ORIGIN_SIM = 1L << 1; /** * Indicates that the primary, canonical storage location and authoritative source * for contacts associated with this account is a cloud service. This applies * regardless of whether contacts were initially created on the device and then * synchronized to the cloud, or if they were created directly in the cloud and * downloaded to the device. The cloud serves as the central hub for persistence * and synchronization across devices. * An account can only have one of attributes among {@code ATTRIBUTE_DATA_ORIGIN_LOCAL}, * {@code ATTRIBUTE_DATA_ORIGIN_SIM} and {@code ATTRIBUTE_DATA_ORIGIN_CLOUD}. */ public static final long ATTRIBUTE_DATA_ORIGIN_CLOUD = 1 << 2; /** * Indicates that contacts associated with this account are synchronized * from the device to the cloud. Local changes (creations, edits, deletions) * are uploaded to the authoritative source. * A two-way sync accounts have both {@code ATTRIBUTE_SYNC_MODE_UP_SYNC} and * {@code ATTRIBUTE_SYNC_MODE_DOWN_SYNC} attributes. */ public static final long ATTRIBUTE_SYNC_MODE_UP_SYNC = 1L << 3; /** * Indicates that contacts associated with this account are * synchronized from a cloud account to the device. Local * changes (creations, edits, deletions) are generally not uploaded * to the cloud via this sync mechanism. * A two-way sync account has both {@code ATTRIBUTE_SYNC_MODE_UP_SYNC} and * {@code ATTRIBUTE_SYNC_MODE_DOWN_SYNC} attributes. */ public static final long ATTRIBUTE_SYNC_MODE_DOWN_SYNC = 1L << 4; /** * Indicates that this account has declared custom or non-standard * contact data fields (e.g., those defined via custom MIME types in `contacts.xml` * or other extensibility mechanisms). This data often provides supplementary * information and may not be directly user-editable via the standard Contacts app. */ public static final long ATTRIBUTE_DATA_TYPE_CUSTOM_DECLARED = 1L << 5; /** * @hide */ @LongDef(flag = true, value = { ATTRIBUTE_DATA_ORIGIN_LOCAL, ATTRIBUTE_DATA_ORIGIN_SIM, ATTRIBUTE_DATA_ORIGIN_CLOUD, ATTRIBUTE_SYNC_MODE_UP_SYNC, ATTRIBUTE_SYNC_MODE_DOWN_SYNC, ATTRIBUTE_DATA_TYPE_CUSTOM_DECLARED }) @Retention(RetentionPolicy.SOURCE) public @interface AttributeFlags { } } /** * Returns the attributes of a given account as a 64-bit bitmask. * * <p>A return value of {@code 0L} indicates the account exists but has no specific * attributes enabled or set. * * @param resolver The {@link ContentResolver} to use for the query. * @param account The account to query. If {@code null}, this will query the * attributes of the local, device-only account. * @param dataSet The data set specific to the account type, which may be {@code null}. * @return A {@code long} representing the attributes bitmask. * @throws IllegalStateException if the specified account does not exist or its * attributes could not be determined. */ @FlaggedApi(Flags.FLAG_NEW_ACCOUNT_ATTRIBUTES_API_ENABLED) @RequiresPermission(android.Manifest.permission.READ_CONTACTS) public static @AccountAttributes.AttributeFlags long getAccountAttributes( @NonNull ContentResolver resolver, @Nullable Account account, @Nullable String dataSet) { Bundle extras = new Bundle(); if (account != null) { extras.putString(ACCOUNT_NAME, account.name); extras.putString(ACCOUNT_TYPE, account.type); } if (!TextUtils.isEmpty(dataSet)) { extras.putString(DATA_SET, dataSet); } Bundle response = nullSafeCall(resolver, ContactsContract.AUTHORITY_URI, GET_ACCOUNT_ATTRIBUTES_METHOD, null, extras); if (response == null || !response.containsKey(KEY_ACCOUNT_ATTRIBUTES)) { throw new IllegalStateException(String.format( "Could not determine attributes for account: %s, data_set: %s", account, dataSet)); } return response.getLong(KEY_ACCOUNT_ATTRIBUTES); } /** * Sets the attributes for a given account with a new set of flags. * * <p><b>Warning:</b> This is a destructive operation. Any attributes previously * set on the account will be cleared and replaced by the provided {@code newAttributes}. * * <p>The provided bitmask must be valid and free of semantic conflicts (e.g., * containing more than one {@code DATA_ORIGIN} type). * * <h4>Security</h4> * <p> This method requires that the calling application to be the authenticator * for the account's type. * @see android.accounts.AccountManager#getAuthenticatorTypes() * * @param resolver The {@code ContentResolver} to use for the update. * @param account The target account. If {@code null}, this operation applies to the * local, device-only account. * @param dataSet The data set within the account, which may be {@code null}. * @param newAttributes The complete new bitmask of attributes to apply. * @throws IllegalArgumentException if {@code newAttributes} contains any undefined * bits, has semantic conflicts, or the account is * otherwise invalid. */ @FlaggedApi(Flags.FLAG_NEW_ACCOUNT_ATTRIBUTES_API_ENABLED) @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) public static void setAccountAttributes(@NonNull ContentResolver resolver, @Nullable Account account, @Nullable String dataSet, @AccountAttributes.AttributeFlags long newAttributes) { Bundle extras = new Bundle(); if (account != null) { extras.putString(ACCOUNT_NAME, account.name); extras.putString(ACCOUNT_TYPE, account.type); } if (!TextUtils.isEmpty(dataSet)) { extras.putString(DATA_SET, dataSet); } extras.putLong(KEY_ACCOUNT_ATTRIBUTES, newAttributes); nullSafeCall(resolver, ContactsContract.AUTHORITY_URI, SET_ACCOUNT_ATTRIBUTES_METHOD, null, extras); } } /** Loading
core/java/android/provider/flags.aconfig +9 −0 Original line number Diff line number Diff line Loading @@ -87,3 +87,12 @@ flag { description: "Feature flag to expose SYSTEM_UPDATE_SETTINGS as a public API" bug: "417458670" } # OWNER = liefuliu flag { name: "new_account_attributes_api_enabled" is_exported: true namespace: "contacts" description: "Enable the new Account Attributes APIs for contacts" bug: "330326187" } No newline at end of file