Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa08a2cc authored by Fan Zhang's avatar Fan Zhang
Browse files

Use slice uri from slice index db directly.

During SettingsSliceProvider#onGetSliceDescendants, use the uris from
database directly instead of getting the key and construct the uris
manually.

Bug: 126222433
Test: robotest
Change-Id: Iad4e9fc28ec4442b6bb323878503d743582b35ac
parent 9e05bf90
Loading
Loading
Loading
Loading
+70 −101
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import static android.Manifest.permission.READ_SEARCH_INDEXABLES;

import android.app.PendingIntent;
import android.app.slice.SliceManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -57,6 +56,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.stream.Collectors;

/**
 * A {@link SliceProvider} for Settings to enabled inline results in system apps.
@@ -118,6 +118,22 @@ public class SettingsSliceProvider extends SliceProvider {
    public static final String EXTRA_SLICE_PLATFORM_DEFINED =
            "com.android.settings.slice.extra.platform";


    /**
     * A list of custom slice uris that are supported publicly. This is a subset of slices defined
     * in {@link CustomSliceRegistry}. Things here are exposed publicly so all clients with proper
     * permission can use them.
     */
    private static final List<Uri> PUBLICLY_SUPPORTED_CUSTOM_SLICE_URIS =
            Arrays.asList(
                    CustomSliceRegistry.BLUETOOTH_URI,
                    CustomSliceRegistry.FLASHLIGHT_SLICE_URI,
                    CustomSliceRegistry.LOCATION_SLICE_URI,
                    CustomSliceRegistry.MOBILE_DATA_SLICE_URI,
                    CustomSliceRegistry.WIFI_SLICE_URI,
                    CustomSliceRegistry.ZEN_MODE_SLICE_URI
            );

    private static final KeyValueListParser KEY_VALUE_LIST_PARSER = new KeyValueListParser(',');

    @VisibleForTesting
@@ -264,37 +280,30 @@ public class SettingsSliceProvider extends SliceProvider {
        }

        final String authority = uri.getAuthority();
        final String pathPrefix = uri.getPath();
        final boolean isPathEmpty = pathPrefix.isEmpty();

        // No path nor authority. Return all possible Uris.
        if (isPathEmpty && TextUtils.isEmpty(authority)) {
            final List<String> platformKeys = mSlicesDatabaseAccessor.getSliceKeys(
                    true /* isPlatformSlice */);
            final List<String> oemKeys = mSlicesDatabaseAccessor.getSliceKeys(
                    false /* isPlatformSlice */);
            descendants.addAll(buildUrisFromKeys(platformKeys, SettingsSlicesContract.AUTHORITY));
            descendants.addAll(buildUrisFromKeys(oemKeys, SettingsSliceProvider.SLICE_AUTHORITY));
            descendants.addAll(getSpecialCaseUris(true /* isPlatformSlice */));
            descendants.addAll(getSpecialCaseUris(false /* isPlatformSlice */));

            return descendants;
        }
        final String path = uri.getPath();
        final boolean isPathEmpty = path.isEmpty();

        // Path is anything but empty, "action", or "intent". Return empty list.
        if (!isPathEmpty
                && !TextUtils.equals(pathPrefix, "/" + SettingsSlicesContract.PATH_SETTING_ACTION)
                && !TextUtils.equals(pathPrefix,
                "/" + SettingsSlicesContract.PATH_SETTING_INTENT)) {
                && !TextUtils.equals(path, "/" + SettingsSlicesContract.PATH_SETTING_ACTION)
                && !TextUtils.equals(path, "/" + SettingsSlicesContract.PATH_SETTING_INTENT)) {
            // Invalid path prefix, there are no valid Uri descendants.
            return descendants;
        }

        // Add all descendants from db with matching authority.
        descendants.addAll(mSlicesDatabaseAccessor.getSliceUris(authority));

        if (isPathEmpty && TextUtils.isEmpty(authority)) {
            // No path nor authority. Return all possible Uris by adding all special slice uri
            descendants.addAll(PUBLICLY_SUPPORTED_CUSTOM_SLICE_URIS);
        } else {
            // Can assume authority belongs to the provider. Return all Uris for the authority.
        final boolean isPlatformUri = TextUtils.equals(authority, SettingsSlicesContract.AUTHORITY);
        final List<String> keys = mSlicesDatabaseAccessor.getSliceKeys(isPlatformUri);
        descendants.addAll(buildUrisFromKeys(keys, authority));
        descendants.addAll(getSpecialCaseUris(isPlatformUri));
            final List<Uri> customSlices = PUBLICLY_SUPPORTED_CUSTOM_SLICE_URIS.stream()
                    .filter(sliceUri -> TextUtils.equals(authority, sliceUri.getAuthority()))
                    .collect(Collectors.toList());
            descendants.addAll(customSlices);
        }
        grantWhitelistedPackagePermissions(getContext(), descendants);
        return descendants;
    }
