Merge changes from topics "15_apis", "set_get_properties" am: a11a12ae1d

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2481779

Change-Id: Icf6c2839ecbbd39718e188b424849de4bb5d97ae
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2023-03-11 00:08:51 +00:00
committed by Automerger Merge Worker

View File

@@ -58,6 +58,7 @@ import android.os.UserHandle;
import android.provider.Telephony.SimInfo; import android.provider.Telephony.SimInfo;
import android.telephony.euicc.EuiccManager; import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsMmTelManager; import android.telephony.ims.ImsMmTelManager;
import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
@@ -2591,17 +2592,27 @@ public class SubscriptionManager {
} }
/** /**
* Store properties associated with SubscriptionInfo in database * Set a field in the subscription database. Note not all fields are supported.
* @param subId Subscription Id of Subscription *
* @param propKey Column name in database associated with SubscriptionInfo * @param subscriptionId Subscription Id of Subscription.
* @param propValue Value to store in DB for particular subId & column name * @param columnName Column name in the database. Note not all fields are supported.
* @param value Value to store in the database.
*
* @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
* exposed.
* @throws SecurityException if callers do not hold the required permission.
*
* @see android.provider.Telephony.SimInfo for all the columns.
*
* @hide * @hide
*/ */
public static void setSubscriptionProperty(int subId, String propKey, String propValue) { @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public static void setSubscriptionProperty(int subscriptionId, @NonNull String columnName,
@NonNull String value) {
try { try {
ISub iSub = TelephonyManager.getSubscriptionService(); ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) { if (iSub != null) {
iSub.setSubscriptionProperty(subId, propKey, propValue); iSub.setSubscriptionProperty(subscriptionId, columnName, value);
} }
} catch (RemoteException ex) { } catch (RemoteException ex) {
// ignore it // ignore it
@@ -2630,118 +2641,149 @@ public class SubscriptionManager {
} }
/** /**
* Return list of contacts uri corresponding to query result. * Get specific field in string format from the subscription info database.
* @param subId Subscription Id of Subscription *
* @param propKey Column name in SubscriptionInfo database * @param context The calling context.
* @return list of contacts uri to be returned * @param subscriptionId Subscription id of the subscription.
* @param columnName Column name in subscription database.
*
* @return Value in string format associated with {@code subscriptionId} and {@code columnName}
* from the database.
*
* @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
* exposed.
*
* @see android.provider.Telephony.SimInfo for all the columns.
*
* @hide * @hide
*/ */
private static List<Uri> getContactsFromSubscriptionProperty(int subId, String propKey, @NonNull
Context context) { @RequiresPermission(anyOf = {
String result = getSubscriptionProperty(subId, propKey, context); Manifest.permission.READ_PHONE_STATE,
if (result != null) { Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
try { "carrier privileges",
byte[] b = Base64.decode(result, Base64.DEFAULT); })
ByteArrayInputStream bis = new ByteArrayInputStream(b); private static String getStringSubscriptionProperty(@NonNull Context context,
ObjectInputStream ois = new ObjectInputStream(bis); int subscriptionId, @NonNull String columnName) {
List<String> contacts = ArrayList.class.cast(ois.readObject());
List<Uri> uris = new ArrayList<>();
for (String contact : contacts) {
uris.add(Uri.parse(contact));
}
return uris;
} catch (IOException e) {
logd("getContactsFromSubscriptionProperty IO exception");
} catch (ClassNotFoundException e) {
logd("getContactsFromSubscriptionProperty ClassNotFound exception");
}
}
return new ArrayList<>();
}
/**
* Store properties associated with SubscriptionInfo in database
* @param subId Subscription Id of Subscription
* @param propKey Column name in SubscriptionInfo database
* @return Value associated with subId and propKey column in database
* @hide
*/
private static String getSubscriptionProperty(int subId, String propKey,
Context context) {
String resultValue = null; String resultValue = null;
try { try {
ISub iSub = TelephonyManager.getSubscriptionService(); ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) { if (iSub != null) {
resultValue = iSub.getSubscriptionProperty(subId, propKey, resultValue = iSub.getSubscriptionProperty(subscriptionId, columnName,
context.getOpPackageName(), context.getAttributionTag()); context.getOpPackageName(), context.getAttributionTag());
} }
} catch (RemoteException ex) { } catch (RemoteException ex) {
// ignore it // ignore it
} }
return resultValue; return TextUtils.emptyIfNull(resultValue);
} }
/** /**
* Returns boolean value corresponding to query result. * Get specific field in {@code boolean} format from the subscription info database.
* @param subId Subscription Id of Subscription *
* @param propKey Column name in SubscriptionInfo database * @param subscriptionId Subscription id of the subscription.
* @param defValue Default boolean value to be returned * @param columnName Column name in subscription database.
* @return boolean result value to be returned * @param defaultValue Default value in case not found or error.
* @param context The calling context.
*
* @return Value in {@code boolean} format associated with {@code subscriptionId} and
* {@code columnName} from the database, or {@code defaultValue} if not found or error.
*
* @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
* exposed.
*
* @see android.provider.Telephony.SimInfo for all the columns.
*
* @hide * @hide
*/ */
public static boolean getBooleanSubscriptionProperty(int subId, String propKey, @RequiresPermission(anyOf = {
boolean defValue, Context context) { Manifest.permission.READ_PHONE_STATE,
String result = getSubscriptionProperty(subId, propKey, context); Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
if (result != null) { "carrier privileges",
})
public static boolean getBooleanSubscriptionProperty(int subscriptionId,
@NonNull String columnName, boolean defaultValue, @NonNull Context context) {
String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
if (!result.isEmpty()) {
try { try {
return Integer.parseInt(result) == 1; return Integer.parseInt(result) == 1;
} catch (NumberFormatException err) { } catch (NumberFormatException err) {
logd("getBooleanSubscriptionProperty NumberFormat exception"); logd("getBooleanSubscriptionProperty NumberFormat exception");
} }
} }
return defValue; return defaultValue;
} }
/** /**
* Returns integer value corresponding to query result. * Get specific field in {@code integer} format from the subscription info database.
* @param subId Subscription Id of Subscription *
* @param propKey Column name in SubscriptionInfo database * @param subscriptionId Subscription id of the subscription.
* @param defValue Default integer value to be returned * @param columnName Column name in subscription database.
* @return integer result value to be returned * @param defaultValue Default value in case not found or error.
* @param context The calling context.
*
* @return Value in {@code integer} format associated with {@code subscriptionId} and
* {@code columnName} from the database, or {@code defaultValue} if not found or error.
*
* @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
* exposed.
*
* @see android.provider.Telephony.SimInfo for all the columns.
*
* @hide * @hide
*/ */
public static int getIntegerSubscriptionProperty(int subId, String propKey, int defValue, @RequiresPermission(anyOf = {
Context context) { Manifest.permission.READ_PHONE_STATE,
String result = getSubscriptionProperty(subId, propKey, context); Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
if (result != null) { "carrier privileges",
})
public static int getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName,
int defaultValue, @NonNull Context context) {
String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
if (!result.isEmpty()) {
try { try {
return Integer.parseInt(result); return Integer.parseInt(result);
} catch (NumberFormatException err) { } catch (NumberFormatException err) {
logd("getIntegerSubscriptionProperty NumberFormat exception"); logd("getIntegerSubscriptionProperty NumberFormat exception");
} }
} }
return defValue; return defaultValue;
} }
/** /**
* Returns long value corresponding to query result. * Get specific field in {@code long} format from the subscription info database.
* @param subId Subscription Id of Subscription *
* @param propKey Column name in SubscriptionInfo database * @param subscriptionId Subscription id of the subscription.
* @param defValue Default long value to be returned * @param columnName Column name in subscription database.
* @return long result value to be returned * @param defaultValue Default value in case not found or error.
* @param context The calling context.
*
* @return Value in {@code long} format associated with {@code subscriptionId} and
* {@code columnName} from the database, or {@code defaultValue} if not found or error.
*
* @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
* exposed.
*
* @see android.provider.Telephony.SimInfo for all the columns.
*
* @hide * @hide
*/ */
public static long getLongSubscriptionProperty(int subId, String propKey, long defValue, @RequiresPermission(anyOf = {
Context context) { Manifest.permission.READ_PHONE_STATE,
String result = getSubscriptionProperty(subId, propKey, context); Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
if (result != null) { "carrier privileges",
})
public static long getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName,
long defaultValue, @NonNull Context context) {
String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
if (!result.isEmpty()) {
try { try {
return Long.parseLong(result); return Long.parseLong(result);
} catch (NumberFormatException err) { } catch (NumberFormatException err) {
logd("getLongSubscriptionProperty NumberFormat exception"); logd("getLongSubscriptionProperty NumberFormat exception");
} }
} }
return defValue; return defaultValue;
} }
/** /**
@@ -3469,7 +3511,6 @@ public class SubscriptionManager {
* @param groupUuid of which list of subInfo will be returned. * @param groupUuid of which list of subInfo will be returned.
* @return list of subscriptionInfo that belong to the same group, including the given * @return list of subscriptionInfo that belong to the same group, including the given
* subscription itself. It will return an empty list if no subscription belongs to the group. * subscription itself. It will return an empty list if no subscription belongs to the group.
*
*/ */
@SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(Manifest.permission.READ_PHONE_STATE) @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
@@ -3509,7 +3550,8 @@ public class SubscriptionManager {
* want to see their own hidden subscriptions. * want to see their own hidden subscriptions.
* *
* @param info the subscriptionInfo to check against. * @param info the subscriptionInfo to check against.
* @return true if this subscription should be visible to the API caller. *
* @return {@code true} if this subscription should be visible to the API caller.
* *
* @hide * @hide
*/ */
@@ -3582,9 +3624,9 @@ public class SubscriptionManager {
* <p> * <p>
* Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
* *
* @param subscriptionId Subscription to be enabled or disabled. It could be a eSIM or pSIM
* subscription.
* @param enable whether user is turning it on or off. * @param enable whether user is turning it on or off.
* @param subscriptionId Subscription to be enabled or disabled.
* It could be a eSIM or pSIM subscription.
* *
* @return whether the operation is successful. * @return whether the operation is successful.
* *
@@ -3617,8 +3659,6 @@ public class SubscriptionManager {
* available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated * available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated
* immediately.) * immediately.)
* *
* Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
*
* @param subscriptionId which subscription to operate on. * @param subscriptionId which subscription to operate on.
* @param enabled whether uicc applications are enabled or disabled. * @param enabled whether uicc applications are enabled or disabled.
* @hide * @hide
@@ -3651,8 +3691,6 @@ public class SubscriptionManager {
* It provides whether a physical SIM card can be disabled without taking it out, which is done * It provides whether a physical SIM card can be disabled without taking it out, which is done
* via {@link #setSubscriptionEnabled(int, boolean)} API. * via {@link #setSubscriptionEnabled(int, boolean)} API.
* *
* Requires Permission: READ_PRIVILEGED_PHONE_STATE.
*
* @return whether can disable subscriptions on physical SIMs. * @return whether can disable subscriptions on physical SIMs.
* *
* @hide * @hide
@@ -3680,13 +3718,9 @@ public class SubscriptionManager {
} }
/** /**
* Check if a subscription is active. * Check if the subscription is currently active in any slot.
* *
* @param subscriptionId The subscription id to check. * @param subscriptionId The subscription id.
*
* @return {@code true} if the subscription is active.
*
* @throws IllegalArgumentException if the provided slot index is invalid.
* *
* @hide * @hide
*/ */
@@ -3706,15 +3740,14 @@ public class SubscriptionManager {
} }
/** /**
* Set the device to device status sharing user preference for a subscription ID. The setting * Set the device to device status sharing user preference for a subscription id. The setting
* app uses this method to indicate with whom they wish to share device to device status * app uses this method to indicate with whom they wish to share device to device status
* information. * information.
* *
* @param subscriptionId the unique Subscription ID in database. * @param subscriptionId The subscription id.
* @param sharing the status sharing preference. * @param sharing The status sharing preference.
* *
* @throws IllegalArgumentException if the subscription does not exist, or the sharing * @throws SecurityException if the caller doesn't have permissions required.
* preference is invalid.
*/ */
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setDeviceToDeviceStatusSharingPreference(int subscriptionId, public void setDeviceToDeviceStatusSharingPreference(int subscriptionId,
@@ -3731,6 +3764,8 @@ public class SubscriptionManager {
* Returns the user-chosen device to device status sharing preference * Returns the user-chosen device to device status sharing preference
* @param subscriptionId Subscription id of subscription * @param subscriptionId Subscription id of subscription
* @return The device to device status sharing preference * @return The device to device status sharing preference
*
* @throws SecurityException if the caller doesn't have permissions required.
*/ */
public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference( public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference(
int subscriptionId) { int subscriptionId) {
@@ -3742,15 +3777,14 @@ public class SubscriptionManager {
} }
/** /**
* Set the list of contacts that allow device to device status sharing for a subscription ID. * Set the list of contacts that allow device to device status sharing for a subscription id.
* The setting app uses this method to indicate with whom they wish to share device to device * The setting app uses this method to indicate with whom they wish to share device to device
* status information. * status information.
* *
* @param subscriptionId The unique Subscription ID in database. * @param subscriptionId The subscription id.
* @param contacts The list of contacts that allow device to device status sharing. * @param contacts The list of contacts that allow device to device status sharing.
* *
* @throws IllegalArgumentException if the subscription does not exist, or contacts is * @throws SecurityException if the caller doesn't have permissions required.
* {@code null}.
*/ */
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setDeviceToDeviceStatusSharingContacts(int subscriptionId, public void setDeviceToDeviceStatusSharingContacts(int subscriptionId,
@@ -3766,38 +3800,46 @@ public class SubscriptionManager {
} }
/** /**
* Returns the list of contacts that allow device to device status sharing. * Get the list of contacts that allow device to device status sharing.
* @param subscriptionId Subscription id of subscription *
* @return The list of contacts that allow device to device status sharing * @param subscriptionId Subscription id.
*
* @return The list of contacts that allow device to device status sharing.
*/ */
public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts( public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(int subscriptionId) {
int subscriptionId) { String result = getStringSubscriptionProperty(mContext, subscriptionId,
if (VDBG) { D2D_STATUS_SHARING_SELECTED_CONTACTS);
logd("[getDeviceToDeviceStatusSharingContacts] + subId: " + subscriptionId); if (result != null) {
try {
byte[] b = Base64.decode(result, Base64.DEFAULT);
ByteArrayInputStream bis = new ByteArrayInputStream(b);
ObjectInputStream ois = new ObjectInputStream(bis);
List<String> contacts = ArrayList.class.cast(ois.readObject());
List<Uri> uris = new ArrayList<>();
for (String contact : contacts) {
uris.add(Uri.parse(contact));
}
return uris;
} catch (IOException e) {
logd("getDeviceToDeviceStatusSharingContacts IO exception");
} catch (ClassNotFoundException e) {
logd("getDeviceToDeviceStatusSharingContacts ClassNotFound exception");
}
} }
return getContactsFromSubscriptionProperty(subscriptionId, return new ArrayList<>();
D2D_STATUS_SHARING_SELECTED_CONTACTS, mContext);
} }
/** /**
* Get the active subscription id by logical SIM slot index. * DO NOT USE.
* * This API is designed for features that are not finished at this point. Do not call this API.
* @param slotIndex The logical SIM slot index.
* @return The active subscription id.
*
* @throws IllegalArgumentException if the provided slot index is invalid.
*
* @hide * @hide
* TODO b/135547512: further clean up
*/ */
@SystemApi @SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public int getEnabledSubscriptionId(int slotIndex) { public int getEnabledSubscriptionId(int slotIndex) {
int subId = INVALID_SUBSCRIPTION_ID; int subId = INVALID_SUBSCRIPTION_ID;
if (!isValidSlotIndex(slotIndex)) {
throw new IllegalArgumentException("Invalid slot index " + slotIndex);
}
try { try {
ISub iSub = TelephonyManager.getSubscriptionService(); ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) { if (iSub != null) {
@@ -3839,7 +3881,7 @@ public class SubscriptionManager {
/** /**
* Get active data subscription id. Active data subscription refers to the subscription * Get active data subscription id. Active data subscription refers to the subscription
* currently chosen to provide cellular internet connection to the user. This may be * currently chosen to provide cellular internet connection to the user. This may be
* different from getDefaultDataSubscriptionId(). * different from {@link #getDefaultDataSubscriptionId()}.
* *
* @return Active data subscription id if any is chosen, or {@link #INVALID_SUBSCRIPTION_ID} if * @return Active data subscription id if any is chosen, or {@link #INVALID_SUBSCRIPTION_ID} if
* not. * not.