Merge "Check dir path before updating permissions." into sc-v2-dev am: 9d158f2adf
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/providers/TelephonyProvider/+/19734284
Change-Id: If25400e63c7783bf6f4e2b57d454656e6d486bda
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..a3881b9
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.textpb text
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index cd24b24..2bc2fb0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,20 +1,6 @@
package {
- default_applicable_licenses: [
- "packages_providers_TelephonyProvider_license",
- ],
-}
-
-// Added automatically by a large-scale-change
-// See: http://go/android-license-faq
-license {
- name: "packages_providers_TelephonyProvider_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-Apache-2.0",
- ],
- license_text: [
- "NOTICE",
- ],
+ // See: http://go/android-license-faq
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
android_app {
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0a9802d..6633d14 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -19,6 +19,10 @@
coreApp="true"
android:sharedUserId="android.uid.phone">
+ <permission android:name="android.permission.ACCESS_TELEPHONY_SIMINFO_DB"
+ android:label="Read and write SIMINFO table in TelephonyProvider"
+ android:protectionLevel="signature" />
+
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/OWNERS b/OWNERS
index 799e5d3..6927b2e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,15 +1 @@
-amitmahajan@google.com
-breadley@google.com
-fionaxu@google.com
-jackyu@google.com
-rgreenwalt@google.com
-tgunn@google.com
-jminjie@google.com
-shuoq@google.com
-sarahchin@google.com
-xiaotonj@google.com
-huiwang@google.com
-jayachandranc@google.com
-chinmayd@google.com
-amruthr@google.com
-sasindran@google.com
+file:platform/frameworks/opt/telephony:/OWNERS
diff --git a/assets/latest_carrier_id/carrier_list.pb b/assets/latest_carrier_id/carrier_list.pb
index d038016..7c46449 100644
--- a/assets/latest_carrier_id/carrier_list.pb
+++ b/assets/latest_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/latest_carrier_id/carrier_list.textpb b/assets/latest_carrier_id/carrier_list.textpb
index 62398c0..5b521f2 100644
--- a/assets/latest_carrier_id/carrier_list.textpb
+++ b/assets/latest_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/assets/sdk28_carrier_id/carrier_list.pb b/assets/sdk28_carrier_id/carrier_list.pb
index 91d6640..ff06545 100644
--- a/assets/sdk28_carrier_id/carrier_list.pb
+++ b/assets/sdk28_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/sdk28_carrier_id/carrier_list.textpb b/assets/sdk28_carrier_id/carrier_list.textpb
index 0cd3a99..881a66a 100644
--- a/assets/sdk28_carrier_id/carrier_list.textpb
+++ b/assets/sdk28_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/assets/sdk29_carrier_id/carrier_list.pb b/assets/sdk29_carrier_id/carrier_list.pb
index 5e78f39..fd32451 100644
--- a/assets/sdk29_carrier_id/carrier_list.pb
+++ b/assets/sdk29_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/sdk29_carrier_id/carrier_list.textpb b/assets/sdk29_carrier_id/carrier_list.textpb
index 6c1420c..4a2a263 100644
--- a/assets/sdk29_carrier_id/carrier_list.textpb
+++ b/assets/sdk29_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/assets/sdk30_carrier_id/carrier_list.pb b/assets/sdk30_carrier_id/carrier_list.pb
index 946634d..be5d8f5 100644
--- a/assets/sdk30_carrier_id/carrier_list.pb
+++ b/assets/sdk30_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/sdk30_carrier_id/carrier_list.textpb b/assets/sdk30_carrier_id/carrier_list.textpb
index e301ad0..ef71379 100644
--- a/assets/sdk30_carrier_id/carrier_list.textpb
+++ b/assets/sdk30_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/assets/sdk31_carrier_id/carrier_list.pb b/assets/sdk31_carrier_id/carrier_list.pb
new file mode 100644
index 0000000..11e2628
--- /dev/null
+++ b/assets/sdk31_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/sdk31_carrier_id/carrier_list.textpb b/assets/sdk31_carrier_id/carrier_list.textpb
new file mode 100644
index 0000000..fe1806f
--- /dev/null
+++ b/assets/sdk31_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/proto/Android.bp b/proto/Android.bp
index 810e346..2506cae 100644
--- a/proto/Android.bp
+++ b/proto/Android.bp
@@ -14,13 +14,7 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "packages_providers_TelephonyProvider_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: [
- "packages_providers_TelephonyProvider_license",
- ],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
filegroup {
diff --git a/src/com/android/providers/telephony/CarrierDatabaseHelper.java b/src/com/android/providers/telephony/CarrierDatabaseHelper.java
index 0b97da1..3d2de29 100644
--- a/src/com/android/providers/telephony/CarrierDatabaseHelper.java
+++ b/src/com/android/providers/telephony/CarrierDatabaseHelper.java
@@ -28,14 +28,13 @@
public class CarrierDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "CarrierDatabaseHelper";
- private static final boolean DBG = true;
-
private static final String DATABASE_NAME = "CarrierInformation.db";
public static final String CARRIER_KEY_TABLE = "carrier_key";
- private static final int DATABASE_VERSION = 2;
+ private static final int DATABASE_VERSION = 3;
/**
* CarrierDatabaseHelper carrier database helper class.
+ *
* @param context of the user.
*/
public CarrierDatabaseHelper(Context context) {
@@ -46,21 +45,20 @@
public static final String KEY_TYPE = "key_type";
public static final String MCC = "mcc";
public static final String MNC = "mnc";
- public static final String MVNO_TYPE = "mvno_type";
- public static final String MVNO_MATCH_DATA = "mvno_match_data";
+ public static final String CARRIER_ID = "carrier_id";
public static final String PUBLIC_KEY = "public_key";
public static final String KEY_IDENTIFIER = "key_identifier";
public static final String EXPIRATION_TIME = "expiration_time";
public static final String LAST_MODIFIED = "last_modified";
private static final List<String> CARRIERS_UNIQUE_FIELDS = new ArrayList<String>();
+ private static final String TEMPORARY_CARRIER_KEY_TABLE = CARRIER_KEY_TABLE + "_temp";
static {
CARRIERS_UNIQUE_FIELDS.add(MCC);
CARRIERS_UNIQUE_FIELDS.add(MNC);
+ CARRIERS_UNIQUE_FIELDS.add(CARRIER_ID);
CARRIERS_UNIQUE_FIELDS.add(KEY_TYPE);
- CARRIERS_UNIQUE_FIELDS.add(MVNO_TYPE);
- CARRIERS_UNIQUE_FIELDS.add(MVNO_MATCH_DATA);
}
public static String getStringForCarrierKeyTableCreation(String tableName) {
@@ -68,8 +66,7 @@
"(_id INTEGER PRIMARY KEY," +
MCC + " TEXT DEFAULT ''," +
MNC + " TEXT DEFAULT ''," +
- MVNO_TYPE + " TEXT DEFAULT ''," +
- MVNO_MATCH_DATA + " TEXT DEFAULT ''," +
+ CARRIER_ID + " INTEGER DEFAULT -1," +
KEY_TYPE + " TEXT DEFAULT ''," +
KEY_IDENTIFIER + " TEXT DEFAULT ''," +
PUBLIC_KEY + " BLOB DEFAULT ''," +
@@ -93,10 +90,43 @@
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.d(TAG, "dbh.onUpgrade:+ db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
+ Log.d(TAG, "dbh.onUpgrade:db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
if (oldVersion < 2) {
dropCarrierTable(db);
createCarrierTable(db);
+ return;
+ }
+ if (oldVersion < 3) {
+ // Create new table and copy the contents from the existing table
+ renameCarrierTable(db);
+ createCarrierTable(db);
+ copyContents(db);
+ dropTemporaryTable(db);
+ db.execSQL("COMMIT");
+ return;
}
}
-}
+
+ // Renames the existing table as temporary table
+ private void renameCarrierTable(SQLiteDatabase db) {
+ db.execSQL(
+ "ALTER TABLE " + CARRIER_KEY_TABLE + " RENAME TO " + TEMPORARY_CARRIER_KEY_TABLE);
+ }
+
+ // Copies the content from temporary table to new table
+ private void copyContents(SQLiteDatabase db) {
+ String copyStr = new StringBuilder().append("INSERT INTO ").append(
+ CARRIER_KEY_TABLE).append(
+ " (MCC, MNC, KEY_TYPE, KEY_IDENTIFIER, PUBLIC_KEY, "
+ + "EXPIRATION_TIME, LAST_MODIFIED)").append(" SELECT ").append(
+ "MCC, MNC, KEY_TYPE, KEY_IDENTIFIER, PUBLIC_KEY, "
+ + "EXPIRATION_TIME, LAST_MODIFIED").append(" FROM ").append(
+ TEMPORARY_CARRIER_KEY_TABLE).toString();
+ db.execSQL(copyStr);
+ }
+
+ // Drops the temporary table
+ private void dropTemporaryTable(SQLiteDatabase db) {
+ db.execSQL("DROP TABLE IF EXISTS " + TEMPORARY_CARRIER_KEY_TABLE + ";");
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/providers/telephony/MmsProvider.java b/src/com/android/providers/telephony/MmsProvider.java
index 1e33313..5ddd6ac 100644
--- a/src/com/android/providers/telephony/MmsProvider.java
+++ b/src/com/android/providers/telephony/MmsProvider.java
@@ -99,8 +99,13 @@
// or received messages, without wap pushes.
final boolean accessRestricted = ProviderUtil.isAccessRestricted(
getContext(), getCallingPackage(), Binder.getCallingUid());
- final String pduTable = getPduTable(accessRestricted);
+ // If access is restricted, we don't allow subqueries in the query.
+ if (accessRestricted) {
+ SqlQueryChecker.checkQueryParametersForSubqueries(projection, selection, sortOrder);
+ }
+
+ final String pduTable = getPduTable(accessRestricted);
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
// Generate the body of the query.
diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
index a9494fb..73ffa3b 100644
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
@@ -295,7 +295,7 @@
setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
setWriteAheadLoggingEnabled(false);
try {
- PhoneFactory.addLocalLog(TAG, 100);
+ PhoneFactory.addLocalLog(TAG, 64);
} catch (IllegalArgumentException e) {
// ignore
}
@@ -1657,7 +1657,7 @@
} finally {
db.endTransaction();
}
- // fall through
+ return;
}
Log.e(TAG, "Destroying all old data.");
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index c0faeee..e09fa72 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -17,6 +17,7 @@
package com.android.providers.telephony;
+import static android.provider.Telephony.Carriers.ALWAYS_ON;
import static android.provider.Telephony.Carriers.APN;
import static android.provider.Telephony.Carriers.APN_SET_ID;
import static android.provider.Telephony.Carriers.AUTH_TYPE;
@@ -31,8 +32,8 @@
import static android.provider.Telephony.Carriers.CURRENT;
import static android.provider.Telephony.Carriers.DEFAULT_SORT_ORDER;
import static android.provider.Telephony.Carriers.EDITED_STATUS;
+import static android.provider.Telephony.Carriers.LINGERING_NETWORK_TYPE_BITMASK;
import static android.provider.Telephony.Carriers.MAX_CONNECTIONS;
-import static android.provider.Telephony.Carriers.TIME_LIMIT_FOR_MAX_CONNECTIONS;
import static android.provider.Telephony.Carriers.MCC;
import static android.provider.Telephony.Carriers.MMSC;
import static android.provider.Telephony.Carriers.MMSPORT;
@@ -40,6 +41,8 @@
import static android.provider.Telephony.Carriers.MNC;
import static android.provider.Telephony.Carriers.MODEM_PERSIST;
import static android.provider.Telephony.Carriers.MTU;
+import static android.provider.Telephony.Carriers.MTU_V4;
+import static android.provider.Telephony.Carriers.MTU_V6;
import static android.provider.Telephony.Carriers.MVNO_MATCH_DATA;
import static android.provider.Telephony.Carriers.MVNO_TYPE;
import static android.provider.Telephony.Carriers.NAME;
@@ -59,6 +62,7 @@
import static android.provider.Telephony.Carriers.SKIP_464XLAT;
import static android.provider.Telephony.Carriers.SKIP_464XLAT_DEFAULT;
import static android.provider.Telephony.Carriers.SUBSCRIPTION_ID;
+import static android.provider.Telephony.Carriers.TIME_LIMIT_FOR_MAX_CONNECTIONS;
import static android.provider.Telephony.Carriers.TYPE;
import static android.provider.Telephony.Carriers.UNEDITED;
import static android.provider.Telephony.Carriers.USER;
@@ -155,7 +159,7 @@
private static final boolean DBG = true;
private static final boolean VDBG = false; // STOPSHIP if true
- private static final int DATABASE_VERSION = 52 << 16;
+ private static final int DATABASE_VERSION = 57 << 16;
private static final int URL_UNKNOWN = 0;
private static final int URL_TELEPHONY = 1;
private static final int URL_CURRENT = 2;
@@ -190,11 +194,6 @@
private static final int URL_SIMINFO_SUW_RESTORE = 28;
private static final int URL_SIMINFO_SIM_INSERTED_RESTORE = 29;
- /**
- * Default value for mtu if it's not set. Moved from PhoneConstants.
- */
- private static final int UNSPECIFIED_INT = -1;
-
private static final String TAG = "TelephonyProvider";
private static final String CARRIERS_TABLE = "carriers";
private static final String CARRIERS_TABLE_TMP = "carriers_tmp";
@@ -370,8 +369,8 @@
static {
// Columns not included in UNIQUE constraint: name, current, edited, user, server, password,
// authtype, type, protocol, roaming_protocol, sub_id, modem_cognitive, max_conns,
- // wait_time, max_conns_time, mtu, bearer_bitmask, user_visible, network_type_bitmask,
- // skip_464xlat
+ // wait_time, max_conns_time, mtu, mtu_v4, mtu_v6, bearer_bitmask, user_visible,
+ // network_type_bitmask, skip_464xlat, lingering_network_type_bitmask, always_on
CARRIERS_UNIQUE_FIELDS_DEFAULTS.put(NUMERIC, "");
CARRIERS_UNIQUE_FIELDS_DEFAULTS.put(MCC, "");
CARRIERS_UNIQUE_FIELDS_DEFAULTS.put(MNC, "");
@@ -431,16 +430,19 @@
SIM_INFO_COLUMNS_TO_BACKUP.put(
Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING, Cursor.FIELD_TYPE_INTEGER);
SIM_INFO_COLUMNS_TO_BACKUP.put(
+ Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS,
+ Cursor.FIELD_TYPE_STRING);
+ SIM_INFO_COLUMNS_TO_BACKUP.put(
Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED, Cursor.FIELD_TYPE_INTEGER);
SIM_INFO_COLUMNS_TO_BACKUP.put(
Telephony.SimInfo.COLUMN_WFC_IMS_MODE, Cursor.FIELD_TYPE_INTEGER);
SIM_INFO_COLUMNS_TO_BACKUP.put(
Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE, Cursor.FIELD_TYPE_INTEGER);
SIM_INFO_COLUMNS_TO_BACKUP.put(
- Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS,
- Cursor.FIELD_TYPE_STRING);
- SIM_INFO_COLUMNS_TO_BACKUP.put(
Telephony.SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED, Cursor.FIELD_TYPE_INTEGER);
+ SIM_INFO_COLUMNS_TO_BACKUP.put(
+ Telephony.SimInfo.COLUMN_USAGE_SETTING,
+ Cursor.FIELD_TYPE_INTEGER);
}
@VisibleForTesting
@@ -470,6 +472,7 @@
BEARER + " INTEGER DEFAULT 0," +
BEARER_BITMASK + " INTEGER DEFAULT 0," +
NETWORK_TYPE_BITMASK + " INTEGER DEFAULT 0," +
+ LINGERING_NETWORK_TYPE_BITMASK + " INTEGER DEFAULT 0," +
MVNO_TYPE + " TEXT DEFAULT ''," +
MVNO_MATCH_DATA + " TEXT DEFAULT ''," +
SUBSCRIPTION_ID + " INTEGER DEFAULT " +
@@ -480,18 +483,21 @@
WAIT_TIME_RETRY + " INTEGER DEFAULT 0," +
TIME_LIMIT_FOR_MAX_CONNECTIONS + " INTEGER DEFAULT 0," +
MTU + " INTEGER DEFAULT 0," +
+ MTU_V4 + " INTEGER DEFAULT 0," +
+ MTU_V6 + " INTEGER DEFAULT 0," +
EDITED_STATUS + " INTEGER DEFAULT " + UNEDITED + "," +
USER_VISIBLE + " BOOLEAN DEFAULT 1," +
USER_EDITABLE + " BOOLEAN DEFAULT 1," +
OWNED_BY + " INTEGER DEFAULT " + OWNED_BY_OTHERS + "," +
APN_SET_ID + " INTEGER DEFAULT " + NO_APN_SET_ID + "," +
SKIP_464XLAT + " INTEGER DEFAULT " + SKIP_464XLAT_DEFAULT + "," +
+ ALWAYS_ON + " INTEGER DEFAULT 0," +
// Uniqueness collisions are used to trigger merge code so if a field is listed
// here it means we will accept both (user edited + new apn_conf definition)
// Columns not included in UNIQUE constraint: name, current, edited,
// user, server, password, authtype, type, sub_id, modem_cognitive, max_conns,
- // wait_time, max_conns_time, mtu, bearer_bitmask, user_visible,
- // network_type_bitmask, skip_464xlat.
+ // wait_time, max_conns_time, mtu, mtu_v4, mtu_v6, bearer_bitmask, user_visible,
+ // network_type_bitmask, skip_464xlat, lingering_network_type_bitmask, always_on.
"UNIQUE (" + TextUtils.join(", ", CARRIERS_UNIQUE_FIELDS) + "));";
}
@@ -563,10 +569,15 @@
+ Telephony.SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED + " INTEGER DEFAULT 0,"
+ Telephony.SimInfo.COLUMN_RCS_CONFIG + " BLOB,"
+ Telephony.SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS + " TEXT,"
- + Telephony.SimInfo.COLUMN_VOIMS_OPT_IN_STATUS + " INTEGER DEFAULT 0,"
+ Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING + " INTEGER DEFAULT 0,"
+ + Telephony.SimInfo.COLUMN_VOIMS_OPT_IN_STATUS + " INTEGER DEFAULT 0,"
+ Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS + " TEXT,"
- + Telephony.SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED + " INTEGER DEFAULT -1"
+ + Telephony.SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED + " INTEGER DEFAULT -1,"
+ + Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_CARRIER + " TEXT,"
+ + Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS + " TEXT,"
+ + Telephony.SimInfo.COLUMN_PORT_INDEX + " INTEGER DEFAULT -1,"
+ + Telephony.SimInfo.COLUMN_USAGE_SETTING + " INTEGER DEFAULT "
+ + SubscriptionManager.USAGE_SETTING_UNKNOWN
+ ");";
}
@@ -1650,21 +1661,6 @@
try {
// Try to update the siminfo table. It might not be there.
db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
- + Telephony.SimInfo.COLUMN_VOIMS_OPT_IN_STATUS
- + " INTEGER DEFAULT 0;");
- } catch (SQLiteException e) {
- if (DBG) {
- log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. "
- + "The table will get created in onOpen.");
- }
- }
- oldVersion = 49 << 16 | 6;
- }
-
- if (oldVersion < (50 << 16 | 6)) {
- try {
- // Try to update the siminfo table. It might not be there.
- db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING
+ " INTEGER DEFAULT 0;");
} catch (SQLiteException e) {
@@ -1673,6 +1669,20 @@
+ " to add d2d status sharing column. ");
}
}
+ }
+
+ if (oldVersion < (50 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + Telephony.SimInfo.COLUMN_VOIMS_OPT_IN_STATUS
+ + " INTEGER DEFAULT 0;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+ "The table will get created in onOpen.");
+ }
+ }
oldVersion = 50 << 16 | 6;
}
@@ -1705,6 +1715,96 @@
}
oldVersion = 52 << 16 | 6;
}
+
+ if (oldVersion < (53 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. Fix typo error in version 51.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS
+ + " TEXT;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade failed to updated " + SIMINFO_TABLE
+ + " to add d2d status sharing contacts. ");
+ }
+ }
+ oldVersion = 53 << 16 | 6;
+ }
+
+ if (oldVersion < (54 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table with new columns.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_CARRIER
+ + " TEXT;");
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS
+ + " TEXT;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade failed to update " + SIMINFO_TABLE
+ + " to add phone numbers. ");
+ }
+ }
+ oldVersion = 54 << 16 | 6;
+ }
+
+ if (oldVersion < (55 << 16 | 6)) {
+ try {
+ // Try to add new fields LINGERING_NETWORK_TYPE_BITMASK, ALWAYS_ON,
+ // MTU_V4, and MTU_V6
+ db.execSQL("ALTER TABLE " + CARRIERS_TABLE + " ADD COLUMN "
+ + LINGERING_NETWORK_TYPE_BITMASK + " INTEGER DEFAULT 0;");
+ db.execSQL("ALTER TABLE " + CARRIERS_TABLE + " ADD COLUMN "
+ + ALWAYS_ON + " INTEGER DEFAULT 0;");
+ db.execSQL("ALTER TABLE " + CARRIERS_TABLE + " ADD COLUMN "
+ + MTU_V4 + " INTEGER DEFAULT 0;");
+ db.execSQL("ALTER TABLE " + CARRIERS_TABLE + " ADD COLUMN "
+ + MTU_V6 + " INTEGER DEFAULT 0;");
+ // Populate MTU_V4 with MTU values
+ db.execSQL("UPDATE " + CARRIERS_TABLE + " SET " + MTU_V4 + " = "
+ + MTU + " WHERE " + MTU + " != 0;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade failed to update " + CARRIERS_TABLE
+ + " to add lingering network type bitmask, always on flag,"
+ + " and MTU v4 and v6 values.");
+ }
+ }
+ oldVersion = 55 << 16 | 6;
+ }
+
+ if (oldVersion < (56 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + Telephony.SimInfo.COLUMN_PORT_INDEX
+ + " INTEGER DEFAULT -1;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+ "The table will get created in onOpen.");
+ }
+ }
+ oldVersion = 56 << 16 | 6;
+ }
+
+ if (oldVersion < (57 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + Telephony.SimInfo.COLUMN_USAGE_SETTING
+ + " INTEGER DEFAULT " + SubscriptionManager.USAGE_SETTING_UNKNOWN
+ + ";");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade failed to updated " + SIMINFO_TABLE
+ + " to add preferred usage setting");
+ }
+ }
+ oldVersion = 57 << 16 | 6;
+ }
+
if (DBG) {
log("dbh.onUpgrade:- db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
}
@@ -1950,8 +2050,10 @@
queryValOrNull(MAX_CONNECTIONS) +
queryValOrNull(WAIT_TIME_RETRY) +
queryValOrNull(TIME_LIMIT_FOR_MAX_CONNECTIONS) +
- queryValOrNull(MTU);
- String[] whereArgs = new String[29];
+ queryValOrNull(MTU) +
+ queryValOrNull(MTU_V4) +
+ queryValOrNull(MTU_V6);
+ String[] whereArgs = new String[31];
int i = 0;
whereArgs[i++] = values.getAsString(NUMERIC);
whereArgs[i++] = values.getAsString(MCC);
@@ -2021,6 +2123,10 @@
values.getAsString(TIME_LIMIT_FOR_MAX_CONNECTIONS) : "0";
whereArgs[i++] = values.containsKey(MTU) ?
values.getAsString(MTU) : "0";
+ whereArgs[i++] = values.containsKey(MTU_V4) ?
+ values.getAsString(MTU_V4) : "0";
+ whereArgs[i++] = values.containsKey(MTU_V6) ?
+ values.getAsString(MTU_V6) : "0";
if (VDBG) {
log("deleteRow: where: " + where);
@@ -2135,7 +2241,10 @@
getIntValueFromCursor(cv, c, WAIT_TIME_RETRY);
getIntValueFromCursor(cv, c, TIME_LIMIT_FOR_MAX_CONNECTIONS);
getIntValueFromCursor(cv, c, MTU);
+ getIntValueFromCursor(cv, c, MTU_V4);
+ getIntValueFromCursor(cv, c, MTU_V6);
getIntValueFromCursor(cv, c, NETWORK_TYPE_BITMASK);
+ getIntValueFromCursor(cv, c, LINGERING_NETWORK_TYPE_BITMASK);
getIntValueFromCursor(cv, c, BEARER_BITMASK);
getIntValueFromCursor(cv, c, EDITED_STATUS);
getIntValueFromCursor(cv, c, USER_VISIBLE);
@@ -2143,6 +2252,7 @@
getIntValueFromCursor(cv, c, OWNED_BY);
getIntValueFromCursor(cv, c, APN_SET_ID);
getIntValueFromCursor(cv, c, SKIP_464XLAT);
+ getIntValueFromCursor(cv, c, ALWAYS_ON);
}
private void copyPreservedApnsToNewTable(SQLiteDatabase db, Cursor c) {
@@ -2154,9 +2264,9 @@
while (c.moveToNext()) {
ContentValues cv = new ContentValues();
String val;
- // Using V17 copy function for V15 upgrade. This should be fine since it handles
- // columns that may not exist properly (getStringValueFromCursor() and
- // getIntValueFromCursor() handle column index -1)
+ // Using V17 copy function for V15 upgrade. This should be fine since it
+ // handles columns that may not exist properly (getStringValueFromCursor()
+ // and getIntValueFromCursor() handle column index -1)
copyApnValuesV17(cv, c);
// Change bearer to a bitmask
String bearerStr = c.getString(c.getColumnIndex(BEARER));
@@ -2313,17 +2423,19 @@
String mncString = mnc;
// Since an mnc can have both two and three digits and it is hard to verify
// all OEM's Global APN lists we only do this for overlays.
- if (isOverlay) {
+ if (isOverlay && mcc !=null && mnc != null) {
mccString = String.format("%03d", Integer.parseInt(mcc));
// Looks up a two digit mnc in the carrier id DB
// if not found a three digit mnc value is chosen
mncString = getBestStringMnc(mContext, mccString, Integer.parseInt(mnc));
}
-
- String numeric = mccString + mncString;
+ // Make sure to set default values for numeric, mcc and mnc. This is the empty string.
+ // If default is not set here, a duplicate of each carrier id APN will be created next
+ // time the apn list is read. This happens at OTA or at restore.
+ String numeric = (mccString == null | mncString == null) ? "" : mccString + mncString;
map.put(NUMERIC, numeric);
- map.put(MCC, mccString);
- map.put(MNC, mncString);
+ map.put(MCC, mccString != null ? mccString : "");
+ map.put(MNC, mncString != null ? mncString : "");
map.put(NAME, parser.getAttributeValue(null, "carrier"));
// do not add NULL to the map so that default values can be inserted in db
@@ -2354,6 +2466,8 @@
addIntAttribute(parser, "wait_time", map, WAIT_TIME_RETRY);
addIntAttribute(parser, "max_conns_time", map, TIME_LIMIT_FOR_MAX_CONNECTIONS);
addIntAttribute(parser, "mtu", map, MTU);
+ addIntAttribute(parser, "mtu_v4", map, MTU_V4);
+ addIntAttribute(parser, "mtu_v6", map, MTU_V6);
addIntAttribute(parser, "apn_set_id", map, APN_SET_ID);
addIntAttribute(parser, "carrier_id", map, CARRIER_ID);
addIntAttribute(parser, "skip_464xlat", map, SKIP_464XLAT);
@@ -2362,6 +2476,7 @@
addBoolAttribute(parser, "modem_cognitive", map, MODEM_PERSIST);
addBoolAttribute(parser, "user_visible", map, USER_VISIBLE);
addBoolAttribute(parser, "user_editable", map, USER_EDITABLE);
+ addBoolAttribute(parser, "always_on", map, ALWAYS_ON);
int networkTypeBitmask = 0;
String networkTypeList = parser.getAttributeValue(null, "network_type_bitmask");
@@ -2370,6 +2485,14 @@
}
map.put(NETWORK_TYPE_BITMASK, networkTypeBitmask);
+ int lingeringNetworkTypeBitmask = 0;
+ String lingeringNetworkTypeList =
+ parser.getAttributeValue(null, "lingering_network_type_bitmask");
+ if (lingeringNetworkTypeList != null) {
+ lingeringNetworkTypeBitmask = getBitmaskFromString(lingeringNetworkTypeList);
+ }
+ map.put(LINGERING_NETWORK_TYPE_BITMASK, lingeringNetworkTypeBitmask);
+
int bearerBitmask = 0;
if (networkTypeList != null) {
bearerBitmask = convertNetworkTypeBitmaskToBearerBitmask(networkTypeBitmask);
@@ -2904,7 +3027,7 @@
mOpenHelper = new DatabaseHelper(getContext());
try {
- PhoneFactory.addLocalLog(TAG, 100);
+ PhoneFactory.addLocalLog(TAG, 64);
} catch (IllegalArgumentException e) {
// ignore
}
@@ -3141,8 +3264,10 @@
}
boolean isCallingFromSystemOrPhoneUid() {
- return mInjector.binderGetCallingUid() == Process.SYSTEM_UID ||
- mInjector.binderGetCallingUid() == Process.PHONE_UID;
+ int callingUid = mInjector.binderGetCallingUid();
+ return callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
+ // Allow ROOT for testing. ROOT can access underlying DB files anyways.
+ || callingUid == Process.ROOT_UID;
}
void ensureCallingFromSystemOrPhoneUid(String message) {
@@ -3513,7 +3638,7 @@
PersistableBundle backedUpSimInfoEntry, int backupDataFormatVersion,
String isoCountryCodeFromDb,
List<String> wfcRestoreBlockedCountries) {
- if (DATABASE_VERSION != 52 << 16) {
+ if (DATABASE_VERSION != 57 << 16) {
throw new AssertionError("The database schema has been updated which might make "
+ "the format of #BACKED_UP_SIM_SPECIFIC_SETTINGS_FILE outdated. Make sure to "
+ "1) review whether any of the columns in #SIM_INFO_COLUMNS_TO_BACKUP have "
@@ -3555,6 +3680,12 @@
* Also make sure to add necessary removal of sensitive settings in
* polishContentValues(ContentValues contentValues).
*/
+ if (backupDataFormatVersion >= 57 << 16) {
+ contentValues.put(Telephony.SimInfo.COLUMN_USAGE_SETTING,
+ backedUpSimInfoEntry.getInt(
+ Telephony.SimInfo.COLUMN_USAGE_SETTING,
+ SubscriptionManager.USAGE_SETTING_UNKNOWN));
+ }
if (backupDataFormatVersion >= 52 << 16) {
contentValues.put(Telephony.SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED,
backedUpSimInfoEntry.getInt(
@@ -3804,6 +3935,14 @@
break;
}
+ case URL_DPC_ID: {
+ constraints.add("_id = " + url.getLastPathSegment());
+ ensureCallingFromSystemOrPhoneUid("URL_DPC called from non SYSTEM_UID.");
+ // DPC query only returns DPC records.
+ constraints.add(IS_OWNED_BY_DPC);
+ break;
+ }
+
case URL_FILTERED_ID:
case URL_FILTERED_USING_SUBID: {
String idString = url.getLastPathSegment();
@@ -3966,7 +4105,7 @@
.createForSubscriptionId(subId);
SQLiteDatabase db = getReadableDatabase();
String mccmnc = tm.getSimOperator();
- int carrierId = tm.getSimCarrierId();
+ int carrierId = tm.getSimSpecificCarrierId();
qb.appendWhereStandalone(IS_NOT_USER_DELETED + " and " +
IS_NOT_USER_DELETED_BUT_PRESENT_IN_XML + " and " +
@@ -3991,6 +4130,7 @@
MatrixCursor currentCursor = new MatrixCursor(columnNames);
MatrixCursor parentCursor = new MatrixCursor(columnNames);
MatrixCursor carrierIdCursor = new MatrixCursor(columnNames);
+ MatrixCursor carrierIdNonMatchingMNOCursor = new MatrixCursor(columnNames);
int numericIndex = ret.getColumnIndex(NUMERIC);
int mvnoIndex = ret.getColumnIndex(MVNO_TYPE);
@@ -4004,15 +4144,17 @@
data.add(ret.getString(ret.getColumnIndex(column)));
}
- boolean isCurrentSimOperator;
- final long identity = Binder.clearCallingIdentity();
- try {
- isCurrentSimOperator = tm.matchesCurrentSimOperator(
- ret.getString(numericIndex),
- getMvnoTypeIntFromString(ret.getString(mvnoIndex)),
- ret.getString(mvnoDataIndex));
- } finally {
- Binder.restoreCallingIdentity(identity);
+ boolean isCurrentSimOperator = false;
+ if (!TextUtils.isEmpty(ret.getString(numericIndex))) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ isCurrentSimOperator = tm.matchesCurrentSimOperator(
+ ret.getString(numericIndex),
+ getMvnoTypeIntFromString(ret.getString(mvnoIndex)),
+ ret.getString(mvnoDataIndex));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
boolean isMVNOAPN = !TextUtils.isEmpty(ret.getString(numericIndex))
@@ -4032,7 +4174,11 @@
parentCursor.addRow(data);
} else if (isCarrierIdAPN) {
// The APN that query based on carrier Id (not include the MVNO or MNO APN)
- carrierIdCursor.addRow(data);
+ if (TextUtils.isEmpty(ret.getString(numericIndex))) {
+ carrierIdCursor.addRow(data);
+ } else {
+ carrierIdNonMatchingMNOCursor.addRow(data);
+ }
}
}
ret.close();
@@ -4045,8 +4191,11 @@
if (DBG) log("match MNO APN: " + parentCursor.getCount());
result = parentCursor;
} else {
- if (DBG) log("can't find the MVNO and MNO APN");
- result = new MatrixCursor(columnNames);
+ if (DBG) {
+ log("No MVNO, MNO and no MCC/MNC match, but we have match/matches with the " +
+ "same carrier id, count: " + carrierIdNonMatchingMNOCursor.getCount());
+ }
+ result = carrierIdNonMatchingMNOCursor;
}
if (DBG) log("match carrier id APN: " + carrierIdCursor.getCount());
@@ -4187,12 +4336,12 @@
Uri result = null;
int subId = SubscriptionManager.getDefaultSubscriptionId();
- checkPermission();
+ int match = s_urlMatcher.match(url);
+ checkPermission(match);
syncBearerBitmaskAndNetworkTypeBitmask(initialValues);
boolean notify = false;
SQLiteDatabase db = getWritableDatabase();
- int match = s_urlMatcher.match(url);
switch (match)
{
case URL_TELEPHONY_USING_SUBID:
@@ -4340,10 +4489,10 @@
ContentValues cv = new ContentValues();
cv.put(EDITED_STATUS, USER_DELETED);
- checkPermission();
+ int match = s_urlMatcher.match(url);
+ checkPermission(match);
SQLiteDatabase db = getWritableDatabase();
- int match = s_urlMatcher.match(url);
switch (match)
{
case URL_DELETE:
@@ -4502,11 +4651,11 @@
int uriType = URL_UNKNOWN;
int subId = SubscriptionManager.getDefaultSubscriptionId();
- checkPermission();
+ int match = s_urlMatcher.match(url);
+ checkPermission(match);
syncBearerBitmaskAndNetworkTypeBitmask(values);
SQLiteDatabase db = getWritableDatabase();
- int match = s_urlMatcher.match(url);
switch (match)
{
case URL_TELEPHONY_USING_SUBID:
@@ -4780,6 +4929,12 @@
Telephony.SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED),
usingSubId, subId), null, true, UserHandle.USER_ALL);
}
+ if (values.containsKey(Telephony.SimInfo.COLUMN_USAGE_SETTING)) {
+ getContext().getContentResolver().notifyChange(getNotifyContentUri(
+ Uri.withAppendedPath(Telephony.SimInfo.CONTENT_URI,
+ Telephony.SimInfo.COLUMN_USAGE_SETTING),
+ usingSubId, subId), null, true, UserHandle.USER_ALL);
+ }
break;
default:
getContext().getContentResolver().notifyChange(
@@ -4794,7 +4949,28 @@
return (usingSubId) ? Uri.withAppendedPath(uri, "" + subId) : uri;
}
- private void checkPermission() {
+ /**
+ * Checks permission to query or insert/update/delete the database. The permissions required
+ * for APN DB and SIMINFO DB are different:
+ * <ul>
+ * <li>APN DB requires WRITE_APN_SETTINGS or carrier privileges
+ * <li>SIMINFO DB requires phone UID; it's for phone internal usage only
+ * </ul>
+ */
+ private void checkPermission(int match) {
+ switch (match) {
+ case URL_SIMINFO:
+ case URL_SIMINFO_USING_SUBID:
+ case URL_SIMINFO_SUW_RESTORE:
+ case URL_SIMINFO_SIM_INSERTED_RESTORE:
+ checkPermissionForSimInfoTable();
+ break;
+ default:
+ checkPermissionForApnTable();
+ }
+ }
+
+ private void checkPermissionForApnTable() {
int status = getContext().checkCallingOrSelfPermission(
"android.permission.WRITE_APN_SETTINGS");
if (status == PackageManager.PERMISSION_GRANTED) {
@@ -4835,12 +5011,14 @@
log("Using old permission behavior for telephony provider compat");
checkQueryPermission(match, projectionIn);
} else {
- checkPermission();
+ checkPermission(match);
}
}
private void checkQueryPermission(int match, String[] projectionIn) {
- if (match != URL_SIMINFO) {
+ if (match == URL_SIMINFO) {
+ checkPermissionForSimInfoTable();
+ } else {
if (projectionIn != null) {
for (String column : projectionIn) {
if (TYPE.equals(column) ||
@@ -4852,17 +5030,27 @@
APN.equals(column)) {
// noop
} else {
- checkPermission();
+ checkPermissionForApnTable();
break;
}
}
} else {
// null returns all columns, so need permission check
- checkPermission();
+ checkPermissionForApnTable();
}
}
}
+ private void checkPermissionForSimInfoTable() {
+ ensureCallingFromSystemOrPhoneUid("Access SIMINFO table from not phone/system UID");
+ if (getContext().checkCallingOrSelfPermission(
+ "android.permission.ACCESS_TELEPHONY_SIMINFO_DB")
+ == PackageManager.PERMISSION_GRANTED) {
+ return;
+ }
+ throw new SecurityException("No permission to access SIMINFO table");
+ }
+
private DatabaseHelper mOpenHelper;
private void restoreDefaultAPN(int subId) {
@@ -4909,6 +5097,7 @@
TelephonyManager telephonyManager =
getContext().getSystemService(TelephonyManager.class).createForSubscriptionId(subId);
String simOperator = telephonyManager.getSimOperator();
+ int simCarrierId = telephonyManager.getSimSpecificCarrierId();
Cursor cursor = db.query(CARRIERS_TABLE, new String[] {MVNO_TYPE, MVNO_MATCH_DATA},
NUMERIC + "='" + simOperator + "'", null, null, null, DEFAULT_SORT_ORDER);
String where = null;
@@ -4936,6 +5125,12 @@
+ " AND (" + MVNO_TYPE + "='' OR " + MVNO_MATCH_DATA + "='')"
+ " AND " + IS_NOT_OWNED_BY_DPC;
}
+ // Add carrier id APNs
+ if (TelephonyManager.UNKNOWN_CARRIER_ID < simCarrierId) {
+ where = where.concat(" OR " + CARRIER_ID + " = '" + simCarrierId + "'" + " AND "
+ + IS_NOT_OWNED_BY_DPC);
+ }
+
}
return where;
}
@@ -5075,7 +5270,7 @@
private static int getMvnoTypeIntFromString(String mvnoType) {
String mvnoTypeString = TextUtils.isEmpty(mvnoType) ? mvnoType : mvnoType.toLowerCase();
Integer mvnoTypeInt = MVNO_TYPE_STRING_MAP.get(mvnoTypeString);
- return mvnoTypeInt == null ? UNSPECIFIED_INT : mvnoTypeInt;
+ return mvnoTypeInt == null ? 0 : mvnoTypeInt;
}
private static int getBitmaskFromString(String bearerList) {
diff --git a/tests/Android.bp b/tests/Android.bp
index 8ecc370..7695c03 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -1,12 +1,6 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "packages_providers_TelephonyProvider_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: [
- "packages_providers_TelephonyProvider_license",
- ],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
android_test {
diff --git a/tests/src/com/android/providers/telephony/CarrierProviderTest.java b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
index eb95fb6..d329002 100644
--- a/tests/src/com/android/providers/telephony/CarrierProviderTest.java
+++ b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
@@ -22,14 +22,13 @@
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
+import android.telephony.TelephonyManager;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.TextUtils;
import android.util.Log;
-import com.android.providers.telephony.CarrierProvider;
-
import junit.framework.TestCase;
import org.junit.Test;
@@ -60,11 +59,10 @@
public static final String test_mcc = "MCC005";
public static final String test_key1 = "PUBKEY1";
public static final String test_key2 = "PUBKEY2";
- public static final String test_mvno_type = "100";
- public static final String test_mvno_match_data = "101";
public static final String test_key_identifier_data = "key_identifier1";
public static final long test_key_expiration = 1496795015L;
-
+ public static final int TEST_CARRIER_ID_1 = 1;
+ public static final int TEST_CARRIER_ID_2 = 2;
/**
* This is used to give the CarrierProviderTest a mocked context which takes a
@@ -147,8 +145,7 @@
contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
- contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
- contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+ contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration);
@@ -183,8 +180,7 @@
contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
- contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
- contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+ contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration);
@@ -199,8 +195,9 @@
ContentValues updatedValues = new ContentValues();
updatedValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key2);
mContentResolver.update(CarrierProvider.CONTENT_URI, updatedValues,
- "mcc=? and mnc=? and key_type=?", new String[] { test_mcc, test_mnc,
- String.valueOf(test_type) });
+ "mcc=? and mnc=? and carrier_id=? and key_type=?",
+ new String[]{test_mcc, test_mnc, Integer.toString(TEST_CARRIER_ID_1),
+ String.valueOf(test_type)});
} catch (Exception e) {
Log.d(TAG, "Error updating values:" + e);
}
@@ -208,8 +205,9 @@
try {
String[] columns ={CarrierDatabaseHelper.PUBLIC_KEY};
Cursor findEntry = mContentResolver.query(CarrierProvider.CONTENT_URI, columns,
- "mcc=? and mnc=? and key_type=?",
- new String[] { test_mcc, test_mnc, String.valueOf(test_type) }, null);
+ "mcc=? and mnc=? and carrier_id=? and key_type=?",
+ new String[]{test_mcc, test_mnc, Integer.toString(TEST_CARRIER_ID_1),
+ String.valueOf(test_type)}, null);
findEntry.moveToFirst();
key = findEntry.getString(0);
} catch (Exception e) {
@@ -229,8 +227,7 @@
contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
- contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
- contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+ contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
@@ -238,8 +235,7 @@
contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc);
contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc2);
- contentValuesNew.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
- contentValuesNew.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+ contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key2.getBytes());
@@ -265,6 +261,97 @@
}
/**
+ * Test inserting cert with same MCC and MNC but with diff carrier ID
+ */
+ @Test
+ @SmallTest
+ public void testMnoandMvnoCertificates() {
+ int count = -1;
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+ contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
+ contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
+ contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
+ contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
+ contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
+
+ ContentValues contentValuesNew = new ContentValues();
+ contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+ contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc);
+ contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc);
+ contentValuesNew.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_2);
+ contentValuesNew.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
+ contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
+
+ try {
+ mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
+ mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValuesNew);
+ } catch (Exception e) {
+ System.out.println("Error inserting certificates:: " + e);
+ }
+
+ try {
+ Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI,
+ new String[]{"count(*) AS count"},
+ null,
+ null,
+ null);
+ countCursor.moveToFirst();
+ count = countCursor.getInt(0);
+ } catch (Exception e) {
+ Log.d(TAG, "Exception in getting count:" + e);
+ }
+ assertEquals(2, count);
+ }
+
+ /**
+ * once upgrade to version 3, carrierId = -1
+ * After upgrade, it triggers for new download with correct carrierId
+ * This test case will test writing the new entry, even old entry for same
+ * operator is already existed
+ */
+ @Test
+ @SmallTest
+ public void testOldAndNewDBEntries() {
+ int count = -1;
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+ contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
+ contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
+ contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+ contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
+ contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
+
+ ContentValues contentValuesNew = new ContentValues();
+ contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+ contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc);
+ contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc);
+ contentValuesNew.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_2);
+ contentValuesNew.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
+ contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
+
+ try {
+ mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
+ mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValuesNew);
+ } catch (Exception e) {
+ System.out.println("Error inserting certificates:: " + e);
+ }
+
+ try {
+ Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI,
+ new String[]{"count(*) AS count"},
+ null,
+ null,
+ null);
+ countCursor.moveToFirst();
+ count = countCursor.getInt(0);
+ } catch (Exception e) {
+ Log.d(TAG, "Exception in getting count:" + e);
+ }
+ assertEquals(2, count);
+ }
+
+ /**
* Test inserting duplicate values in carrier key table. Ensure that a SQLException is thrown.
*/
@Test(expected = SQLException.class)
@@ -273,8 +360,7 @@
contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
- contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
- contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+ contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
try {
@@ -300,8 +386,7 @@
contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
- contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
- contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+ contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration);
@@ -313,9 +398,11 @@
}
try {
- String whereClause = "mcc=? and mnc=?";
- String[] whereArgs = new String[] { test_mcc, test_mnc };
- numRowsDeleted = mContentResolver.delete(CarrierProvider.CONTENT_URI, whereClause, whereArgs);
+ String whereClause = "mcc=? and mnc=? and carrier_id=?";
+ String[] whereArgs = new String[]{test_mcc, test_mnc, Integer.toString(
+ TEST_CARRIER_ID_1)};
+ numRowsDeleted = mContentResolver.delete(CarrierProvider.CONTENT_URI, whereClause,
+ whereArgs);
} catch (Exception e) {
Log.d(TAG, "Error updating values:" + e);
}
diff --git a/tests/src/com/android/providers/telephony/SmsProviderTest.java b/tests/src/com/android/providers/telephony/SmsProviderTest.java
index 2bc5f0f..6a225af 100644
--- a/tests/src/com/android/providers/telephony/SmsProviderTest.java
+++ b/tests/src/com/android/providers/telephony/SmsProviderTest.java
@@ -16,6 +16,11 @@
package com.android.providers.telephony;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.app.AppOpsManager;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -26,6 +31,8 @@
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Build;
+import android.os.Process;
import android.provider.Telephony;
import android.telephony.TelephonyManager;
import android.test.mock.MockContentResolver;
@@ -33,11 +40,14 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+
import junit.framework.TestCase;
import org.junit.Test;
+import org.mockito.Mock;
import org.mockito.Mockito;
-
+import org.mockito.MockitoAnnotations;
/**
* Tests for testing CRUD operations of SmsProvider.
@@ -54,9 +64,11 @@
public class SmsProviderTest extends TestCase {
private static final String TAG = "SmsProviderTest";
- private MockContextWithProvider mContext;
+ @Mock private Context mContext;
private MockContentResolver mContentResolver;
private SmsProviderTestable mSmsProviderTestable;
+ @Mock private PackageManager mPackageManager;
+ @Mock private Resources mMockResources;
private int notifyChangeCount;
@@ -75,79 +87,55 @@
private final Uri mRawUriPermanentDelete =
Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
- /**
- * This is used to give the SmsProviderTest a mocked context which takes a
- * SmsProvider and attaches it to the ContentResolver with telephony authority.
- * The mocked context also gives WRITE_APN_SETTINGS permissions
- */
- private class MockContextWithProvider extends MockContext {
- private final MockContentResolver mResolver;
-
- public MockContextWithProvider(SmsProvider smsProvider) {
- mResolver = new MockContentResolver() {
- @Override
- public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork,
- int userHandle) {
- notifyChangeCount++;
- }
- };
-
- // Add authority="sms" to given smsProvider
- ProviderInfo providerInfo = new ProviderInfo();
- providerInfo.authority = "sms";
-
- // Add context to given smsProvider
- smsProvider.attachInfoForTesting(this, providerInfo);
- Log.d(TAG, "MockContextWithProvider: smsProvider.getContext(): "
- + smsProvider.getContext());
-
- // Add given SmsProvider to mResolver with authority="sms" so that
- // mResolver can send queries to mSmsProvider
- mResolver.addProvider("sms", smsProvider);
- Log.d(TAG, "MockContextWithProvider: Add SmsProvider to mResolver");
- }
-
- @Override
- public Object getSystemService(String name) {
- Log.d(TAG, "getSystemService: returning null");
- switch (name) {
- case Context.APP_OPS_SERVICE:
- return Mockito.mock(AppOpsManager.class);
- case Context.TELEPHONY_SERVICE:
- return Mockito.mock(TelephonyManager.class);
- default:
- return null;
- }
- }
-
- @Override
- public Resources getResources() {
- Log.d(TAG, "getResources: returning null");
- return null;
- }
-
- @Override
- public int getUserId() {
- return 0;
- }
-
- @Override
- public MockContentResolver getContentResolver() {
- return mResolver;
- }
-
- @Override
- public int checkCallingOrSelfPermission(String permission) {
- return PackageManager.PERMISSION_GRANTED;
- }
- }
-
@Override
protected void setUp() throws Exception {
super.setUp();
+ MockitoAnnotations.initMocks(this);
mSmsProviderTestable = new SmsProviderTestable();
- mContext = new MockContextWithProvider(mSmsProviderTestable);
- mContentResolver = mContext.getContentResolver();
+
+ when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE)))
+ .thenReturn(mock(AppOpsManager.class));
+ when(mContext.getSystemService(eq(Context.TELEPHONY_SERVICE)))
+ .thenReturn(mock(TelephonyManager.class));
+
+ when(mContext.checkCallingOrSelfPermission(anyString()))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+
+ when(mMockResources
+ .getString(eq(com.android.internal.R.string.config_systemBluetoothStack)))
+ .thenReturn("com.android.bluetooth");
+ when(mContext.getResources()).thenReturn(mMockResources);
+ when(mContext.getUserId()).thenReturn(0);
+
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+
+ /**
+ * This is used to give the SmsProviderTest a mocked context which takes a
+ * SmsProvider and attaches it to the ContentResolver with telephony authority.
+ * The mocked context also gives WRITE_APN_SETTINGS permissions
+ */
+ mContentResolver = new MockContentResolver() {
+ @Override
+ public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork,
+ int userHandle) {
+ notifyChangeCount++;
+ }
+ };
+ when(mContext.getContentResolver()).thenReturn(mContentResolver);
+
+ // Add authority="sms" to given smsProvider
+ ProviderInfo providerInfo = new ProviderInfo();
+ providerInfo.authority = "sms";
+
+ // Add context to given smsProvider
+ mSmsProviderTestable.attachInfoForTesting(mContext, providerInfo);
+ Log.d(TAG, "MockContextWithProvider: smsProvider.getContext(): "
+ + mSmsProviderTestable.getContext());
+
+ // Add given SmsProvider to mResolver with authority="sms" so that
+ // mResolver can send queries to mSmsProvider
+ mContentResolver.addProvider("sms", mSmsProviderTestable);
+ Log.d(TAG, "MockContextWithProvider: Add SmsProvider to mResolver");
notifyChangeCount = 0;
}
diff --git a/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java b/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
index eb03443..9de138c 100644
--- a/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
@@ -121,6 +121,19 @@
}
@Test
+ public void databaseHelperOnUpgrade_hasPortIndexField() {
+ Log.d(TAG, "databaseHelperOnUpgrade_hasPortIndexField");
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
+
+ // the upgraded db must have the PORT_INDEX field
+ Cursor cursor = db.query("siminfo", null, null, null, null, null, null);
+ String[] upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "port index columns: " + Arrays.toString(upgradedColumns));
+ assertTrue(Arrays.asList(upgradedColumns).contains(SubscriptionManager.PORT_INDEX));
+ }
+
+ @Test
public void databaseHelperOnUpgrade_hasSkip464XlatField() {
Log.d(TAG, "databaseHelperOnUpgrade_hasSkip464XlatField");
// (5 << 16 | 6) is the first upgrade trigger in onUpgrade
@@ -218,22 +231,6 @@
}
@Test
- public void databaseHelperOnUpgrade_hasVoImsOptInStatusField() {
- Log.d(TAG, "databaseHelperOnUpgrade_hasImsRcsUceEnabledField");
- // (5 << 16) is the first upgrade trigger in onUpgrade
- SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
- mHelper.onUpgrade(db, 4 << 16, TelephonyProvider.getVersion(mContext));
-
- // the upgraded db must have the SubscriptionManager.VOIMS_OPT_IN_STATUS field
- Cursor cursor = db.query("siminfo", null, null, null, null, null, null);
- String[] upgradedColumns = cursor.getColumnNames();
- Log.d(TAG, "siminfo columns: " + Arrays.toString(upgradedColumns));
-
- assertTrue(Arrays.asList(upgradedColumns).contains(
- Telephony.SimInfo.COLUMN_VOIMS_OPT_IN_STATUS));
- }
-
- @Test
public void databaseHelperOnUpgrade_hasD2DStatusSharingField() {
Log.d(TAG, "databaseHelperOnUpgrade_hasD2DStatusSharingField");
// (5 << 16 | 6) is the first upgrade trigger in onUpgrade
@@ -250,6 +247,22 @@
}
@Test
+ public void databaseHelperOnUpgrade_hasVoImsOptInStatusField() {
+ Log.d(TAG, "databaseHelperOnUpgrade_hasImsRcsUceEnabledField");
+ // (5 << 16) is the first upgrade trigger in onUpgrade
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, 4 << 16, TelephonyProvider.getVersion(mContext));
+
+ // the upgraded db must have the SubscriptionManager.VOIMS_OPT_IN_STATUS field
+ Cursor cursor = db.query("siminfo", null, null, null, null, null, null);
+ String[] upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "siminfo columns: " + Arrays.toString(upgradedColumns));
+
+ assertTrue(Arrays.asList(upgradedColumns).contains(
+ Telephony.SimInfo.COLUMN_VOIMS_OPT_IN_STATUS));
+ }
+
+ @Test
public void databaseHelperOnUpgrade_hasD2DSharingContactsField() {
Log.d(TAG, "databaseHelperOnUpgrade_hasD2DSharingContactsField");
// (5 << 16 | 6) is the first upgrade trigger in onUpgrade
@@ -283,6 +296,61 @@
Telephony.SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED));
}
+ @Test
+ public void databaseHelperOnUpgrade_hasPhoneNumberSourceCarrierAndImsField() {
+ Log.d(TAG, "databaseHelperOnUpgrade_hasPhoneNumberSourceCarrierAndImsField");
+ // (5 << 16 | 6) is the first upgrade trigger in onUpgrade
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
+
+ // the upgraded db must have the
+ // Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_CARRIER field and
+ // Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS field
+ Cursor cursor = db.query("siminfo", null, null, null, null, null, null);
+ String[] upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "siminfo columns: " + Arrays.toString(upgradedColumns));
+
+ assertTrue(Arrays.asList(upgradedColumns).contains(
+ Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_CARRIER));
+ assertTrue(Arrays.asList(upgradedColumns).contains(
+ Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS));
+ }
+
+ @Test
+ public void databaseHelperOnUpgrade_hasLingeringNetworkTypeAlwaysOnMtuFields() {
+ Log.d(TAG, "databaseHelperOnUpgrade_hasLingeringNetworkTypeAlwaysOnMtuFields");
+ // (5 << 16 | 6) is the first upgrade trigger in onUpgrade
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
+
+ // The upgraded db must have the fields Telephony.Carrier.LINGERING_NETWORK_TYPE,
+ // Telephony.Carrier.ALWAYS_ON, Telephony.Carrier.MTU_V4, and Telephony.Carrier.MTU_V6
+ Cursor cursor = db.query("carriers", null, null, null, null, null, null);
+ String[] columns = cursor.getColumnNames();
+ Log.d(TAG, "carriers columns: " + Arrays.toString(columns));
+
+ assertTrue(Arrays.asList(columns).contains(Carriers.LINGERING_NETWORK_TYPE_BITMASK));
+ assertTrue(Arrays.asList(columns).contains(Carriers.ALWAYS_ON));
+ assertTrue(Arrays.asList(columns).contains(Carriers.MTU_V4));
+ assertTrue(Arrays.asList(columns).contains(Carriers.MTU_V6));
+ }
+
+ @Test
+ public void databaseHelperOnUpgrade_hasUsageSettingField() {
+ Log.d(TAG, "databaseHelperOnUpgrade_hasUsageSettingField");
+ // (5 << 16 | 6) is the first upgrade trigger in onUpgrade
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
+
+ // the upgraded db must have the Telephony.SimInfo.USAGE_SETTING field
+ Cursor cursor = db.query("siminfo", null, null, null, null, null, null);
+ String[] upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "siminfo columns: " + Arrays.toString(upgradedColumns));
+
+ assertTrue(Arrays.asList(upgradedColumns).contains(
+ Telephony.SimInfo.COLUMN_USAGE_SETTING));
+ }
+
/**
* Helper for an in memory DB used to test the TelephonyProvider#DatabaseHelper.
*
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
index b1cb97e..b3892be 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
@@ -96,6 +96,7 @@
private static final String TEST_SUBID = "1";
private static final String TEST_OPERATOR = "123456";
+ private static final String TEST_OPERATOR_SECOND_MCCMNC = "567890";
private static final String TEST_MCC = "123";
private static final String TEST_MNC = "456";
private static final String TEST_SPN = TelephonyProviderTestable.TEST_SPN;
@@ -214,6 +215,7 @@
contentValues.put(Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS,
arbitraryStringVal);
contentValues.put(Telephony.SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED, arbitraryIntVal);
+ contentValues.put(Telephony.SimInfo.COLUMN_USAGE_SETTING, arbitraryIntVal);
if (isoCountryCode != null) {
contentValues.put(Telephony.SimInfo.COLUMN_ISO_COUNTRY_CODE, isoCountryCode);
}
@@ -224,7 +226,7 @@
/**
* This is used to give the TelephonyProviderTest a mocked context which takes a
* TelephonyProvider and attaches it to the ContentResolver with telephony authority.
- * The mocked context also gives WRITE_APN_SETTINGS permissions
+ * The mocked context also gives permissions needed to access DB tables.
*/
private class MockContextWithProvider extends MockContext {
private final MockContentResolver mResolver;
@@ -233,7 +235,8 @@
private final List<String> GRANTED_PERMISSIONS = Arrays.asList(
Manifest.permission.MODIFY_PHONE_STATE, Manifest.permission.WRITE_APN_SETTINGS,
- Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+ Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+ "android.permission.ACCESS_TELEPHONY_SIMINFO_DB");
public MockContextWithProvider(TelephonyProvider telephonyProvider,
Boolean isActiveSubscription) {
@@ -258,7 +261,7 @@
.isActiveSubscriptionId(anyInt());
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator();
- doReturn(TEST_CARRIERID).when(mTelephonyManager).getSimCarrierId();
+ doReturn(TEST_CARRIERID).when(mTelephonyManager).getSimSpecificCarrierId();
// Add authority="telephony" to given telephonyProvider
ProviderInfo providerInfo = new ProviderInfo();
@@ -353,6 +356,8 @@
when(mockContextResources.getStringArray(anyInt())).thenReturn(new String[]{"ca", "us"});
notifyChangeCount = 0;
notifyChangeRestoreCount = 0;
+ // Required to access SIMINFO table
+ mTelephonyProviderTestable.fakeCallingUid(Process.PHONE_UID);
}
private void setUpMockContext(boolean isActiveSubId) {
@@ -700,12 +705,14 @@
final String insertIccId = "exampleIccId";
final String insertCardId = "exampleCardId";
final int insertProfileClass = SubscriptionManager.PROFILE_CLASS_DEFAULT;
+ final int insertPortIndex = 1;
contentValues.put(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, insertSubId);
contentValues.put(SubscriptionManager.DISPLAY_NAME, insertDisplayName);
contentValues.put(SubscriptionManager.CARRIER_NAME, insertCarrierName);
contentValues.put(SubscriptionManager.ICC_ID, insertIccId);
contentValues.put(SubscriptionManager.CARD_ID, insertCardId);
contentValues.put(SubscriptionManager.PROFILE_CLASS, insertProfileClass);
+ contentValues.put(SubscriptionManager.PORT_INDEX, insertPortIndex);
Log.d(TAG, "testSimTable Inserting contentValues: " + contentValues);
mContentResolver.insert(SimInfo.CONTENT_URI, contentValues);
@@ -717,6 +724,7 @@
SubscriptionManager.CARRIER_NAME,
SubscriptionManager.CARD_ID,
SubscriptionManager.PROFILE_CLASS,
+ SubscriptionManager.PORT_INDEX,
};
final String selection = SubscriptionManager.DISPLAY_NAME + "=?";
String[] selectionArgs = { insertDisplayName };
@@ -733,10 +741,11 @@
final String resultCarrierName = cursor.getString(1);
final String resultCardId = cursor.getString(2);
final int resultProfileClass = cursor.getInt(3);
+ final int resultPortIndex = cursor.getInt(4);
assertEquals(insertSubId, resultSubId);
assertEquals(insertCarrierName, resultCarrierName);
assertEquals(insertCardId, resultCardId);
- assertEquals(insertProfileClass, resultProfileClass);
+ assertEquals(insertPortIndex, resultPortIndex);
// delete test content
final String selectionToDelete = SubscriptionManager.DISPLAY_NAME + "=?";
@@ -2109,4 +2118,119 @@
assertNull(cursor);
}
+
+ @Test
+ @SmallTest
+ public void testSIMAPNLIST_MatchTheCarrierIDANDdifferentMNOAPN() {
+ setUpMockContext(true);
+
+ final String apnName = "apnName";
+ final String carrierName = "name";
+ final int carrierId = TEST_CARRIERID;
+
+ // Add an APN that have carrier id and matching MNO
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(Carriers.APN, apnName);
+ contentValues.put(Carriers.NAME, carrierName);
+ contentValues.put(Carriers.CARRIER_ID, carrierId);
+ contentValues.put(Carriers.NUMERIC, TEST_OPERATOR);
+ mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+ // Add MNO APN that have same carrier id, but different MNO
+ contentValues = new ContentValues();
+ contentValues.put(Carriers.APN, apnName);
+ contentValues.put(Carriers.NAME, carrierName);
+ contentValues.put(Carriers.CARRIER_ID, carrierId);
+ contentValues.put(Carriers.NUMERIC, TEST_OPERATOR_SECOND_MCCMNC);
+ mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+ // Query DB
+ final String[] testProjection =
+ {
+ Carriers.APN,
+ Carriers.NAME,
+ Carriers.CARRIER_ID,
+ Carriers.NUMERIC,
+ };
+
+ Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, testProjection, null, null, null);
+
+ // The query based on SIM_APN_LIST will return the APN which matches both carrier id and MNO
+ assertEquals(1, cursor.getCount());
+ cursor.moveToFirst();
+ assertEquals(TEST_OPERATOR, cursor.getString(cursor.getColumnIndex(Carriers.NUMERIC)));
+ }
+
+ @Test
+ @SmallTest
+ public void testSIMAPNLIST_MatchTheCarrierIDMissingMNO() {
+ setUpMockContext(true);
+
+ final String apnName = "apnName";
+ final String carrierName = "name";
+ final int carrierId = TEST_CARRIERID;
+
+ // Add an APN that have matching carrier id and no mno
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(Carriers.APN, apnName);
+ contentValues.put(Carriers.NAME, carrierName);
+ contentValues.put(Carriers.CARRIER_ID, carrierId);
+ mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+ // Add MNO APN that have non matching carrier id and no mno
+ contentValues = new ContentValues();
+ contentValues.put(Carriers.APN, apnName);
+ contentValues.put(Carriers.NAME, carrierName);
+ contentValues.put(Carriers.CARRIER_ID, 99999);
+ mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+ // Query DB
+ final String[] testProjection =
+ {
+ Carriers.APN,
+ Carriers.NAME,
+ Carriers.CARRIER_ID,
+ };
+
+ Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, testProjection, null, null, null);
+
+ // The query based on SIM_APN_LIST will return the APN which matches carrier id
+ assertEquals(1, cursor.getCount());
+ cursor.moveToFirst();
+ assertEquals(TEST_CARRIERID, cursor.getInt(cursor.getColumnIndex(Carriers.CARRIER_ID)));
+ }
+
+ @Test
+ @SmallTest
+ public void testSIMAPNLIST_MatchTheCarrierIDNOTMatchingMNO() {
+ setUpMockContext(true);
+
+ final String apnName = "apnName";
+ final String carrierName = "name";
+ final int carrierId = TEST_CARRIERID;
+
+ // Add an APN that have matching carrier id and not matching mno
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(Carriers.APN, apnName);
+ contentValues.put(Carriers.NAME, carrierName);
+ contentValues.put(Carriers.CARRIER_ID, carrierId);
+ contentValues.put(Carriers.NUMERIC, TEST_OPERATOR_SECOND_MCCMNC);
+ mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+ // Query DB
+ final String[] testProjection =
+ {
+ Carriers.APN,
+ Carriers.NAME,
+ Carriers.CARRIER_ID,
+ };
+
+ Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, testProjection, null, null, null);
+
+ // The query based on SIM_APN_LIST will return the APN which matches carrier id,
+ // even though the mno does not match
+ assertEquals(1, cursor.getCount());
+ cursor.moveToFirst();
+ assertEquals(TEST_CARRIERID, cursor.getInt(cursor.getColumnIndex(Carriers.CARRIER_ID)));
+ }
}