[automerger skipped] Merge "Fix cursor leak in TelephonyProvider" am: 46f8429df0 am: 3166b75108
am: f364048b95 -s ours
Change-Id: I8a59d91fb82cdbfe99dcbeae0d0ff2c9af6ef11a
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 125a3ae..59fa7bd 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -66,6 +66,13 @@
android:singleUser="true"
android:readPermission="android.permission.READ_SMS" />
+ <provider android:name="SmsChangesProvider"
+ android:authorities="sms-changes"
+ android:multiprocess="false"
+ android:exported="true"
+ android:singleUser="true"
+ android:readPermission="android.permission.READ_SMS" />
+
<!-- This is a singleton provider that is used by all users.
A new instance is not created for each user. And the db is shared
as well.
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 1c53b15..309a57b 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" product="tablet" msgid="9194799012395299737">"تهيئة شبكة الجوال"</string>
- <string name="app_label" product="default" msgid="8338087656149558019">"سعة تخزينية للهاتف والرسائل"</string>
+ <string name="app_label" product="default" msgid="8338087656149558019">"مساحة تخزين للهاتف والرسائل"</string>
</resources>
diff --git a/res/values-as/config.xml b/res/values-as/config.xml
new file mode 100644
index 0000000..99877a6
--- /dev/null
+++ b/res/values-as/config.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="persist_apns_for_plmn">
+ <item msgid="6413072509259000954">"20404"</item>
+ <item msgid="5639159280778239123">"310004"</item>
+ <item msgid="3860605521380788028">"310120"</item>
+ <item msgid="537693705785480198">"311480"</item>
+ </string-array>
+</resources>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
new file mode 100644
index 0000000..5a39f18
--- /dev/null
+++ b/res/values-as/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" product="tablet" msgid="9194799012395299737">"ম\'বাইল নেটৱৰ্ক কনফিগাৰেশ্বন"</string>
+ <string name="app_label" product="default" msgid="8338087656149558019">"ফ\'ন আৰু বাৰ্তাৰ সঞ্চয়াগাৰ"</string>
+</resources>
diff --git a/res/values-or/config.xml b/res/values-or/config.xml
new file mode 100644
index 0000000..99877a6
--- /dev/null
+++ b/res/values-or/config.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="persist_apns_for_plmn">
+ <item msgid="6413072509259000954">"20404"</item>
+ <item msgid="5639159280778239123">"310004"</item>
+ <item msgid="3860605521380788028">"310120"</item>
+ <item msgid="537693705785480198">"311480"</item>
+ </string-array>
+</resources>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
new file mode 100644
index 0000000..b004c4f
--- /dev/null
+++ b/res/values-or/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" product="tablet" msgid="9194799012395299737">"ମୋବାଇଲ୍ ନେଟ୍ୱର୍କ କନଫିଗରେଶନ୍"</string>
+ <string name="app_label" product="default" msgid="8338087656149558019">"ଫୋନ୍ ଓ ମେସେଜିଙ୍ଗ ଷ୍ଟୋରେଜ୍"</string>
+</resources>
diff --git a/src/com/android/providers/telephony/CarrierDatabaseHelper.java b/src/com/android/providers/telephony/CarrierDatabaseHelper.java
index b654a77..0b97da1 100644
--- a/src/com/android/providers/telephony/CarrierDatabaseHelper.java
+++ b/src/com/android/providers/telephony/CarrierDatabaseHelper.java
@@ -40,6 +40,7 @@
*/
public CarrierDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ setWriteAheadLoggingEnabled(false);
}
public static final String KEY_TYPE = "key_type";
diff --git a/src/com/android/providers/telephony/CarrierIdProvider.java b/src/com/android/providers/telephony/CarrierIdProvider.java
index 7f2de12..6dfa07b 100644
--- a/src/com/android/providers/telephony/CarrierIdProvider.java
+++ b/src/com/android/providers/telephony/CarrierIdProvider.java
@@ -328,6 +328,7 @@
*/
public CarrierIdDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ Log.d(TAG, "CarrierIdDatabaseHelper: " + DATABASE_VERSION);
setWriteAheadLoggingEnabled(false);
}
diff --git a/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java b/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java
index 2debc57..0149687 100644
--- a/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java
+++ b/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java
@@ -102,6 +102,7 @@
mContext = context;
// Memory optimization - close idle connections after 30s of inactivity
setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
+ setWriteAheadLoggingEnabled(false);
}
@Override
diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
index f7a446b..b8dc831 100644
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
@@ -22,6 +22,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.DefaultDatabaseErrorHandler;
@@ -294,6 +295,7 @@
mContext = context;
// Memory optimization - close idle connections after 30s of inactivity
setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
+ setWriteAheadLoggingEnabled(false);
try {
PhoneFactory.addLocalLog(TAG, 100);
} catch (IllegalArgumentException e) {
@@ -1064,6 +1066,29 @@
Sms.TYPE + "=" + Sms.MESSAGE_TYPE_INBOX +
" OR " +
Sms.TYPE + "=" + Sms.MESSAGE_TYPE_SENT + ";");
+
+ if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+ // Create a table to keep track of changes to SMS table - specifically on update to read
+ // and deletion of msgs
+ db.execSQL("CREATE TABLE sms_changes (" +
+ "_id INTEGER PRIMARY KEY," +
+ "orig_rowid INTEGER," +
+ "sub_id INTEGER," +
+ "type INTEGER," +
+ "new_read_status INTEGER" +
+ ");");
+ db.execSQL("CREATE TRIGGER sms_update_on_read_change_row " +
+ "AFTER UPDATE OF read ON sms WHEN NEW.read != OLD.read " +
+ "BEGIN " +
+ " INSERT INTO sms_changes VALUES(null, NEW._id, NEW.sub_id, " +
+ "0, NEW.read); " +
+ "END;");
+ db.execSQL("CREATE TRIGGER sms_delete_change_row " +
+ "AFTER DELETE ON sms " +
+ "BEGIN " +
+ " INSERT INTO sms_changes values(null, OLD._id, OLD.sub_id, 1, null); " +
+ "END;");
+ }
}
private void createCommonTables(SQLiteDatabase db) {
diff --git a/src/com/android/providers/telephony/SmsChangesProvider.java b/src/com/android/providers/telephony/SmsChangesProvider.java
new file mode 100644
index 0000000..3f14e2b
--- /dev/null
+++ b/src/com/android/providers/telephony/SmsChangesProvider.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.telephony;
+
+import android.app.AppOpsManager;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.util.Log;
+
+/**
+ * This is the ContentProvider for the table sms_changes.
+ * This provider is applicable only for Android Auto builds as
+ * this table exists only in Android Auto environment.
+ *
+ * This provider does not notify of changes.
+ * Interested observers should instead listen to notification on sms table, instead.
+ */
+public class SmsChangesProvider extends ContentProvider {
+ private final static String TAG = "SmsChangesProvider";
+
+ private static final String TABLE_SMS_CHANGES = "sms_changes";
+
+ // Db open helper for tables stored in CE(Credential Encrypted) storage.
+ private SQLiteOpenHelper mCeOpenHelper;
+
+ @Override
+ public String getType(Uri url) {
+ return null;
+ }
+
+ @Override
+ public boolean onCreate() {
+ setAppOps(AppOpsManager.OP_READ_SMS, AppOpsManager.OP_WRITE_SMS);
+ mCeOpenHelper = MmsSmsDatabaseHelper.getInstanceForCe(getContext());
+ return true;
+ }
+
+
+ @Override
+ public Cursor query(Uri url, String[] projectionIn, String selection,
+ String[] selectionArgs, String sort) {
+ // return if FEATURE_AUTOMOTIVE is not set
+ if (!isAutoFeatureSet()) {
+ return null;
+ }
+
+ // Only support one type of query
+ // Caller sends content://mms-sms and other params
+ if (!isUrlSupported(url)) {
+ return null;
+ }
+
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+ qb.setTables(TABLE_SMS_CHANGES);
+ SQLiteDatabase db = mCeOpenHelper.getReadableDatabase();
+ return qb.query(db, projectionIn, selection, selectionArgs,
+ null /* groupBy */, null /* having */,
+ null /* sortOrder */);
+ }
+
+ @Override
+ public Uri insert(Uri url, ContentValues initialValues) {
+ return null;
+ }
+
+ @Override
+ public int delete(Uri url, String where, String[] whereArgs) {
+ // return if FEATURE_AUTOMOTIVE is not set
+ if (!isAutoFeatureSet()) {
+ return 0;
+ }
+
+ // only support deletion of all data from the table
+ if (!isUrlSupported(url)) return 0;
+
+ return mCeOpenHelper.getWritableDatabase().delete(TABLE_SMS_CHANGES,
+ null /* whereClause */, null /* whereArgs */);
+ }
+
+ private boolean isUrlSupported(Uri url) {
+ if (sURLMatcher.match(url) != SMSCHANGES_URL) {
+ Log.e(TAG, "Invalid or Unsupported request: " + url);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
+ return 0;
+ }
+
+ private boolean isAutoFeatureSet() {
+ return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+ }
+
+ private static final int SMSCHANGES_URL = 0;
+
+ private static final UriMatcher sURLMatcher =
+ new UriMatcher(UriMatcher.NO_MATCH);
+
+ static {
+ sURLMatcher.addURI("sms-changes", null, SMSCHANGES_URL);
+ }
+}
diff --git a/src/com/android/providers/telephony/SmsProvider.java b/src/com/android/providers/telephony/SmsProvider.java
index 95db869..7d556a7 100644
--- a/src/com/android/providers/telephony/SmsProvider.java
+++ b/src/com/android/providers/telephony/SmsProvider.java
@@ -16,6 +16,9 @@
package com.android.providers.telephony;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_IGNORED;
+
import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.ContentProvider;
@@ -33,6 +36,7 @@
import android.os.Binder;
import android.os.UserHandle;
import android.provider.Contacts;
+import android.provider.Settings;
import android.provider.Telephony;
import android.provider.Telephony.MmsSms;
import android.provider.Telephony.Sms;
@@ -842,6 +846,19 @@
}
}
+ /** @hide */
+ @Override
+ protected int interpretDefaultAppOpMode(int op) {
+ if (op == AppOpsManager.OP_WRITE_SMS) {
+ return MODE_IGNORED;
+ } else {
+ boolean accessRestrictionEnabled = Settings.Global.getInt(
+ getContext().getContentResolver(),
+ Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0) == 1;
+ return accessRestrictionEnabled ? MODE_IGNORED : MODE_ALLOWED;
+ }
+ }
+
// Db open helper for tables stored in CE(Credential Encrypted) storage.
@VisibleForTesting
public SQLiteOpenHelper mCeOpenHelper;
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 22e1a24..db7e4e7 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -169,6 +169,7 @@
private static final int URL_PREFERAPNSET_USING_SUBID = 22;
private static final int URL_SIM_APN_LIST = 23;
private static final int URL_SIM_APN_LIST_ID = 24;
+ private static final int URL_FILTERED_USING_SUBID = 25;
private static final String TAG = "TelephonyProvider";
private static final String CARRIERS_TABLE = "carriers";
@@ -420,6 +421,9 @@
// Only called by Settings app, DcTracker and other telephony components to get a
// single APN according to whether DPC records are enforced.
s_urlMatcher.addURI("telephony", "carriers/filtered/#", URL_FILTERED_ID);
+ // Used by DcTracker to pass a subId.
+ s_urlMatcher.addURI("telephony", "carriers/filtered/subId/*", URL_FILTERED_USING_SUBID);
+
// Only Called by DevicePolicyManager to enforce DPC records.
s_urlMatcher.addURI("telephony", "carriers/enforce_managed", URL_ENFORCE_MANAGED);
s_urlMatcher.addURI("telephony", "carriers/sim_apn_list", URL_SIM_APN_LIST);
@@ -466,6 +470,7 @@
mContext = context;
// Memory optimization - close idle connections after 30s of inactivity
setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
+ setWriteAheadLoggingEnabled(false);
}
@VisibleForTesting
@@ -2700,8 +2705,19 @@
break;
}
- case URL_FILTERED_ID: {
- qb.appendWhere("_id = " + url.getLastPathSegment());
+ case URL_FILTERED_ID:
+ case URL_FILTERED_USING_SUBID: {
+ String idString = url.getLastPathSegment();
+ if (match == URL_FILTERED_ID) {
+ qb.appendWhere("_id = " + idString);
+ } else {
+ try {
+ subId = Integer.parseInt(idString);
+ } catch (NumberFormatException e) {
+ loge("NumberFormatException" + e);
+ return null;
+ }
+ }
}
//intentional fall through from above case
case URL_FILTERED: {
@@ -2888,6 +2904,7 @@
case URL_ID:
case URL_FILTERED_ID:
+ case URL_FILTERED_USING_SUBID:
return "vnd.android.cursor.item/telephony-carrier";
case URL_PREFERAPN_USING_SUBID: