/* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.provider; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; /** * E2eeContactKeysManager provides access to the provider of end-to-end encryption contact keys. * It manages two types of keys - {@link E2eeContactKey} and {@link E2eeSelfKey}. *
* An opaque value that contains hints on how to find the contact if * its row id changed as a result of a sync or aggregation. *
*/ public static final String LOOKUP_KEY = "lookup"; /** ** An app-specified identifier for the device for which the end-to-end encryption * contact key can be used. *
*/ public static final String DEVICE_ID = "device_id"; /** ** An app-specified identifier for the account for which the end-to-end encryption * contact key can be used. * Usually a phone number. *
*/ public static final String ACCOUNT_ID = "account_id"; /** ** The display name for the contact. *
*/ public static final String DISPLAY_NAME = "display_name"; /** ** The phone number as the user entered it. *
*/ public static final String PHONE_NUMBER = "number"; /** ** The email address. *
*/ public static final String EMAIL_ADDRESS = "address"; /** ** Timestamp at which the key was updated. *
*/ public static final String TIME_UPDATED = "time_updated"; /** ** The raw bytes for the key. *
*/ public static final String KEY_VALUE = "key_value"; /** ** The package name of the package that created the key. *
*/ public static final String OWNER_PACKAGE_NAME = "owner_package_name"; /** ** Describes the local verification state for the key, for instance QR-code based * verification. *
*/ public static final String LOCAL_VERIFICATION_STATE = "local_verification_state"; /** ** Describes the remote verification state for the key, for instance through a key * transparency server. *
*/ public static final String REMOTE_VERIFICATION_STATE = "remote_verification_state"; /** * The method to invoke in order to add a new key for a contact. */ public static final String UPDATE_OR_INSERT_CONTACT_KEY_METHOD = "updateOrInsertContactKey"; /** * The method to invoke in order to retrieve key for a single contact. */ public static final String GET_CONTACT_KEY_METHOD = "getContactKey"; /** * The method to invoke in order to retrieve all end-to-end encryption contact keys. */ public static final String GET_ALL_CONTACT_KEYS_METHOD = "getAllContactKeys"; /** * The method to invoke in order to retrieve end-to-end encryption contact keys that belong * to the caller. */ public static final String GET_OWNER_CONTACT_KEYS_METHOD = "getOwnerContactKeys"; /** * The method to invoke in order to update an end-to-end encryption contact key local * verification state. */ public static final String UPDATE_CONTACT_KEY_LOCAL_VERIFICATION_STATE_METHOD = "updateContactKeyLocalVerificationState"; /** * The method to invoke in order to update an end-to-end encryption contact key remote * verification state. */ public static final String UPDATE_CONTACT_KEY_REMOTE_VERIFICATION_STATE_METHOD = "updateContactKeyRemoteVerificationState"; /** * The method to invoke in order to remove a end-to-end encryption contact key. */ public static final String REMOVE_CONTACT_KEY_METHOD = "removeContactKey"; /** * The method to invoke in order to add a new self key. */ public static final String UPDATE_OR_INSERT_SELF_KEY_METHOD = "updateOrInsertSelfKey"; /** * The method to invoke in order to update a self key remote verification state. */ public static final String UPDATE_SELF_KEY_REMOTE_VERIFICATION_STATE_METHOD = "updateSelfKeyRemoteVerificationState"; /** * The method to invoke in order to retrieve a self key. */ public static final String GET_SELF_KEY_METHOD = "getSelfKey"; /** * The method to invoke in order to retrieve all self keys. */ public static final String GET_ALL_SELF_KEYS_METHOD = "getAllSelfKeys"; /** * The method to invoke in order to retrieve self keys that belong to the caller. */ public static final String GET_OWNER_SELF_KEYS_METHOD = "getOwnerSelfKeys"; /** * The method to invoke in order to remove a new self key. */ public static final String REMOVE_SELF_KEY_METHOD = "removeSelfKey"; /** * Key in the incoming Bundle for all the end-to-end encryption contact keys. */ public static final String KEY_CONTACT_KEYS = "key_contact_keys"; /** * Key in the incoming Bundle for a single end-to-end encryption contact key. */ public static final String KEY_CONTACT_KEY = "key_contact_key"; /** * Key in the incoming Bundle for a number of modified rows. */ public static final String KEY_UPDATED_ROWS = "key_updated_rows"; } /** * A parcelable class encapsulating other users' end to end encrypted contact key. */ public static final class E2eeContactKey extends E2eeBaseKey implements Parcelable { /** * Describes the local verification state for the key, for instance QR-code based * verification. */ private final int mLocalVerificationState; /** * The display name for the contact. */ private final String mDisplayName; /** * The phone number as the user entered it. */ private final String mPhoneNumber; /** * The email address. */ private final String mEmailAddress; /** * @hide */ public E2eeContactKey(@Nullable String deviceId, @NonNull String accountId, @NonNull String ownerPackageName, long timeUpdated, @Nullable byte[] keyValue, @VerificationState int localVerificationState, @VerificationState int remoteVerificationState, @Nullable String displayName, @Nullable String phoneNumber, @Nullable String emailAddress) { super(deviceId, accountId, ownerPackageName, timeUpdated, keyValue, remoteVerificationState); this.mLocalVerificationState = localVerificationState; this.mDisplayName = displayName; this.mPhoneNumber = phoneNumber; this.mEmailAddress = emailAddress; } /** * Gets the local verification state for the key, for instance QR-code based verification. * * @return The local verification state for the key. */ public @VerificationState int getLocalVerificationState() { return mLocalVerificationState; } /** * Gets the display name for the contact. * * @return The display name for the contact. */ @Nullable public String getDisplayName() { return mDisplayName; } /** * Gets the phone number as the user entered it. * * @return The phone number as the user entered it. */ @Nullable public String getPhoneNumber() { return mPhoneNumber; } /** * Gets the email address. * * @return The email address. */ @Nullable public String getEmailAddress() { return mEmailAddress; } @Override public int hashCode() { return Objects.hash(mDeviceId, mAccountId, mOwnerPackageName, mTimeUpdated, Arrays.hashCode(mKeyValue), mLocalVerificationState, mRemoteVerificationState, mDisplayName, mPhoneNumber, mEmailAddress); } @Override public boolean equals(Object obj) { if (obj == null) return false; if (obj == this) return true; if (!(obj instanceof E2eeContactKey toCompare)) { return false; } return Objects.equals(mDeviceId, toCompare.mDeviceId) && Objects.equals(mAccountId, toCompare.mAccountId) && Objects.equals(mOwnerPackageName, toCompare.mOwnerPackageName) && mTimeUpdated == toCompare.mTimeUpdated && Arrays.equals(mKeyValue, toCompare.mKeyValue) && mLocalVerificationState == toCompare.mLocalVerificationState && mRemoteVerificationState == toCompare.mRemoteVerificationState && Objects.equals(mDisplayName, toCompare.mDisplayName) && Objects.equals(mPhoneNumber, toCompare.mPhoneNumber) && Objects.equals(mEmailAddress, toCompare.mEmailAddress); } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString8(mDeviceId); dest.writeString8(mAccountId); dest.writeString8(mOwnerPackageName); dest.writeLong(mTimeUpdated); dest.writeInt(mKeyValue != null ? mKeyValue.length : ARRAY_IS_NULL); if (mKeyValue != null) { dest.writeByteArray(mKeyValue); } dest.writeInt(mLocalVerificationState); dest.writeInt(mRemoteVerificationState); dest.writeString8(mDisplayName); dest.writeString8(mPhoneNumber); dest.writeString8(mEmailAddress); } @Override public int describeContents() { return 0; } @NonNull public static final Creator