[automerger skipped] Merge "Remove old CellBroadcastProvider" am: b5c86eb199 am: 9d8d038b8b
am: 2bb03f7dc8 -s ours
am skip reason: change_id Ie78cf392fc04a25e9283939194d6b5a42d9e31fd with SHA1 1e76db24be is in history
Change-Id: I7e430cb5557c3450d5e70edae26c3e5126f0f390
diff --git a/Android.bp b/Android.bp
index eabd567..ad23fcd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,7 +1,13 @@
+filegroup {
+ name: "jarjar-rules",
+ srcs: ["jarjar-rules.txt"],
+}
+
android_app {
name: "TelephonyProvider",
privileged: true,
srcs: ["src/**/*.java"],
+ jarjar_rules: ":jarjar-rules",
platform_apis: true,
certificate: "platform",
libs: ["telephony-common"],
diff --git a/jarjar-rules.txt b/jarjar-rules.txt
new file mode 100644
index 0000000..b0d73d3
--- /dev/null
+++ b/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.android.internal.util.XmlUtils* com.android.internal.telephony.XmlUtils@1
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 6cfcdfb..f3baf24 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/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">"Configuration du réseau mobile"</string>
- <string name="app_label" product="default" msgid="8338087656149558019">"Stockage tél. et SMS/MMS"</string>
+ <string name="app_label" product="default" msgid="8338087656149558019">"Téléphone et stockage des messages"</string>
</resources>
diff --git a/src/com/android/providers/telephony/CarrierIdProvider.java b/src/com/android/providers/telephony/CarrierIdProvider.java
index 44f053d..d43e6c6 100644
--- a/src/com/android/providers/telephony/CarrierIdProvider.java
+++ b/src/com/android/providers/telephony/CarrierIdProvider.java
@@ -25,23 +25,23 @@
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.MatrixCursor;
-import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
+import android.os.FileUtils;
import android.os.SystemProperties;
import android.provider.Telephony.CarrierId;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.nano.CarrierIdProto;
+import com.android.internal.telephony.util.TelephonyUtils;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -54,8 +54,6 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import libcore.io.IoUtils;
-
/**
* This class provides the ability to query the Carrier Identification databases
* (A.K.A. cid) which is stored in a SQLite database.
@@ -536,7 +534,7 @@
} catch (IOException ex) {
Log.e(TAG, "read carrier list from assets pb failure: " + ex);
} finally {
- IoUtils.closeQuietly(is);
+ FileUtils.closeQuietly(is);
}
try {
is = new FileInputStream(new File(Environment.getDataDirectory(), OTA_UPDATED_PB_PATH));
@@ -544,7 +542,7 @@
} catch (IOException ex) {
Log.e(TAG, "read carrier list from ota pb failure: " + ex);
} finally {
- IoUtils.closeQuietly(is);
+ FileUtils.closeQuietly(is);
}
// compare version
@@ -553,7 +551,7 @@
version = assets.version;
}
// bypass version check for ota carrier id test
- if (ota != null && ((Build.IS_DEBUGGABLE && SystemProperties.getBoolean(
+ if (ota != null && ((TelephonyUtils.IS_DEBUGGABLE && SystemProperties.getBoolean(
"persist.telephony.test.carrierid.ota", false))
|| (ota.version > version))) {
carrierList = ota;
diff --git a/src/com/android/providers/telephony/MmsProvider.java b/src/com/android/providers/telephony/MmsProvider.java
index 30158c3..96059d7 100644
--- a/src/com/android/providers/telephony/MmsProvider.java
+++ b/src/com/android/providers/telephony/MmsProvider.java
@@ -31,7 +31,6 @@
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Binder;
-import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.provider.BaseColumns;
@@ -44,6 +43,8 @@
import android.provider.Telephony.Mms.Rate;
import android.provider.Telephony.MmsSms;
import android.provider.Telephony.Threads;
+import android.system.ErrnoException;
+import android.system.Os;
import android.text.TextUtils;
import android.util.Log;
@@ -518,9 +519,13 @@
// Give everyone rw permission until we encrypt the file
// (in PduPersister.persistData). Once the file is encrypted, the
// permissions will be set to 0644.
- int result = FileUtils.setPermissions(path, 0666, -1, -1);
- if (LOCAL_LOGV) {
- Log.d(TAG, "MmsProvider.insert setPermissions result: " + result);
+ try {
+ Os.chmod(path, 0666);
+ if (LOCAL_LOGV) {
+ Log.d(TAG, "MmsProvider.insert chmod is successful");
+ }
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Exception in chmod: " + e);
}
} catch (IOException e) {
Log.e(TAG, "createNewFile", e);
@@ -816,10 +821,13 @@
String path = getContext().getDir(PARTS_DIR_NAME, 0).getPath() + '/' +
uri.getPathSegments().get(1);
// Reset the file permission back to read for everyone but me.
- int result = FileUtils.setPermissions(path, 0644, -1, -1);
- if (LOCAL_LOGV) {
- Log.d(TAG, "MmsProvider.update setPermissions result: " + result +
- " for path: " + path);
+ try {
+ Os.chmod(path, 0644);
+ if (LOCAL_LOGV) {
+ Log.d(TAG, "MmsProvider.update chmod is successful for path: " + path);
+ }
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Exception in chmod: " + e);
}
return 0;
diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
index 4add85d..034efaa 100644
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
@@ -47,7 +47,6 @@
import android.provider.Telephony.Threads;
import android.telephony.SubscriptionManager;
import android.util.Log;
-import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.PhoneFactory;
@@ -267,7 +266,7 @@
/**
* The primary purpose of this DatabaseErrorHandler is to broadcast an intent on corruption and
- * print a Slog.wtf so database corruption can be caught earlier.
+ * print a Log.wtf so database corruption can be caught earlier.
*/
private static class MmsSmsDatabaseErrorHandler implements DatabaseErrorHandler {
private DefaultDatabaseErrorHandler mDefaultDatabaseErrorHandler
@@ -571,7 +570,7 @@
}
private static void localLogWtf(String logMsg) {
- Slog.wtf(TAG, logMsg);
+ Log.wtf(TAG, logMsg);
PhoneFactory.localLog(TAG, logMsg);
}
diff --git a/src/com/android/providers/telephony/MmsSmsProvider.java b/src/com/android/providers/telephony/MmsSmsProvider.java
index 1170aad..0624be7 100644
--- a/src/com/android/providers/telephony/MmsSmsProvider.java
+++ b/src/com/android/providers/telephony/MmsSmsProvider.java
@@ -42,6 +42,7 @@
import android.provider.Telephony.ThreadsColumns;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Patterns;
import com.google.android.mms.pdu.PduHeaders;
@@ -51,6 +52,8 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* This class provides the ability to query the MMS and SMS databases
@@ -102,6 +105,17 @@
private static final int URI_MESSAGE_ID_TO_THREAD = 18;
/**
+ * Regex pattern for names and email addresses.
+ * <ul>
+ * <li><em>mailbox</em> = {@code name-addr}</li>
+ * <li><em>name-addr</em> = {@code [display-name] angle-addr}</li>
+ * <li><em>angle-addr</em> = {@code [CFWS] "<" addr-spec ">" [CFWS]}</li>
+ * </ul>
+ */
+ public static final Pattern NAME_ADDR_EMAIL_PATTERN =
+ Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");
+
+ /**
* the name of the table that is used to store the queue of
* messages(both MMS and SMS) to be sent/downloaded.
*/
@@ -530,8 +544,8 @@
* Return the canonical address ID for this address.
*/
private long getSingleAddressId(String address) {
- boolean isEmail = Mms.isEmailAddress(address);
- boolean isPhoneNumber = Mms.isPhoneNumber(address);
+ boolean isEmail = isEmailAddress(address);
+ boolean isPhoneNumber = isPhoneNumber(address);
// We lowercase all email addresses, but not addresses that aren't numbers, because
// that would incorrectly turn an address such as "My Vodafone" into "my vodafone"
@@ -1414,4 +1428,47 @@
Log.w(LOG_TAG, "Ignored unsupported " + method + " call");
return null;
}
+
+ /**
+ * Is the specified address an email address?
+ *
+ * @param address the input address to test
+ * @return true if address is an email address; false otherwise.
+ */
+ private static boolean isEmailAddress(String address) {
+ if (TextUtils.isEmpty(address)) {
+ return false;
+ }
+
+ String s = extractAddrSpec(address);
+ Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);
+ return match.matches();
+ }
+
+ /**
+ * Is the specified number a phone number?
+ *
+ * @param number the input number to test
+ * @return true if number is a phone number; false otherwise.
+ */
+ private static boolean isPhoneNumber(String number) {
+ if (TextUtils.isEmpty(number)) {
+ return false;
+ }
+
+ Matcher match = Patterns.PHONE.matcher(number);
+ return match.matches();
+ }
+
+ /**
+ * Helper method to extract email address from address string.
+ */
+ private static String extractAddrSpec(String address) {
+ Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);
+
+ if (match.matches()) {
+ return match.group(2);
+ }
+ return address;
+ }
}
diff --git a/src/com/android/providers/telephony/TelephonyBackupAgent.java b/src/com/android/providers/telephony/TelephonyBackupAgent.java
index 437b5a2..dcf98c7 100644
--- a/src/com/android/providers/telephony/TelephonyBackupAgent.java
+++ b/src/com/android/providers/telephony/TelephonyBackupAgent.java
@@ -531,9 +531,7 @@
for (File file : files) {
final String fileName = file.getName();
- if (DEBUG) {
- Log.d(TAG, "onHandleIntent restoring file " + fileName);
- }
+ Log.d(TAG, "onHandleIntent restoring file " + fileName);
try (FileInputStream fileInputStream = new FileInputStream(file)) {
mTelephonyBackupAgent.doRestoreFile(fileName, fileInputStream.getFD());
didRestore = true;
@@ -547,9 +545,7 @@
if (didRestore) {
// Tell the default sms app to do a full sync now that the messages have been
// restored.
- if (DEBUG) {
- Log.d(TAG, "onHandleIntent done - notifying default sms app");
- }
+ Log.d(TAG, "onHandleIntent done - notifying default sms app");
ProviderUtil.notifyIfNotDefaultSmsApp(null /*uri*/, null /*calling package*/,
this);
}
@@ -605,25 +601,17 @@
}
private void doRestoreFile(String fileName, FileDescriptor fd) throws IOException {
- if (DEBUG) {
- Log.d(TAG, "Restoring file " + fileName);
- }
+ Log.d(TAG, "Restoring file " + fileName);
try (JsonReader jsonReader = getJsonReader(fd)) {
if (fileName.endsWith(SMS_BACKUP_FILE_SUFFIX)) {
- if (DEBUG) {
- Log.d(TAG, "Restoring SMS");
- }
+ Log.d(TAG, "Restoring SMS");
putSmsMessagesToProvider(jsonReader);
} else if (fileName.endsWith(MMS_BACKUP_FILE_SUFFIX)) {
- if (DEBUG) {
- Log.d(TAG, "Restoring text MMS");
- }
+ Log.d(TAG, "Restoring text MMS");
putMmsMessagesToProvider(jsonReader);
} else {
- if (DEBUG) {
- Log.e(TAG, "Unknown file to restore:" + fileName);
- }
+ Log.e(TAG, "Unknown file to restore:" + fileName);
}
}
}
@@ -654,6 +642,7 @@
@VisibleForTesting
void putMmsMessagesToProvider(JsonReader jsonReader) throws IOException {
jsonReader.beginArray();
+ int total = 0;
while (jsonReader.hasNext()) {
final Mms mms = readMmsFromReader(jsonReader);
if (DEBUG) {
@@ -662,11 +651,15 @@
if (doesMmsExist(mms)) {
if (DEBUG) {
Log.e(TAG, String.format("Mms: %s already exists", mms.toString()));
+ } else {
+ Log.w(TAG, "Mms: Found duplicate MMS");
}
continue;
}
+ total++;
addMmsMessage(mms);
}
+ Log.d(TAG, "putMmsMessagesToProvider handled " + total + " new messages.");
}
@VisibleForTesting
@@ -823,6 +816,8 @@
default:
if (DEBUG) {
Log.w(TAG, "readSmsValuesFromReader Unknown name:" + name);
+ } else {
+ Log.w(TAG, "readSmsValuesFromReader encountered unknown name.");
}
jsonReader.skipValue();
break;
@@ -955,9 +950,7 @@
mms.values.put(name, jsonReader.nextString());
break;
default:
- if (DEBUG) {
- Log.d(TAG, "Unknown name:" + name);
- }
+ Log.d(TAG, "Unknown JSON element name:" + name);
jsonReader.skipValue();
break;
}
@@ -995,9 +988,7 @@
values,
ARCHIVE_THREAD_SELECTION,
new String[] { Long.toString(threadId)}) != 1) {
- if (DEBUG) {
- Log.e(TAG, "archiveThread: failed to update database");
- }
+ Log.e(TAG, "archiveThread: failed to update database");
}
}
@@ -1066,9 +1057,7 @@
addrValues.put(name, jsonReader.nextString());
break;
default:
- if (DEBUG) {
- Log.d(TAG, "Unknown name:" + name);
- }
+ Log.d(TAG, "Unknown JSON Element name:" + name);
jsonReader.skipValue();
break;
}
@@ -1099,9 +1088,7 @@
attachmentValues.put(name, jsonReader.nextString());
break;
default:
- if (DEBUG) {
- Log.d(TAG, "getMmsAttachmentsFromReader Unknown name:" + name);
- }
+ Log.d(TAG, "getMmsAttachmentsFromReader Unknown name:" + name);
jsonReader.skipValue();
break;
}
@@ -1110,9 +1097,7 @@
if (attachmentValues.containsKey(MMS_ATTACHMENT_FILENAME)) {
mms.attachments.add(attachmentValues);
} else {
- if (DEBUG) {
- Log.d(TAG, "Attachment json with no filenames");
- }
+ Log.d(TAG, "Attachment json with no filenames");
}
}
jsonReader.endArray();
@@ -1140,9 +1125,7 @@
values.put(Telephony.Mms.Part.CONTENT_LOCATION, "smil.xml");
values.put(Telephony.Mms.Part.TEXT, smil);
if (mContentResolver.insert(partUri, values) == null) {
- if (DEBUG) {
- Log.e(TAG, "Could not insert SMIL part");
- }
+ Log.e(TAG, "Could not insert SMIL part");
return;
}
}
@@ -1162,9 +1145,7 @@
values.put(Telephony.Mms.Part.TEXT, mms.body == null ? "" : mms.body.text);
if (mContentResolver.insert(partUri, values) == null) {
- if (DEBUG) {
- Log.e(TAG, "Could not insert body part");
- }
+ Log.e(TAG, "Could not insert body part");
return;
}
}
@@ -1184,9 +1165,7 @@
getDataDir() + ATTACHMENT_DATA_PATH + filename);
Uri newPartUri = mContentResolver.insert(partUri, values);
if (newPartUri == null) {
- if (DEBUG) {
- Log.e(TAG, "Could not insert attachment part");
- }
+ Log.e(TAG, "Could not insert attachment part");
return;
}
}
@@ -1195,9 +1174,7 @@
// Insert mms.
final Uri mmsUri = mContentResolver.insert(Telephony.Mms.CONTENT_URI, mms.values);
if (mmsUri == null) {
- if (DEBUG) {
- Log.e(TAG, "Could not insert mms");
- }
+ Log.e(TAG, "Could not insert mms");
return;
}
@@ -1301,9 +1278,7 @@
try {
threadId = Telephony.Threads.getOrCreateThreadId(this, recipients);
} catch (RuntimeException e) {
- if (DEBUG) {
- Log.e(TAG, e.toString());
- }
+ Log.e(TAG, "Problem obtaining thread.", e);
}
mCacheGetOrCreateThreadId.put(recipients, threadId);
return threadId;
@@ -1377,15 +1352,11 @@
try {
longId = Long.parseLong(id);
if (longId < 0) {
- if (DEBUG) {
- Log.e(TAG, "getAddresses: invalid id " + longId);
- }
+ Log.e(TAG, "getAddresses: invalid id " + longId);
continue;
}
} catch (final NumberFormatException ex) {
- if (DEBUG) {
- Log.e(TAG, "getAddresses: invalid id. " + ex, ex);
- }
+ Log.e(TAG, "getAddresses: invalid id " + ex, ex);
// skip this id
continue;
}
@@ -1397,10 +1368,9 @@
ContentUris.withAppendedId(SINGLE_CANONICAL_ADDRESS_URI, longId),
null, null, null, null);
} catch (final Exception e) {
- if (DEBUG) {
- Log.e(TAG, "getAddresses: query failed for id " + longId, e);
- }
+ Log.e(TAG, "getAddresses: query failed for id " + longId, e);
}
+
if (c != null) {
try {
if (c.moveToFirst()) {
@@ -1408,9 +1378,7 @@
if (!TextUtils.isEmpty(number)) {
numbers.add(number);
} else {
- if (DEBUG) {
- Log.d(TAG, "Canonical MMS/SMS address is empty for id: " + longId);
- }
+ Log.d(TAG, "Canonical MMS/SMS address is empty for id: " + longId);
}
}
} finally {
@@ -1419,9 +1387,7 @@
}
}
if (numbers.isEmpty()) {
- if (DEBUG) {
- Log.d(TAG, "No MMS addresses found from ids string [" + spaceSepIds + "]");
- }
+ Log.d(TAG, "No MMS addresses found from ids string [" + spaceSepIds + "]");
}
return numbers;
}
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 0edbffc..359ff50 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -93,7 +93,6 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Environment;
-import android.os.FileUtils;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
@@ -101,7 +100,6 @@
import android.os.UserHandle;
import android.provider.Telephony;
import android.telephony.ServiceState;
-import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
@@ -112,19 +110,20 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.IApnSourceService;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.dataconnection.ApnSettingUtils;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.util.XmlUtils;
+import android.service.carrier.IApnSourceService;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
@@ -137,6 +136,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.zip.CheckedInputStream;
import java.util.zip.CRC32;
public class TelephonyProvider extends ContentProvider
@@ -584,10 +584,18 @@
}
private long getChecksum(File file) {
- long checksum = -1;
- try {
- checksum = FileUtils.checksumCrc32(file);
- if (DBG) log("Checksum for " + file.getAbsolutePath() + " is " + checksum);
+ CRC32 checkSummer = new CRC32();
+ long checkSum = -1;
+ try (CheckedInputStream cis =
+ new CheckedInputStream(new FileInputStream(file), checkSummer)){
+ byte[] buf = new byte[128];
+ if(cis != null) {
+ while(cis.read(buf) >= 0) {
+ // Just read for checksum to get calculated.
+ }
+ }
+ checkSum = checkSummer.getValue();
+ if (DBG) log("Checksum for " + file.getAbsolutePath() + " is " + checkSum);
} catch (FileNotFoundException e) {
loge("FileNotFoundException for " + file.getAbsolutePath() + ":" + e);
} catch (IOException e) {
@@ -599,14 +607,14 @@
try (InputStream inputStream = mContext.getResources().
openRawResource(com.android.internal.R.xml.apns)) {
byte[] array = toByteArray(inputStream);
- CRC32 c = new CRC32();
- c.update(array);
- checksum += c.getValue();
- if (DBG) log("Checksum after adding resource is " + checksum);
+ checkSummer.reset();
+ checkSummer.update(array);
+ checkSum += checkSummer.getValue();
+ if (DBG) log("Checksum after adding resource is " + checkSummer.getValue());
} catch (IOException | Resources.NotFoundException e) {
loge("Exception when calculating checksum for internal apn resources: " + e);
}
- return checksum;
+ return checkSum;
}
private byte[] toByteArray(InputStream input) throws IOException {
@@ -3779,15 +3787,6 @@
throw new SecurityException("No permission to write APN settings");
}
- private void checkPhonePrivilegePermission() {
- int status = getContext().checkCallingOrSelfPermission(
- "android.permission.READ_PRIVILEGED_PHONE_STATE");
- if (status == PackageManager.PERMISSION_GRANTED) {
- return;
- }
- throw new SecurityException("No phone privilege permission");
- }
-
private DatabaseHelper mOpenHelper;
private void restoreDefaultAPN(int subId) {
diff --git a/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java b/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java
index bc39260..13917ff 100644
--- a/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java
+++ b/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java
@@ -81,8 +81,8 @@
private class FakeContentResolver extends MockContentResolver {
@Override
- public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
- super.notifyChange(uri, observer, syncToNetwork);
+ public void notifyChange(Uri uri, ContentObserver observer) {
+ super.notifyChange(uri, observer);
Log.d(TAG, "onChanged(uri=" + uri + ")" + observer);
mContentObserver.dispatchChange(false, uri);
}