OSDN Git Service

Migrate plans to @SystemApi, evolve permissions.
authorJeff Sharkey <jsharkey@android.com>
Fri, 28 Jul 2017 22:55:41 +0000 (16:55 -0600)
committerJeff Sharkey <jsharkey@android.com>
Fri, 28 Jul 2017 22:59:14 +0000 (16:59 -0600)
We're not yet ready to commit to SubscriptionPlan as public API, so
relax to be @SystemApi instead.  Add a new MANAGE_SUBSCRIPTION_PLANS
permission that we require apps to hold, unless they've been
delegated access via a trusted CarrierService.

Since several apps have the ability to provide plans for a single
subId, we now remember the "owner" who set the current plan
information, and we refuse to leak plan information beyond the app
that originally set it.

Relax permissions check to not require READ_PHONE_STATE, since we're
only returning data that an app provided to us earlier.  Also fix
NPE when SubscriptionInfo is missing.

Test: bit FrameworksServicesTests:com.android.server.NetworkPolicyManagerServiceTest
Bug: 63997177639282776415613863903381
Change-Id: If503378ef406dcaec438c9b41e837e0a821a3ef4

api/current.txt
api/system-current.txt
api/test-current.txt
core/java/android/os/UserHandle.java
core/res/AndroidManifest.xml
services/core/java/com/android/server/net/NetworkPolicyManagerService.java
telephony/java/android/telephony/CarrierConfigManager.java
telephony/java/android/telephony/SubscriptionManager.java
telephony/java/android/telephony/SubscriptionPlan.java

