Merge "Keep contextual card dismissal info upon deletion"
This commit is contained in:
committed by
Android (Google) Code Review
commit
a43c90c64a
@@ -201,6 +201,9 @@
|
|||||||
<!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
|
<!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
|
||||||
<bool name="config_force_rounded_icon_TopLevelSettings">true</bool>
|
<bool name="config_force_rounded_icon_TopLevelSettings">true</bool>
|
||||||
|
|
||||||
|
<!-- Whether dismissal timestamp should be kept before deletion -->
|
||||||
|
<bool name="config_keep_contextual_card_dismissal_timestamp">false</bool>
|
||||||
|
|
||||||
<!-- Settings intelligence package name -->
|
<!-- Settings intelligence package name -->
|
||||||
<string name="config_settingsintelligence_package_name" translatable="false">
|
<string name="config_settingsintelligence_package_name" translatable="false">
|
||||||
com.android.settings.intelligence
|
com.android.settings.intelligence
|
||||||
|
@@ -26,12 +26,16 @@ import android.database.sqlite.SQLiteQueryBuilder;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.StrictMode;
|
import android.os.StrictMode;
|
||||||
|
import android.util.ArrayMap;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
import com.android.settingslib.utils.ThreadUtils;
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provider stores and manages user interaction feedback for homepage contextual cards.
|
* Provider stores and manages user interaction feedback for homepage contextual cards.
|
||||||
*/
|
*/
|
||||||
@@ -81,6 +85,9 @@ public class CardContentProvider extends ContentProvider {
|
|||||||
final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
|
final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
|
||||||
int numInserted = 0;
|
int numInserted = 0;
|
||||||
final SQLiteDatabase database = mDBHelper.getWritableDatabase();
|
final SQLiteDatabase database = mDBHelper.getWritableDatabase();
|
||||||
|
final boolean keepDismissalTimestampBeforeDeletion = getContext().getResources()
|
||||||
|
.getBoolean(R.bool.config_keep_contextual_card_dismissal_timestamp);
|
||||||
|
final Map<String, Long> dismissedTimeMap = new ArrayMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
maybeEnableStrictMode();
|
maybeEnableStrictMode();
|
||||||
@@ -88,9 +95,42 @@ public class CardContentProvider extends ContentProvider {
|
|||||||
final String table = getTableFromMatch(uri);
|
final String table = getTableFromMatch(uri);
|
||||||
database.beginTransaction();
|
database.beginTransaction();
|
||||||
|
|
||||||
// Here deletion first is avoiding redundant insertion. According to cl/215350754
|
if (keepDismissalTimestampBeforeDeletion) {
|
||||||
|
// Query the existing db and get dismissal info.
|
||||||
|
final String[] columns = new String[]{CardDatabaseHelper.CardColumns.NAME,
|
||||||
|
CardDatabaseHelper.CardColumns.DISMISSED_TIMESTAMP};
|
||||||
|
final String selection =
|
||||||
|
CardDatabaseHelper.CardColumns.DISMISSED_TIMESTAMP + " IS NOT NULL";
|
||||||
|
try (Cursor cursor = database.query(table, columns, selection,
|
||||||
|
null/* selectionArgs */, null /* groupBy */,
|
||||||
|
null /* having */, null /* orderBy */)) {
|
||||||
|
// Save them to a Map
|
||||||
|
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
||||||
|
final String cardName = cursor.getString(cursor.getColumnIndex(
|
||||||
|
CardDatabaseHelper.CardColumns.NAME));
|
||||||
|
final long timestamp = cursor.getLong(cursor.getColumnIndex(
|
||||||
|
CardDatabaseHelper.CardColumns.DISMISSED_TIMESTAMP));
|
||||||
|
dismissedTimeMap.put(cardName, timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here delete data first to avoid redundant insertion. According to cl/215350754
|
||||||
database.delete(table, null /* whereClause */, null /* whereArgs */);
|
database.delete(table, null /* whereClause */, null /* whereArgs */);
|
||||||
|
|
||||||
for (ContentValues value : values) {
|
for (ContentValues value : values) {
|
||||||
|
if (keepDismissalTimestampBeforeDeletion) {
|
||||||
|
// Replace dismissedTimestamp in each value if there is an old one.
|
||||||
|
final String cardName =
|
||||||
|
value.get(CardDatabaseHelper.CardColumns.NAME).toString();
|
||||||
|
if (dismissedTimeMap.containsKey(cardName)) {
|
||||||
|
// Replace the value of dismissedTimestamp
|
||||||
|
value.put(CardDatabaseHelper.CardColumns.DISMISSED_TIMESTAMP,
|
||||||
|
dismissedTimeMap.get(cardName));
|
||||||
|
Log.d(TAG, "Replace dismissed time: " + cardName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long ret = database.insert(table, null /* nullColumnHack */, value);
|
long ret = database.insert(table, null /* nullColumnHack */, value);
|
||||||
if (ret != -1L) {
|
if (ret != -1L) {
|
||||||
numInserted++;
|
numInserted++;
|
||||||
|
@@ -72,6 +72,8 @@
|
|||||||
<!-- Whether or not extra preview panels should be used for screen zoom setting. -->
|
<!-- Whether or not extra preview panels should be used for screen zoom setting. -->
|
||||||
<bool name="config_enable_extra_screen_zoom_preview">false</bool>
|
<bool name="config_enable_extra_screen_zoom_preview">false</bool>
|
||||||
|
|
||||||
|
<!-- Whether dismissal timestamp should be kept before deletion -->
|
||||||
|
<bool name="config_keep_contextual_card_dismissal_timestamp">true</bool>
|
||||||
|
|
||||||
<!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
|
<!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
|
||||||
<string-array name="config_settings_slices_accessibility_components" translatable="false">
|
<string-array name="config_settings_slices_accessibility_components" translatable="false">
|
||||||
|
@@ -38,6 +38,7 @@ import org.junit.runner.RunWith;
|
|||||||
import org.robolectric.Robolectric;
|
import org.robolectric.Robolectric;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.util.ReflectionHelpers;
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@@ -85,6 +86,25 @@ public class CardContentProviderTest {
|
|||||||
assertThat(rowsAfterInsert - rowsBeforeInsert).isEqualTo(2);
|
assertThat(rowsAfterInsert - rowsBeforeInsert).isEqualTo(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void bulkInsert_keepDismissalTimestamp_shouldHaveTimestamp() {
|
||||||
|
mResolver.bulkInsert(mUri, generateTwoRowsWithDismissTimestamp());
|
||||||
|
|
||||||
|
mResolver.bulkInsert(mUri, generateTwoRows());
|
||||||
|
|
||||||
|
assertThat(queryDismissedTimestamp()).isEqualTo(10001L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bulkInsert_notKeepDismissalTimestamp_shouldNotHaveTimestamp() {
|
||||||
|
mResolver.bulkInsert(mUri, generateTwoRowsWithDismissTimestamp());
|
||||||
|
|
||||||
|
mResolver.bulkInsert(mUri, generateTwoRows());
|
||||||
|
|
||||||
|
assertThat(queryDismissedTimestamp()).isEqualTo(0L);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void cardData_query() {
|
public void cardData_query() {
|
||||||
mResolver.insert(mUri, generateOneRow());
|
mResolver.insert(mUri, generateOneRow());
|
||||||
@@ -198,10 +218,40 @@ public class CardContentProviderTest {
|
|||||||
return twoRows;
|
return twoRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ContentValues[] generateTwoRowsWithDismissTimestamp() {
|
||||||
|
final ContentValues[] twoRows = new ContentValues[2];
|
||||||
|
twoRows[0] = generateOneRow();
|
||||||
|
|
||||||
|
final ContentValues values = new ContentValues();
|
||||||
|
values.put(CardDatabaseHelper.CardColumns.NAME, "toggle_airplane");
|
||||||
|
values.put(CardDatabaseHelper.CardColumns.TYPE, 1);
|
||||||
|
values.put(CardDatabaseHelper.CardColumns.SCORE, 0.95);
|
||||||
|
values.put(CardDatabaseHelper.CardColumns.SLICE_URI,
|
||||||
|
"content://com.android.settings.slices/action/toggle_airplane");
|
||||||
|
values.put(CardDatabaseHelper.CardColumns.CATEGORY, 2);
|
||||||
|
values.put(CardDatabaseHelper.CardColumns.PACKAGE_NAME, "com.android.settings");
|
||||||
|
values.put(CardDatabaseHelper.CardColumns.APP_VERSION, 10001);
|
||||||
|
values.put(CardDatabaseHelper.CardColumns.DISMISSED_TIMESTAMP, 10001L);
|
||||||
|
twoRows[1] = values;
|
||||||
|
|
||||||
|
return twoRows;
|
||||||
|
}
|
||||||
|
|
||||||
private int getRowCount() {
|
private int getRowCount() {
|
||||||
final Cursor cr = mResolver.query(mUri, null, null, null);
|
final Cursor cr = mResolver.query(mUri, null, null, null);
|
||||||
final int count = cr.getCount();
|
final int count = cr.getCount();
|
||||||
cr.close();
|
cr.close();
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long queryDismissedTimestamp() {
|
||||||
|
final String[] columns = {CardDatabaseHelper.CardColumns.DISMISSED_TIMESTAMP};
|
||||||
|
final String selection = CardDatabaseHelper.CardColumns.NAME + "=?";
|
||||||
|
final String[] selectionArgs = {"toggle_airplane"};
|
||||||
|
final Cursor cr = mResolver.query(mUri, columns, selection, selectionArgs, null);
|
||||||
|
cr.moveToFirst();
|
||||||
|
final long dismissedTimestamp = cr.getLong(0);
|
||||||
|
cr.close();
|
||||||
|
return dismissedTimestamp;
|
||||||
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user