summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/providers/contacts/MetadataEntryParser.java225
-rw-r--r--tests/assets/test1/testFileDeviceContactMetadataJSON.txt61
-rw-r--r--tests/src/com/android/providers/contacts/MetadataEntryParserTest.java284
3 files changed, 570 insertions, 0 deletions
diff --git a/src/com/android/providers/contacts/MetadataEntryParser.java b/src/com/android/providers/contacts/MetadataEntryParser.java
new file mode 100644
index 0000000..a276cae
--- /dev/null
+++ b/src/com/android/providers/contacts/MetadataEntryParser.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2015 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.contacts;
+
+import android.text.TextUtils;
+import com.android.providers.contacts.util.NeededForTesting;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+
+@NeededForTesting
+public class MetadataEntryParser {
+
+ private final static String UNIQUE_CONTACT_ID = "unique_contact_id";
+ private final static String ACCOUNT_TYPE = "account_type";
+ private final static String CUSTOM_ACCOUNT_TYPE = "custom_account_type";
+ private final static String ENUM_VALUE_FOR_CUSTOM_ACCOUNT = "CUSTOM_ACCOUNT";
+ private final static String ACCOUNT_NAME = "account_name";
+ private final static String CONTACT_ID = "contact_id";
+ private final static String CONTACT_PREFS = "contact_prefs";
+ private final static String SEND_TO_VOICEMAIL = "send_to_voicemail";
+ private final static String STARRED = "starred";
+ private final static String PINNED = "pinned";
+ private final static String AGGREGATION_DATA = "aggregation_data";
+ private final static String CONTACT_IDS = "contact_ids";
+ private final static String TYPE = "type";
+ private final static String FIELD_DATA = "field_data";
+ private final static String FIELD_DATA_ID = "field_data_id";
+ private final static String FIELD_DATA_PREFS = "field_data_prefs";
+ private final static String IS_PRIMARY = "is_primary";
+ private final static String IS_SUPER_PRIMARY = "is_super_primary";
+ private final static String USAGE_STATS = "usage_stats";
+ private final static String USAGE_TYPE = "usage_type";
+ private final static String LAST_TIME_USED = "last_time_used";
+ private final static String USAGE_COUNT = "usage_count";
+
+ @NeededForTesting
+ public static class UsageStats {
+ final String mUsageType;
+ final long mLastTimeUsed;
+ final int mTimesUsed;
+
+ @NeededForTesting
+ public UsageStats(String usageType, long lastTimeUsed, int timesUsed) {
+ this.mUsageType = usageType;
+ this.mLastTimeUsed = lastTimeUsed;
+ this.mTimesUsed = timesUsed;
+ }
+ }
+
+ @NeededForTesting
+ public static class FieldData {
+ final long mFieldDataId;
+ final boolean mIsPrimary;
+ final boolean mIsSuperPrimary;
+ final ArrayList<UsageStats> mUsageStatsList;
+
+ @NeededForTesting
+ public FieldData(long fieldDataId, boolean isPrimary, boolean isSuperPrimary,
+ ArrayList<UsageStats> usageStatsList) {
+ this.mFieldDataId = fieldDataId;
+ this.mIsPrimary = isPrimary;
+ this.mIsSuperPrimary = isSuperPrimary;
+ this.mUsageStatsList = usageStatsList;
+ }
+ }
+
+ @NeededForTesting
+ public static class AggregationData {
+ final long mRawContactId1;
+ final long mRawContactId2;
+ final String mType;
+
+ @NeededForTesting
+ public AggregationData(long rawContactId1, long rawContactId2, String type) {
+ this.mRawContactId1 = rawContactId1;
+ this.mRawContactId2 = rawContactId2;
+ this.mType = type;
+ }
+ }
+
+ @NeededForTesting
+ public static class MetadataEntry {
+ final long mRawContactId;
+ final String mAccountType;
+ final String mAccountName;
+ final int mSendToVoicemail;
+ final int mStarred;
+ final int mPinned;
+ final ArrayList<FieldData> mFieldDatas;
+ final ArrayList<AggregationData> mAggregationDatas;
+
+ @NeededForTesting
+ public MetadataEntry(long rawContactId, String accountType, String accountName,
+ int sendToVoicemail, int starred, int pinned,
+ ArrayList<FieldData> fieldDatas,
+ ArrayList<AggregationData> aggregationDatas) {
+ this.mRawContactId = rawContactId;
+ this.mAccountType = accountType;
+ this.mAccountName = accountName;
+ this.mSendToVoicemail = sendToVoicemail;
+ this.mStarred = starred;
+ this.mPinned = pinned;
+ this.mFieldDatas = fieldDatas;
+ this.mAggregationDatas = aggregationDatas;
+ }
+ }
+
+ @NeededForTesting
+ static MetadataEntry parseDataToMetaDataEntry(String inputData) {
+ if (TextUtils.isEmpty(inputData)) {
+ throw new IllegalArgumentException("Input cannot be empty.");
+ }
+
+ try {
+ final JSONObject root = new JSONObject(inputData);
+ // Parse to get rawContactId and account info.
+ final JSONObject uniqueContact = root.getJSONObject(UNIQUE_CONTACT_ID);
+ final String rawContactId = uniqueContact.getString(CONTACT_ID);
+ String accountType = uniqueContact.getString(ACCOUNT_TYPE);
+ if (ENUM_VALUE_FOR_CUSTOM_ACCOUNT.equals(accountType)) {
+ accountType = uniqueContact.getString(CUSTOM_ACCOUNT_TYPE);
+ }
+ final String accountName = uniqueContact.getString(ACCOUNT_NAME);
+ if (TextUtils.isEmpty(rawContactId) || TextUtils.isEmpty(accountType)
+ || TextUtils.isEmpty(accountName)) {
+ throw new IllegalArgumentException(
+ "contact_id, account_type, account_name cannot be empty.");
+ }
+
+ // Parse contactPrefs to get sendToVoicemail, starred, pinned.
+ final JSONObject contactPrefs = root.getJSONObject(CONTACT_PREFS);
+ final boolean sendToVoicemail = contactPrefs.getBoolean(SEND_TO_VOICEMAIL);
+ final boolean starred = contactPrefs.getBoolean(STARRED);
+ final int pinned = contactPrefs.getInt(PINNED);
+
+ // Parse aggregationDatas
+ final ArrayList<AggregationData> aggregationsList = new ArrayList<AggregationData>();
+ if (root.has(AGGREGATION_DATA)) {
+ final JSONArray aggregationDatas = root.getJSONArray(AGGREGATION_DATA);
+
+ for (int i = 0; i < aggregationDatas.length(); i++) {
+ final JSONObject aggregationData = aggregationDatas.getJSONObject(i);
+ final JSONArray contacts = aggregationData.getJSONArray(CONTACT_IDS);
+
+ if (contacts.length() != 2) {
+ throw new IllegalArgumentException(
+ "There should be two contacts for each aggregation.");
+ }
+ final JSONObject rawContact1 = contacts.getJSONObject(0);
+ final long rawContactId1 = rawContact1.getLong(CONTACT_ID);
+ final JSONObject rawContact2 = contacts.getJSONObject(1);
+ final long rawContactId2 = rawContact2.getLong(CONTACT_ID);
+ final String type = aggregationData.getString(TYPE);
+ if (TextUtils.isEmpty(type)) {
+ throw new IllegalArgumentException("Aggregation type cannot be empty.");
+ }
+
+ final AggregationData aggregation = new AggregationData(
+ rawContactId1, rawContactId2, type);
+ aggregationsList.add(aggregation);
+ }
+ }
+
+ // Parse fieldDatas
+ final ArrayList<FieldData> fieldDatasList = new ArrayList<FieldData>();
+ if (root.has(FIELD_DATA)) {
+ final JSONArray fieldDatas = root.getJSONArray(FIELD_DATA);
+
+ for (int i = 0; i < fieldDatas.length(); i++) {
+ final JSONObject fieldData = fieldDatas.getJSONObject(i);
+ final long fieldDataId = fieldData.getLong(FIELD_DATA_ID);
+ final JSONObject fieldDataPrefs = fieldData.getJSONObject(FIELD_DATA_PREFS);
+ final boolean isPrimary = fieldDataPrefs.getBoolean(IS_PRIMARY);
+ final boolean isSuperPrimary = fieldDataPrefs.getBoolean(IS_SUPER_PRIMARY);
+
+ final ArrayList<UsageStats> usageStatsList = new ArrayList<UsageStats>();
+ if (fieldData.has(USAGE_STATS)) {
+ final JSONArray usageStats = fieldData.getJSONArray(USAGE_STATS);
+ for (int j = 0; j < usageStats.length(); j++) {
+ final JSONObject usageStat = usageStats.getJSONObject(j);
+ final String usageType = usageStat.getString(USAGE_TYPE);
+ if (TextUtils.isEmpty(usageType)) {
+ throw new IllegalArgumentException("Usage type cannot be empty.");
+ }
+ final long lastTimeUsed = usageStat.getLong(LAST_TIME_USED);
+ final int usageCount = usageStat.getInt(USAGE_COUNT);
+
+ final UsageStats usageStatsParsed = new UsageStats(
+ usageType, lastTimeUsed, usageCount);
+ usageStatsList.add(usageStatsParsed);
+ }
+ }
+
+ final FieldData fieldDataParse = new FieldData(fieldDataId, isPrimary,
+ isSuperPrimary, usageStatsList);
+ fieldDatasList.add(fieldDataParse);
+ }
+ }
+ final MetadataEntry metaDataEntry = new MetadataEntry(Long.parseLong(rawContactId),
+ accountType, accountName, sendToVoicemail ? 1 : 0, starred ? 1 : 0, pinned,
+ fieldDatasList, aggregationsList);
+ return metaDataEntry;
+ } catch (JSONException e) {
+ throw new IllegalArgumentException("JSON Exception.", e);
+ }
+ }
+}
diff --git a/tests/assets/test1/testFileDeviceContactMetadataJSON.txt b/tests/assets/test1/testFileDeviceContactMetadataJSON.txt
new file mode 100644
index 0000000..c9494d8
--- /dev/null
+++ b/tests/assets/test1/testFileDeviceContactMetadataJSON.txt
@@ -0,0 +1,61 @@
+{
+ "unique_contact_id": {
+ "account_type": "CUSTOM_ACCOUNT",
+ "custom_account_type": "facebook",
+ "account_name": "android-test",
+ "contact_id": "1111111"
+ },
+ "contact_prefs": {
+ "send_to_voicemail": true,
+ "starred": false,
+ "pinned": 2
+ },
+ "aggregation_data": [
+ {
+ "type": "TOGETHER",
+ "contact_ids": [
+ {
+ "contact_id": "2222222"
+ },
+ {
+ "contact_id": "3333333"
+ }
+ ]
+ }
+ ],
+ "field_data": [
+ {
+ "field_data_id": "1001",
+ "field_data_prefs": {
+ "is_primary": true,
+ "is_super_primary": true
+ },
+ "usage_stats": [
+ {
+ "usage_type": "CALL",
+ "last_time_used": 10000001,
+ "usage_count": 10
+ },
+ {
+ "usage_type": "SHORT_TEXT",
+ "last_time_used": 20000002,
+ "usage_count": 20
+ }
+ ]
+ },
+ {
+ "field_data_id": "1002",
+ "field_data_prefs": {
+ "is_primary": false,
+ "is_super_primary": false
+ },
+ "usage_stats": [
+ {
+ "usage_type": "LONG_TEXT",
+ "last_time_used": 30000003,
+ "usage_count": 30
+ }
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/src/com/android/providers/contacts/MetadataEntryParserTest.java b/tests/src/com/android/providers/contacts/MetadataEntryParserTest.java
new file mode 100644
index 0000000..94ca074
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/MetadataEntryParserTest.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2015 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.contacts;
+
+import android.content.Context;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import com.android.providers.contacts.MetadataEntryParser.AggregationData;
+import com.android.providers.contacts.MetadataEntryParser.FieldData;
+import com.android.providers.contacts.MetadataEntryParser.MetadataEntry;
+import com.android.providers.contacts.MetadataEntryParser.UsageStats;
+import org.json.JSONException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+/**
+ * Unit tests for {@link MetadataEntryParser}.
+ *
+ * Run the test like this:
+ * <code>
+ adb shell am instrument -e class com.android.providers.contacts.MetadataEntryParserTest -w \
+ com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
+ * </code>
+ */
+@SmallTest
+public class MetadataEntryParserTest extends AndroidTestCase {
+
+ public void testErrorForEmptyInput() {
+ try {
+ MetadataEntryParser.parseDataToMetaDataEntry("");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ public void testParseDataToMetadataEntry() throws IOException {
+ long rawContactId = 1111111;
+ String accountType = "facebook";
+ String accountName = "android-test";
+ int sendToVoicemail = 1;
+ int starred = 0;
+ int pinned = 2;
+ long fieldDataId1 = 1001;
+ String usageType1_1 = "CALL";
+ long lastTimeUsed1_1 = 10000001;
+ int timesUsed1_1 = 10;
+ String usageType1_2 = "SHORT_TEXT";
+ long lastTimeUsed1_2 = 20000002;
+ int timesUsed1_2 = 20;
+ long fieldDataId2 = 1002;
+ String usageType2 = "LONG_TEXT";
+ long lastTimeUsed2 = 30000003;
+ int timesUsed2 = 30;
+ long aggregationContact1 = 2222222;
+ long aggregationContact2 = 3333333;
+ String type = "TOGETHER";
+ String inputFile = "test1/testFileDeviceContactMetadataJSON.txt";
+
+ AggregationData aggregationData = new AggregationData(
+ aggregationContact1, aggregationContact2, type);
+ ArrayList<AggregationData> aggregationDataList = new ArrayList<>();
+ aggregationDataList.add(aggregationData);
+
+ UsageStats usageStats1_1 = new UsageStats(usageType1_1, lastTimeUsed1_1, timesUsed1_1);
+ UsageStats usageStats1_2 = new UsageStats(usageType1_2, lastTimeUsed1_2, timesUsed1_2);
+ UsageStats usageStats2 = new UsageStats(usageType2, lastTimeUsed2, timesUsed2);
+
+ ArrayList<UsageStats> usageStats1List = new ArrayList<>();
+ usageStats1List.add(usageStats1_1);
+ usageStats1List.add(usageStats1_2);
+ FieldData fieldData1 = new FieldData(fieldDataId1, true, true, usageStats1List);
+
+ ArrayList<UsageStats> usageStats2List = new ArrayList<>();
+ usageStats2List.add(usageStats2);
+ FieldData fieldData2 = new FieldData(fieldDataId2, false, false, usageStats2List);
+
+ ArrayList<FieldData> fieldDataList = new ArrayList<>();
+ fieldDataList.add(fieldData1);
+ fieldDataList.add(fieldData2);
+
+ MetadataEntry expectedResult = new MetadataEntry(rawContactId, accountType, accountName,
+ sendToVoicemail, starred, pinned, fieldDataList, aggregationDataList);
+
+ String inputJson = readAssetAsString(inputFile);
+ MetadataEntry metadataEntry = MetadataEntryParser.parseDataToMetaDataEntry(
+ inputJson.toString());
+ assertMetaDataEntry(expectedResult, metadataEntry);
+ }
+
+ public void testErrorForMissingContactId() {
+ String input = "{\"unique_contact_id\": {\n" +
+ " \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
+ " \"custom_account_type\": \"facebook\",\n" +
+ " \"account_name\": \"android-test\"\n" +
+ " }}";
+ try {
+ MetadataEntryParser.parseDataToMetaDataEntry(input);
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ public void testErrorForNullContactId() throws JSONException {
+ String input = "{\"unique_contact_id\": {\n" +
+ " \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
+ " \"custom_account_type\": \"facebook\",\n" +
+ " \"account_name\": \"android-test\",\n" +
+ " \"contact_id\": \"\"\n" +
+ " }}";
+ try {
+ MetadataEntryParser.parseDataToMetaDataEntry(input);
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ public void testErrorForNullAccountType() throws JSONException {
+ String input = "{\"unique_contact_id\": {\n" +
+ " \"account_type\": \"\",\n" +
+ " \"custom_account_type\": \"facebook\",\n" +
+ " \"account_name\": \"android-test\",\n" +
+ " \"contact_id\": \"\"\n" +
+ " }}";
+ try {
+ MetadataEntryParser.parseDataToMetaDataEntry(input);
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ public void testErrorForNullAccountName() throws JSONException {
+ String input = "{\"unique_contact_id\": {\n" +
+ " \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
+ " \"custom_account_type\": \"facebook\",\n" +
+ " \"account_name\": \"\",\n" +
+ " \"contact_id\": \"1111111\"\n" +
+ " }}";
+ try {
+ MetadataEntryParser.parseDataToMetaDataEntry(input);
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ public void testErrorForNullFieldDataId() throws JSONException {
+ String input = "{\"unique_contact_id\": {\n" +
+ " \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
+ " \"custom_account_type\": \"facebook\",\n" +
+ " \"account_name\": \"android-test\",\n" +
+ " \"contact_id\": \"1111111\"\n" +
+ " },\n" +
+ " \"contact_prefs\": {\n" +
+ " \"send_to_voicemail\": true,\n" +
+ " \"starred\": false,\n" +
+ " \"pinned\": 2\n" +
+ " }," +
+ " \"field_data\": [{\n" +
+ " \"field_data_id\": \"\"}]" +
+ "}";
+ try {
+ MetadataEntryParser.parseDataToMetaDataEntry(input);
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ public void testErrorForNullAggregationType() throws JSONException {
+ String input = "{\n" +
+ " \"unique_contact_id\": {\n" +
+ " \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
+ " \"custom_account_type\": \"facebook\",\n" +
+ " \"account_name\": \"android-test\",\n" +
+ " \"contact_id\": \"1111111\"\n" +
+ " },\n" +
+ " \"contact_prefs\": {\n" +
+ " \"send_to_voicemail\": true,\n" +
+ " \"starred\": false,\n" +
+ " \"pinned\": 2\n" +
+ " },\n" +
+ " \"aggregation_data\": [\n" +
+ " {\n" +
+ " \"type\": \"\",\n" +
+ " \"contact_ids\": [\n" +
+ " {\n" +
+ " \"contact_id\": \"2222222\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"contact_id\": \"3333333\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ]}";
+ try {
+ MetadataEntryParser.parseDataToMetaDataEntry(input);
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ private String readAssetAsString(String fileName) throws IOException {
+ Context context = getTestContext();
+ InputStream input = context.getAssets().open(fileName);
+ ByteArrayOutputStream contents = new ByteArrayOutputStream();
+ int len;
+ byte[] data = new byte[1024];
+ do {
+ len = input.read(data);
+ if (len > 0) contents.write(data, 0, len);
+ } while (len == data.length);
+ return contents.toString();
+ }
+
+ private void assertMetaDataEntry(MetadataEntry entry1, MetadataEntry entry2) {
+ assertEquals(entry1.mRawContactId, entry2.mRawContactId);
+ assertEquals(entry1.mAccountType, entry2.mAccountType);
+ assertEquals(entry1.mAccountName, entry2.mAccountName);
+ assertEquals(entry1.mSendToVoicemail, entry2.mSendToVoicemail);
+ assertEquals(entry1.mStarred, entry2.mStarred);
+ assertEquals(entry1.mPinned, entry2.mPinned);
+ assertAggregationDataListEquals(entry1.mAggregationDatas, entry2.mAggregationDatas);
+ assertFieldDataListEquals(entry1.mFieldDatas, entry2.mFieldDatas);
+ }
+
+ private void assertAggregationDataListEquals(ArrayList<AggregationData> aggregationList1,
+ ArrayList<AggregationData> aggregationList2) {
+ assertEquals(aggregationList1.size(), aggregationList2.size());
+ for (int i = 0; i < aggregationList1.size(); i++) {
+ assertAggregationDataEquals(aggregationList1.get(i), aggregationList2.get(i));
+ }
+ }
+
+ private void assertAggregationDataEquals(AggregationData aggregationData1,
+ AggregationData aggregationData2) {
+ assertEquals(aggregationData1.mRawContactId1, aggregationData2.mRawContactId1);
+ assertEquals(aggregationData1.mRawContactId2, aggregationData2.mRawContactId2);
+ assertEquals(aggregationData1.mType, aggregationData2.mType);
+ }
+
+ private void assertFieldDataListEquals(ArrayList<FieldData> fieldDataList1,
+ ArrayList<FieldData> fieldDataList2) {
+ assertEquals(fieldDataList1.size(), fieldDataList2.size());
+ for (int i = 0; i < fieldDataList1.size(); i++) {
+ assertFieldDataEquals(fieldDataList1.get(i), fieldDataList2.get(i));
+ }
+ }
+
+ private void assertFieldDataEquals(FieldData fieldData1, FieldData fieldData2) {
+ assertEquals(fieldData1.mFieldDataId, fieldData2.mFieldDataId);
+ assertEquals(fieldData1.mIsPrimary, fieldData2.mIsPrimary);
+ assertEquals(fieldData1.mIsSuperPrimary, fieldData2.mIsSuperPrimary);
+ assertUsageStatsListEquals(fieldData1.mUsageStatsList, fieldData2.mUsageStatsList);
+ }
+
+ private void assertUsageStatsListEquals(ArrayList<UsageStats> usageStatsList1,
+ ArrayList<UsageStats> usageStatsList2) {
+ assertEquals(usageStatsList1.size(), usageStatsList2.size());
+ for (int i = 0; i < usageStatsList1.size(); i++) {
+ assertUsageStatsEquals(usageStatsList1.get(i), usageStatsList2.get(i));
+ }
+ }
+
+ private void assertUsageStatsEquals(UsageStats usageStats1, UsageStats usageStats2) {
+ assertEquals(usageStats1.mUsageType, usageStats2.mUsageType);
+ assertEquals(usageStats1.mLastTimeUsed, usageStats2.mLastTimeUsed);
+ assertEquals(usageStats1.mTimesUsed, usageStats2.mTimesUsed);
+ }
+}