index b4c6089..4db5cee 100644 (file)
@@ -39538,7 +39538,7 @@ package android.telephony {
     method public android.os.PersistableBundle getConfigForSubId(int);
     method public void notifyConfigChangedForSubId(int);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
-    field public static final deprecated int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
+    field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
     field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
     field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final java.lang.String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -39580,10 +39580,9 @@ package android.telephony {
     field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING = "ci_action_on_sys_update_extra_val_string";
     field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING = "ci_action_on_sys_update_intent_string";
     field public static final java.lang.String KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING = "config_ims_package_override_string";
-    field public static final java.lang.String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string";
     field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
-    field public static final deprecated java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
-    field public static final deprecated java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
+    field public static final java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
+    field public static final java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
     field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
     field public static final java.lang.String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
     field public static final java.lang.String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
@@ -39640,7 +39639,7 @@ package android.telephony {
     field public static final java.lang.String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName";
     field public static final java.lang.String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
     field public static final java.lang.String KEY_MMS_USER_AGENT_STRING = "userAgent";
-    field public static final deprecated java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
+    field public static final java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
     field public static final java.lang.String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array";
     field public static final java.lang.String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
     field public static final java.lang.String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
@@ -40152,10 +40151,8 @@ package android.telephony {
     method public static int getDefaultSmsSubscriptionId();
     method public static int getDefaultSubscriptionId();
     method public static int getDefaultVoiceSubscriptionId();
-    method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
     method public boolean isNetworkRoaming(int);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
-    method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
     field public static final java.lang.String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
     field public static final java.lang.String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
     field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
@@ -40169,38 +40166,6 @@ package android.telephony {
     method public void onSubscriptionsChanged();
   }
 
-  public final class SubscriptionPlan implements android.os.Parcelable {
-    method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
-    method public int describeContents();
-    method public int getDataLimitBehavior();
-    method public long getDataLimitBytes();
-    method public long getDataUsageBytes();
-    method public long getDataUsageTime();
-    method public java.lang.CharSequence getSummary();
-    method public java.lang.CharSequence getTitle();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final long BYTES_UNKNOWN = -1L; // 0xffffffffffffffffL
-    field public static final long BYTES_UNLIMITED = 9223372036854775807L; // 0x7fffffffffffffffL
-    field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionPlan> CREATOR;
-    field public static final int LIMIT_BEHAVIOR_BILLED = 1; // 0x1
-    field public static final int LIMIT_BEHAVIOR_DISABLED = 0; // 0x0
-    field public static final int LIMIT_BEHAVIOR_THROTTLED = 2; // 0x2
-    field public static final int LIMIT_BEHAVIOR_UNKNOWN = -1; // 0xffffffff
-    field public static final long TIME_UNKNOWN = -1L; // 0xffffffffffffffffL
-  }
-
-  public static class SubscriptionPlan.Builder {
-    method public android.telephony.SubscriptionPlan build();
-    method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
-    method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
-    method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
-    method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
-    method public android.telephony.SubscriptionPlan.Builder setTitle(java.lang.CharSequence);
-  }
-
   public class TelephonyManager {
     method public boolean canChangeDtmfToneLength();
     method public android.telephony.TelephonyManager createForPhoneAccountHandle(android.telecom.PhoneAccountHandle);
index 57bf4b4..41f6353 100644 (file)
@@ -149,6 +149,7 @@ package android {
     field public static final java.lang.String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS";
     field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
     field public static final java.lang.String MANAGE_OWN_CALLS = "android.permission.MANAGE_OWN_CALLS";
+    field public static final java.lang.String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS";
     field public static final java.lang.String MANAGE_USB = "android.permission.MANAGE_USB";
     field public static final java.lang.String MANAGE_USERS = "android.permission.MANAGE_USERS";
     field public static final java.lang.String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE";
@@ -43087,7 +43088,7 @@ package android.telephony {
     method public void notifyConfigChangedForSubId(int);
     method public void updateConfigForPhoneId(int, java.lang.String);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
-    field public static final deprecated int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
+    field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
     field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
     field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final java.lang.String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -43131,8 +43132,8 @@ package android.telephony {
     field public static final java.lang.String KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING = "config_ims_package_override_string";
     field public static final java.lang.String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string";
     field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
-    field public static final deprecated java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
-    field public static final deprecated java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
+    field public static final java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
+    field public static final java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
     field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
     field public static final java.lang.String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
     field public static final java.lang.String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
@@ -43189,7 +43190,7 @@ package android.telephony {
     field public static final java.lang.String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName";
     field public static final java.lang.String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
     field public static final java.lang.String KEY_MMS_USER_AGENT_STRING = "userAgent";
-    field public static final deprecated java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
+    field public static final java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
     field public static final java.lang.String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array";
     field public static final java.lang.String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
     field public static final java.lang.String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
index 52a659e..87539ec 100644 (file)
@@ -39789,7 +39789,7 @@ package android.telephony {
     method public android.os.PersistableBundle getConfigForSubId(int);
     method public void notifyConfigChangedForSubId(int);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
-    field public static final deprecated int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
+    field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
     field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
     field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final java.lang.String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -39831,10 +39831,9 @@ package android.telephony {
     field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING = "ci_action_on_sys_update_extra_val_string";
     field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING = "ci_action_on_sys_update_intent_string";
     field public static final java.lang.String KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING = "config_ims_package_override_string";
-    field public static final java.lang.String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string";
     field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
-    field public static final deprecated java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
-    field public static final deprecated java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
+    field public static final java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
+    field public static final java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
     field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
     field public static final java.lang.String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
     field public static final java.lang.String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
@@ -39891,7 +39890,7 @@ package android.telephony {
     field public static final java.lang.String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName";
     field public static final java.lang.String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
     field public static final java.lang.String KEY_MMS_USER_AGENT_STRING = "userAgent";
-    field public static final deprecated java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
+    field public static final java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
     field public static final java.lang.String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array";
     field public static final java.lang.String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
     field public static final java.lang.String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
@@ -40403,10 +40402,8 @@ package android.telephony {
     method public static int getDefaultSmsSubscriptionId();
     method public static int getDefaultSubscriptionId();
     method public static int getDefaultVoiceSubscriptionId();
-    method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
     method public boolean isNetworkRoaming(int);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
-    method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
     field public static final java.lang.String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
     field public static final java.lang.String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
     field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
@@ -40420,38 +40417,6 @@ package android.telephony {
     method public void onSubscriptionsChanged();
   }
 
-  public final class SubscriptionPlan implements android.os.Parcelable {
-    method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
-    method public int describeContents();
-    method public int getDataLimitBehavior();
-    method public long getDataLimitBytes();
-    method public long getDataUsageBytes();
-    method public long getDataUsageTime();
-    method public java.lang.CharSequence getSummary();
-    method public java.lang.CharSequence getTitle();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final long BYTES_UNKNOWN = -1L; // 0xffffffffffffffffL
-    field public static final long BYTES_UNLIMITED = 9223372036854775807L; // 0x7fffffffffffffffL
-    field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionPlan> CREATOR;
-    field public static final int LIMIT_BEHAVIOR_BILLED = 1; // 0x1
-    field public static final int LIMIT_BEHAVIOR_DISABLED = 0; // 0x0
-    field public static final int LIMIT_BEHAVIOR_THROTTLED = 2; // 0x2
-    field public static final int LIMIT_BEHAVIOR_UNKNOWN = -1; // 0xffffffff
-    field public static final long TIME_UNKNOWN = -1L; // 0xffffffffffffffffL
-  }
-
-  public static class SubscriptionPlan.Builder {
-    method public android.telephony.SubscriptionPlan build();
-    method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
-    method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
-    method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
-    method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
-    method public android.telephony.SubscriptionPlan.Builder setTitle(java.lang.CharSequence);
-  }
-
   public class TelephonyManager {
     method public boolean canChangeDtmfToneLength();
     method public android.telephony.TelephonyManager createForPhoneAccountHandle(android.telecom.PhoneAccountHandle);
index 6a4fef2..e8ebf63 100644 (file)
@@ -158,6 +158,11 @@ public final class UserHandle implements Parcelable {
     }
 
     /** @hide */
+    public static @AppIdInt int getCallingAppId() {
+        return getAppId(Binder.getCallingUid());
+    }
+
+    /** @hide */
     @SystemApi
     public static UserHandle of(@UserIdInt int userId) {
         return userId == USER_SYSTEM ? SYSTEM : new UserHandle(userId);
index aa98bac..f7e9b6d 100644 (file)
     <permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi @hide Allows an application to manage carrier subscription plans. -->
+    <permission android:name="android.permission.MANAGE_SUBSCRIPTION_PLANS"
+        android:protectionLevel="signature|privileged" />
+
     <!-- C2DM permission.
          @hide Used internally.
      -->
index f70486a..cfdbb01 100644 (file)
@@ -19,6 +19,7 @@ package com.android.server.net;
 import static android.Manifest.permission.ACCESS_NETWORK_STATE;
 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
 import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
+import static android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS;
 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
 import static android.Manifest.permission.READ_PHONE_STATE;
 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
@@ -311,6 +312,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
     private static final String ATTR_LIMIT_BEHAVIOR = "limitBehavior";
     private static final String ATTR_USAGE_BYTES = "usageBytes";
     private static final String ATTR_USAGE_TIME = "usageTime";
+    private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
 
     private static final String ACTION_ALLOW_BACKGROUND =
             "com.android.server.net.action.ALLOW_BACKGROUND";
@@ -372,8 +374,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
     /** Currently active network rules for ifaces. */
     final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>();
 
-    /** Defined subscription plans. */
+    /** Map from subId to subscription plans. */
     final SparseArray<SubscriptionPlan[]> mSubscriptionPlans = new SparseArray<>();
+    /** Map from subId to package name that owns subscription plans. */
+    final SparseArray<String> mSubscriptionPlansOwner = new SparseArray<>();
 
     /** Defined UID policies. */
     @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray();
@@ -1761,6 +1765,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
         // clear any existing policy and read from disk
         mNetworkPolicy.clear();
         mSubscriptionPlans.clear();
+        mSubscriptionPlansOwner.clear();
         mUidPolicy.clear();
 
         FileInputStream fis = null;
@@ -1902,6 +1907,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                         mSubscriptionPlans.put(subId, ArrayUtils.appendElement(
                                 SubscriptionPlan.class, mSubscriptionPlans.get(subId), plan));
 
+                        final String ownerPackage = readStringAttribute(in, ATTR_OWNER_PACKAGE);
+                        mSubscriptionPlansOwner.put(subId, ownerPackage);
+
                     } else if (TAG_UID_POLICY.equals(tag)) {
                         final int uid = readIntAttribute(in, ATTR_UID);
                         final int policy = readIntAttribute(in, ATTR_POLICY);
@@ -2074,12 +2082,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
             // write all known subscription plans
             for (int i = 0; i < mSubscriptionPlans.size(); i++) {
                 final int subId = mSubscriptionPlans.keyAt(i);
+                final String ownerPackage = mSubscriptionPlansOwner.get(subId);
                 final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
                 if (ArrayUtils.isEmpty(plans)) continue;
 
                 for (SubscriptionPlan plan : plans) {
                     out.startTag(null, TAG_SUBSCRIPTION_PLAN);
                     writeIntAttribute(out, ATTR_SUB_ID, subId);
+                    writeStringAttribute(out, ATTR_OWNER_PACKAGE, ownerPackage);
                     final RecurrenceRule cycleRule = plan.getCycleRule();
                     writeStringAttribute(out, ATTR_CYCLE_START,
                             RecurrenceRule.convertZonedDateTime(cycleRule.start));
@@ -2589,14 +2599,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
         // Verify they're not lying about package name
         mAppOps.checkPackage(callingUid, callingPackage);
 
-        // Verify they have phone permission from user
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
-        if (mAppOps.checkOp(AppOpsManager.OP_READ_PHONE_STATE, callingUid,
-                callingPackage) != AppOpsManager.MODE_ALLOWED) {
-            throw new SecurityException(
-                    "Calling package " + callingPackage + " does not hold " + READ_PHONE_STATE);
-        }
-
         final SubscriptionInfo si;
         final PersistableBundle config;
         final long token = Binder.clearCallingIdentity();
@@ -2609,8 +2611,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
         }
 
         // First check: is caller the CarrierService?
-        if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) {
-            return;
+        if (si != null) {
+            if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) {
+                return;
+            }
         }
 
         // Second check: has the CarrierService delegated access?
@@ -2630,8 +2634,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
             return;
         }
 
-        throw new SecurityException("Calling package " + callingPackage
-                + " has no access to subscription plans for " + subId);
+        // Final check: does the caller hold a permission?
+        mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG);
     }
 
     @Override
@@ -2710,7 +2714,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
 
         synchronized (mUidRulesFirstLock) {
             synchronized (mNetworkPoliciesSecondLock) {
-                return mSubscriptionPlans.get(subId);
+                // Only give out plan details to the package that defined them,
+                // so that we don't risk leaking plans between apps. We always
+                // let in core system components (like the Settings app).
+                final String ownerPackage = mSubscriptionPlansOwner.get(subId);
+                if (Objects.equals(ownerPackage, callingPackage)
+                        || (UserHandle.getCallingAppId() == android.os.Process.SYSTEM_UID)) {
+                    return mSubscriptionPlans.get(subId);
+                } else {
+                    Log.w(TAG, "Not returning plans because caller " + callingPackage
+                            + " doesn't match owner " + ownerPackage);
+                    return null;
+                }
             }
         }
     }
@@ -2729,6 +2744,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
             synchronized (mUidRulesFirstLock) {
                 synchronized (mNetworkPoliciesSecondLock) {
                     mSubscriptionPlans.put(subId, plans);
+                    mSubscriptionPlansOwner.put(subId, callingPackage);
                     // TODO: update any implicit details from newly defined plans
                     handleNetworkPoliciesUpdateAL(false);
                 }
index 0001d42..8368f42 100644 (file)
@@ -269,7 +269,9 @@ public class CarrierConfigManager {
      *
      * @see SubscriptionManager#getSubscriptionPlans(int)
      * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List)
+     * @hide
      */
+    @SystemApi
     public static final String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING =
             "config_plans_package_override_string";
 
@@ -1396,11 +1398,7 @@ public class CarrierConfigManager {
      * <p>
      * This setting may be still overridden by explicit user choice. By default,
      * the platform value will be used.
-     *
-     * @deprecated replaced by
-     *             {@link SubscriptionManager#setSubscriptionPlans(int, java.util.List)}
      */
-    @Deprecated
     public static final String KEY_MONTHLY_DATA_CYCLE_DAY_INT =
             "monthly_data_cycle_day_int";
 
@@ -1425,7 +1423,6 @@ public class CarrierConfigManager {
      * default data limit, if one exists, will be disabled. A user selected data limit will not be
      * overridden.
      */
-    @Deprecated
     public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2;
 
     /**
@@ -1438,11 +1435,7 @@ public class CarrierConfigManager {
      * <p>
      * This setting may be overridden by explicit user choice. By default, the platform value
      * will be used.
-     *
-     * @deprecated replaced by
-     *             {@link SubscriptionManager#setSubscriptionPlans(int, java.util.List)}
      */
-    @Deprecated
     public static final String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG =
             "data_warning_threshold_bytes_long";
 
@@ -1456,11 +1449,7 @@ public class CarrierConfigManager {
      * <p>
      * This setting may be overridden by explicit user choice. By default, the platform value
      * will be used.
-     *
-     * @deprecated replaced by
-     *             {@link SubscriptionManager#setSubscriptionPlans(int, java.util.List)}
      */
-    @Deprecated
     public static final String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG =
             "data_limit_threshold_bytes_long";
 
index 503bf82..5ac368b 100644 (file)
@@ -18,6 +18,7 @@ package android.telephony;
 
 import android.annotation.NonNull;
 import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemService;
 import android.content.Context;
@@ -1555,7 +1556,9 @@ public class SubscriptionManager {
      * </ul>
      *
      * @param subId the subscriber this relationship applies to
+     * @hide
      */
+    @SystemApi
     public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
         final INetworkPolicyManager npm = INetworkPolicyManager.Stub
                 .asInterface(ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
@@ -1583,7 +1586,9 @@ public class SubscriptionManager {
      * @param plans the list of plans. The first plan is always the primary and
      *            most important plan. Any additional plans are secondary and
      *            may not be displayed or used by decision making logic.
+     * @hide
      */
+    @SystemApi
     public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
         final INetworkPolicyManager npm = INetworkPolicyManager.Stub
                 .asInterface(ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
index c9419c5..265e3e7 100644 (file)
@@ -21,6 +21,7 @@ import android.annotation.CurrentTimeMillisLong;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Pair;
@@ -42,7 +43,9 @@ import java.util.Iterator;
  *
  * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List)
  * @see SubscriptionManager#getSubscriptionPlans(int)
+ * @hide
  */
+@SystemApi
 public final class SubscriptionPlan implements Parcelable {
     /** {@hide} */
     @IntDef(prefix = "LIMIT_BEHAVIOR_", value = {