@@ -332,32 +341,6 @@ public class SettingsSliceProvider extends SliceProvider {
        }
    }

    private void startBackgroundWorker(Sliceable sliceable, Uri uri) {
        final Class workerClass = sliceable.getBackgroundWorkerClass();
        if (workerClass == null) {
            return;
        }

        if (mPinnedWorkers.containsKey(uri)) {
            return;
        }

        Log.d(TAG, "Starting background worker for: " + uri);
        final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(
                getContext(), sliceable, uri);
        mPinnedWorkers.put(uri, worker);
        worker.onSlicePinned();
    }

    private void stopBackgroundWorker(Uri uri) {
        final SliceBackgroundWorker worker = mPinnedWorkers.get(uri);
        if (worker != null) {
            Log.d(TAG, "Stopping background worker for: " + uri);
            worker.onSliceUnpinned();
            mPinnedWorkers.remove(uri);
        }
    }

    @Override
    public void shutdown() {
        ThreadUtils.postOnMainThread(() -> {
@@ -365,23 +348,6 @@ public class SettingsSliceProvider extends SliceProvider {
        });
    }

    private List<Uri> buildUrisFromKeys(List<String> keys, String authority) {
        final List<Uri> descendants = new ArrayList<>();

        final Uri.Builder builder = new Uri.Builder()
                .scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority)
                .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION);

        final String newUriPathPrefix = SettingsSlicesContract.PATH_SETTING_ACTION + "/";
        for (String key : keys) {
            builder.path(newUriPathPrefix + key);
            descendants.add(builder.build());
        }

        return descendants;
    }

    @VisibleForTesting
    void loadSlice(Uri uri) {
        long startBuildTime = System.currentTimeMillis();
@@ -416,38 +382,6 @@ public class SettingsSliceProvider extends SliceProvider {
        ThreadUtils.postOnBackgroundThread(() -> loadSlice(uri));
    }

    /**
     * @return an empty {@link Slice} with {@param uri} to be used as a stub while the real
     * {@link SliceData} is loaded from {@link SlicesDatabaseHelper.Tables#TABLE_SLICES_INDEX}.
     */
    private Slice getSliceStub(Uri uri) {
        // TODO: Switch back to ListBuilder when slice loading states are fixed.
        return new Slice.Builder(uri).build();
    }

    private List<Uri> getSpecialCaseUris(boolean isPlatformUri) {
        if (isPlatformUri) {
            return getSpecialCasePlatformUris();
        }
        return getSpecialCaseOemUris();
    }

    private List<Uri> getSpecialCasePlatformUris() {
        return Arrays.asList(
                CustomSliceRegistry.WIFI_SLICE_URI,
                CustomSliceRegistry.BLUETOOTH_URI,
                CustomSliceRegistry.LOCATION_SLICE_URI
        );
    }

    private List<Uri> getSpecialCaseOemUris() {
        return Arrays.asList(
                CustomSliceRegistry.FLASHLIGHT_SLICE_URI,
                CustomSliceRegistry.MOBILE_DATA_SLICE_URI,
                CustomSliceRegistry.ZEN_MODE_SLICE_URI
        );
    }

    @VisibleForTesting
    /**
     * Registers an IntentFilter in SysUI to notify changes to {@param sliceUri} when broadcasts to
@@ -476,7 +410,42 @@ public class SettingsSliceProvider extends SliceProvider {
        return set;
    }

    private String[] parseStringArray(String value) {
    private void startBackgroundWorker(Sliceable sliceable, Uri uri) {
        final Class workerClass = sliceable.getBackgroundWorkerClass();
        if (workerClass == null) {
            return;
        }

        if (mPinnedWorkers.containsKey(uri)) {
            return;
        }

        Log.d(TAG, "Starting background worker for: " + uri);
        final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(
                getContext(), sliceable, uri);
        mPinnedWorkers.put(uri, worker);
        worker.onSlicePinned();
    }

    private void stopBackgroundWorker(Uri uri) {
        final SliceBackgroundWorker worker = mPinnedWorkers.get(uri);
        if (worker != null) {
            Log.d(TAG, "Stopping background worker for: " + uri);
            worker.onSliceUnpinned();
            mPinnedWorkers.remove(uri);
        }
    }

    /**
     * @return an empty {@link Slice} with {@param uri} to be used as a stub while the real
     * {@link SliceData} is loaded from {@link SlicesDatabaseHelper.Tables#TABLE_SLICES_INDEX}.
     */
    private static Slice getSliceStub(Uri uri) {
        // TODO: Switch back to ListBuilder when slice loading states are fixed.
        return new Slice.Builder(uri).build();
    }

    private static String[] parseStringArray(String value) {
        if (value != null) {
            String[] parts = value.split(":");
            if (parts.length > 0) {
+15 −19
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Binder;
import android.text.TextUtils;
import android.util.Pair;

import androidx.slice.Slice;
@@ -91,34 +92,29 @@ public class SlicesDatabaseAccessor {
    }

    /**
     * @return a list of keys in the Slices database matching on {@param isPlatformSlice}.
     * @return a list of Slice {@link Uri}s matching {@param authority}.
     */
    public List<String> getSliceKeys(boolean isPlatformSlice) {
    public List<Uri> getSliceUris(String authority) {
        verifyIndexing();
        final String whereClause;

        if (isPlatformSlice) {
            whereClause = IndexColumns.PLATFORM_SLICE + " = 1";
        } else {
            whereClause = IndexColumns.PLATFORM_SLICE + " = 0";
        }

        final List<Uri> uris = new ArrayList<>();
        final SQLiteDatabase database = mHelper.getReadableDatabase();
        final String[] columns = new String[]{IndexColumns.KEY};
        final List<String> keys = new ArrayList<>();

        try (final Cursor resultCursor = database.query(TABLE_SLICES_INDEX, columns, whereClause,
                null /* selection */, null /* groupBy */, null /* having */, null /* orderBy */)) {
        final String[] columns = new String[]{IndexColumns.SLICE_URI};
        try (final Cursor resultCursor = database.query(TABLE_SLICES_INDEX, columns,
                null /* where */, null /* selection */, null /* groupBy */, null /* having */,
                null /* orderBy */)) {
            if (!resultCursor.moveToFirst()) {
                return keys;
                return uris;
            }

            do {
                keys.add(resultCursor.getString(0 /* key index */));
                final Uri uri = Uri.parse(resultCursor.getString(0 /* SLICE_URI */));
                if (TextUtils.isEmpty(authority)
                        || TextUtils.equals(authority, uri.getAuthority())) {
                    uris.add(uri);
                }
            } while (resultCursor.moveToNext());
        }

        return keys;
        return uris;
    }

    private Cursor getIndexedSliceData(String path) {
+47 −78
Original line number Diff line number Diff line
@@ -108,13 +108,8 @@ public class SettingsSliceProviderTest {
                    .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
                    .appendPath(KEY)
                    .build();
    private static final String TITLE = "title";
    private static final String SUMMARY = "summary";
    private static final String SCREEN_TITLE = "screen title";
    private static final String FRAGMENT_NAME = "fragment name";
    private static final int ICON = R.drawable.ic_settings_accent;

    private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
    private static final String PREF_CONTROLLER = FakeToggleController.class.getName();

    private Context mContext;
    private SettingsSliceProvider mProvider;
@@ -164,7 +159,7 @@ public class SettingsSliceProviderTest {

    @Test
    public void testInitialSliceReturned_emptySlice() {
        insertSpecialCase(KEY);
        SliceTestUtils.insertSliceToDb(mContext, KEY);
        Slice slice = mProvider.onBindSlice(INTENT_SLICE_URI);

        assertThat(slice.getUri()).isEqualTo(INTENT_SLICE_URI);
@@ -173,18 +168,18 @@ public class SettingsSliceProviderTest {

    @Test
    public void testLoadSlice_returnsSliceFromAccessor() {
        insertSpecialCase(KEY);
        SliceTestUtils.insertSliceToDb(mContext, KEY);

        mProvider.loadSlice(INTENT_SLICE_URI);
        SliceData data = mProvider.mSliceWeakDataCache.get(INTENT_SLICE_URI);

        assertThat(data.getKey()).isEqualTo(KEY);
        assertThat(data.getTitle()).isEqualTo(TITLE);
        assertThat(data.getTitle()).isEqualTo(SliceTestUtils.FAKE_TITLE);
    }

    @Test
    public void loadSlice_registersIntentFilter() {
        insertSpecialCase(KEY);
        SliceTestUtils.insertSliceToDb(mContext, KEY);

        mProvider.loadSlice(INTENT_SLICE_URI);

@@ -194,7 +189,7 @@ public class SettingsSliceProviderTest {

    @Test
    public void loadSlice_registersBackgroundListener() {
        insertSpecialCase(KEY);
        SliceTestUtils.insertSliceToDb(mContext, KEY);

        mProvider.loadSlice(INTENT_SLICE_URI);

@@ -210,7 +205,7 @@ public class SettingsSliceProviderTest {
        SliceData data = getDummyData();
        mProvider.mSliceWeakDataCache.put(data.getUri(), data);
        mProvider.onBindSlice(data.getUri());
        insertSpecialCase(data.getKey());
        SliceTestUtils.insertSliceToDb(mContext, data.getKey());

        SliceData cachedData = mProvider.mSliceWeakDataCache.get(data.getUri());

@@ -291,7 +286,7 @@ public class SettingsSliceProviderTest {
    @Test
    public void getDescendantUris_invalidPath_returnsEmpty() {
        final String key = "platform_key";
        insertSpecialCase(key, true /* isPlatformSlice */);
        SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */);
        final Uri uri = new Uri.Builder()
                .scheme(SCHEME_CONTENT)
                .authority(SettingsSlicesContract.AUTHORITY)
@@ -306,7 +301,7 @@ public class SettingsSliceProviderTest {

    @Test
    public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() {
        insertSpecialCase("oem_key", false /* isPlatformSlice */);
        SliceTestUtils.insertSliceToDb(mContext, "oem_key", false /* isPlatformSlice */);
        final Uri uri = new Uri.Builder()
                .scheme(SCHEME_CONTENT)
                .authority(SettingsSlicesContract.AUTHORITY)
@@ -320,7 +315,7 @@ public class SettingsSliceProviderTest {

    @Test
    public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() {
        insertSpecialCase("platform_key", true /* isPlatformSlice */);
        SliceTestUtils.insertSliceToDb(mContext, "platform_key", true /* isPlatformSlice */);
        final Uri uri = new Uri.Builder()
                .scheme(SCHEME_CONTENT)
                .authority(SettingsSliceProvider.SLICE_AUTHORITY)
@@ -335,7 +330,7 @@ public class SettingsSliceProviderTest {
    @Test
    public void getDescendantUris_oemSlice_returnsOEMUriDescendant() {
        final String key = "oem_key";
        insertSpecialCase(key, false /* isPlatformSlice */);
        SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */);
        final Uri uri = new Uri.Builder()
                .scheme(SCHEME_CONTENT)
                .authority(SettingsSliceProvider.SLICE_AUTHORITY)
@@ -358,7 +353,7 @@ public class SettingsSliceProviderTest {
    @Test
    public void getDescendantUris_oemSliceNoPath_returnsOEMUriDescendant() {
        final String key = "oem_key";
        insertSpecialCase(key, false /* isPlatformSlice */);
        SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */);
        final Uri uri = new Uri.Builder()
                .scheme(SCHEME_CONTENT)
                .authority(SettingsSliceProvider.SLICE_AUTHORITY)
@@ -380,7 +375,7 @@ public class SettingsSliceProviderTest {
    @Test
    public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() {
        final String key = "platform_key";
        insertSpecialCase(key, true /* isPlatformSlice */);
        SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */);
        final Uri uri = new Uri.Builder()
                .scheme(SCHEME_CONTENT)
                .authority(SettingsSlicesContract.AUTHORITY)
@@ -403,7 +398,7 @@ public class SettingsSliceProviderTest {
    @Test
    public void getDescendantUris_platformSliceNoPath_returnsPlatformUriDescendant() {
        final String key = "platform_key";
        insertSpecialCase(key, true /* isPlatformSlice */);
        SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */);
        final Uri uri = new Uri.Builder()
                .scheme(SCHEME_CONTENT)
                .authority(SettingsSlicesContract.AUTHORITY)
@@ -426,8 +421,8 @@ public class SettingsSliceProviderTest {
    public void getDescendantUris_noAuthorityNorPath_returnsAllUris() {
        final String platformKey = "platform_key";
        final String oemKey = "oemKey";
        insertSpecialCase(platformKey, true /* isPlatformSlice */);
        insertSpecialCase(oemKey, false /* isPlatformSlice */);
        SliceTestUtils.insertSliceToDb(mContext, platformKey, true /* isPlatformSlice */);
        SliceTestUtils.insertSliceToDb(mContext, oemKey, false /* isPlatformSlice */);
        final Uri uri = new Uri.Builder()
                .scheme(SCHEME_CONTENT)
                .build();
@@ -492,31 +487,6 @@ public class SettingsSliceProviderTest {
        mProvider.onSlicePinned(uri);
    }

    @Implements(WifiScanWorker.class)
    public static class ShadowWifiScanWorker {
        private static WifiTracker mWifiTracker;

        @Implementation
        protected void onSlicePinned() {
            mWifiTracker = mock(WifiTracker.class);
            mWifiTracker.onStart();
        }

        @Implementation
        protected void onSliceUnpinned() {
            mWifiTracker.onStop();
        }

        @Implementation
        protected void close() {
            mWifiTracker.onDestroy();
        }

        static WifiTracker getWifiTracker() {
            return mWifiTracker;
        }
    }

    @Test
    public void onSlicePinned_backgroundWorker_started() {
        mProvider.onSlicePinned(CustomSliceRegistry.WIFI_SLICE_URI);
@@ -563,45 +533,44 @@ public class SettingsSliceProviderTest {
                .grantSlicePermission("com.android.settings.slice_whitelist_package", uris.get(0));
    }

    private void insertSpecialCase(String key) {
        insertSpecialCase(key, true);
    }

    private void insertSpecialCase(String key, boolean isPlatformSlice) {
        final ContentValues values = new ContentValues();
        values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
        values.put(SlicesDatabaseHelper.IndexColumns.TITLE, TITLE);
        values.put(SlicesDatabaseHelper.IndexColumns.SUMMARY, "s");
        values.put(SlicesDatabaseHelper.IndexColumns.SCREENTITLE, "s");
        values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, R.drawable.ic_settings_accent);
        values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, "test");
        values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, PREF_CONTROLLER);
        values.put(SlicesDatabaseHelper.IndexColumns.PLATFORM_SLICE, isPlatformSlice);
        values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
        final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase();
        db.beginTransaction();
        try {
            db.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values);
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
        db.close();
    }

    private static SliceData getDummyData() {
        return new SliceData.Builder()
                .setKey(KEY)
                .setTitle(TITLE)
                .setSummary(SUMMARY)
                .setScreenTitle(SCREEN_TITLE)
                .setIcon(ICON)
                .setFragmentName(FRAGMENT_NAME)
                .setUri(URI)
                .setPreferenceControllerClassName(PREF_CONTROLLER)
                .setTitle(SliceTestUtils.FAKE_TITLE)
                .setSummary(SliceTestUtils.FAKE_SUMMARY)
                .setScreenTitle(SliceTestUtils.FAKE_SCREEN_TITLE)
                .setIcon(SliceTestUtils.FAKE_ICON)
                .setFragmentName(SliceTestUtils.FAKE_FRAGMENT_NAME)
                .setPreferenceControllerClassName(SliceTestUtils.FAKE_CONTROLLER_NAME)
                .build();
    }

    @Implements(WifiScanWorker.class)
    public static class ShadowWifiScanWorker {
        private static WifiTracker mWifiTracker;

        @Implementation
        protected void onSlicePinned() {
            mWifiTracker = mock(WifiTracker.class);
            mWifiTracker.onStart();
        }

        @Implementation
        protected void onSliceUnpinned() {
            mWifiTracker.onStop();
        }

        @Implementation
        protected void close() {
            mWifiTracker.onDestroy();
        }

        static WifiTracker getWifiTracker() {
            return mWifiTracker;
        }
    }

    @Implements(value = StrictMode.class)
    public static class ShadowStrictMode {

+77 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.settings.slices;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.SettingsSlicesContract;

import com.android.settings.testutils.FakeIndexProvider;
import com.android.settings.testutils.FakeToggleController;

class SliceTestUtils {

    public static final String FAKE_TITLE = "title";
    public static final String FAKE_SUMMARY = "summary";
    public static final String FAKE_SCREEN_TITLE = "screen_title";
    public static final String FAKE_KEYWORDS = "a, b, c";
    public static final int FAKE_ICON = 1234;
    public static final String FAKE_FRAGMENT_NAME = FakeIndexProvider.class.getName();
    public static final String FAKE_CONTROLLER_NAME = FakeToggleController.class.getName();


    public static void insertSliceToDb(Context context, String key) {
        insertSliceToDb(context, key, true /* isPlatformSlice */);
    }

    public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice) {
        insertSliceToDb(context, key, isPlatformSlice, null /*customizedUnavailableSliceSubtitle*/);
    }

    public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice,
            String customizedUnavailableSliceSubtitle) {
        final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(context).getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
        values.put(SlicesDatabaseHelper.IndexColumns.SLICE_URI,
                new Uri.Builder()
                        .scheme(ContentResolver.SCHEME_CONTENT)
                        .authority(isPlatformSlice
                                ? SettingsSlicesContract.AUTHORITY
                                : SettingsSliceProvider.SLICE_AUTHORITY)
                        .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
                        .appendPath(key)
                        .build().toSafeString());
        values.put(SlicesDatabaseHelper.IndexColumns.TITLE, FAKE_TITLE);
        values.put(SlicesDatabaseHelper.IndexColumns.SUMMARY, FAKE_SUMMARY);
        values.put(SlicesDatabaseHelper.IndexColumns.SCREENTITLE, FAKE_SCREEN_TITLE);
        values.put(SlicesDatabaseHelper.IndexColumns.KEYWORDS, FAKE_KEYWORDS);
        values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, FAKE_ICON);
        values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, FAKE_FRAGMENT_NAME);
        values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, FAKE_CONTROLLER_NAME);
        values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
        values.put(SlicesDatabaseHelper.IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
                customizedUnavailableSliceSubtitle);

        db.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values);
        db.close();
    }

}
+55 −92

File changed.

Preview size limit exceeded, changes collapsed.