Step 2 in refactoring DatabaseIndexingManager. This step moves the insertion of data into the database into a new class. This removes the remaining bulk of the code outside of DIM, but it does not fix the actual issue with the indexing code. The indexing code still chains functions together to insert data into the database at the end of the functions. It is exceedingly hard to read, and hard to track down bugs. I would like the converter to eventually return a list of IndexData objects, which lets us dissociate the database from the data collection. I.e. we can store the database in the Search app, and just pass IndexData objects via IPC.Fixing this requires more of a refactor, and will be done in a subsquent CL. Bug: 33577327 Test: make RunSettingsRoboTests Test: Took a database dump before and after change, and they were the same. Cool. Change-Id: Ia9bb815657b76f6cb9163014e746ec5eb6db8c5e
507 lines
20 KiB
Java
507 lines
20 KiB
Java
/*
|
|
* Copyright (C) 2017 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.search;
|
|
|
|
import static com.google.common.truth.Truth.assertThat;
|
|
import static org.mockito.Matchers.any;
|
|
import static org.mockito.Matchers.anyInt;
|
|
import static org.mockito.Matchers.anyList;
|
|
import static org.mockito.Matchers.anyString;
|
|
import static org.mockito.Matchers.anyBoolean;
|
|
import static org.mockito.Mockito.doNothing;
|
|
import static org.mockito.Mockito.doReturn;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.spy;
|
|
import static org.mockito.Mockito.times;
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
import android.content.ContentValues;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.pm.ApplicationInfo;
|
|
import android.content.pm.PackageManager;
|
|
import android.content.pm.ProviderInfo;
|
|
import android.content.pm.ResolveInfo;
|
|
import android.database.Cursor;
|
|
import android.database.sqlite.SQLiteDatabase;
|
|
import android.os.Build;
|
|
import android.provider.SearchIndexableData;
|
|
import android.util.ArrayMap;
|
|
|
|
import com.android.settings.TestConfig;
|
|
import com.android.settings.search.indexing.PreIndexData;
|
|
import com.android.settings.testutils.DatabaseTestUtils;
|
|
import com.android.settings.testutils.FakeFeatureFactory;
|
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
import com.android.settings.testutils.shadow.ShadowRunnableAsyncTask;
|
|
|
|
import org.junit.After;
|
|
import org.junit.Before;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.mockito.Mock;
|
|
import org.mockito.MockitoAnnotations;
|
|
import org.robolectric.Robolectric;
|
|
import org.robolectric.RuntimeEnvironment;
|
|
import org.robolectric.annotation.Config;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
@RunWith(SettingsRobolectricTestRunner.class)
|
|
@Config(
|
|
manifest = TestConfig.MANIFEST_PATH,
|
|
sdk = TestConfig.SDK_VERSION,
|
|
shadows = {
|
|
ShadowRunnableAsyncTask.class,
|
|
}
|
|
)
|
|
public class DatabaseIndexingManagerTest {
|
|
private final String localeStr = "en_US";
|
|
|
|
private final int rank = 8;
|
|
private final String title = "title\u2011title";
|
|
private final String updatedTitle = "title-title";
|
|
private final String normalizedTitle = "titletitle";
|
|
private final String summaryOn = "summary\u2011on";
|
|
private final String updatedSummaryOn = "summary-on";
|
|
private final String normalizedSummaryOn = "summaryon";
|
|
private final String summaryOff = "summary\u2011off";
|
|
private final String updatedSummaryOff = "summary-off";
|
|
private final String normalizedSummaryOff = "summaryoff";
|
|
private final String entries = "entries";
|
|
private final String keywords = "keywords, keywordss, keywordsss";
|
|
private final String spaceDelimittedKeywords = "keywords keywordss keywordsss";
|
|
private final String screenTitle = "screen title";
|
|
private final String className = "class name";
|
|
private final int iconResId = 0xff;
|
|
private final int noIcon = 0;
|
|
private final String action = "action";
|
|
private final String targetPackage = "target package";
|
|
private final String targetClass = "target class";
|
|
private final String packageName = "package name";
|
|
private final String key = "key";
|
|
private final int userId = -1;
|
|
private final boolean enabled = true;
|
|
|
|
private final String AUTHORITY_ONE = "authority";
|
|
private final String PACKAGE_ONE = "com.android.settings";
|
|
|
|
private final String TITLE_ONE = "title one";
|
|
private final String TITLE_TWO = "title two";
|
|
private final String KEY_ONE = "key one";
|
|
private final String KEY_TWO = "key two";
|
|
|
|
private Context mContext;
|
|
|
|
private DatabaseIndexingManager mManager;
|
|
private SQLiteDatabase mDb;
|
|
|
|
private final List<ResolveInfo> FAKE_PROVIDER_LIST = new ArrayList<>();
|
|
|
|
@Mock
|
|
private PackageManager mPackageManager;
|
|
|
|
@Before
|
|
public void setUp() {
|
|
MockitoAnnotations.initMocks(this);
|
|
mContext = spy(RuntimeEnvironment.application);
|
|
mManager = spy(new DatabaseIndexingManager(mContext));
|
|
mDb = IndexDatabaseHelper.getInstance(mContext).getWritableDatabase();
|
|
|
|
doReturn(mPackageManager).when(mContext).getPackageManager();
|
|
doReturn(FAKE_PROVIDER_LIST).when(mPackageManager)
|
|
.queryIntentContentProviders(any(Intent.class), anyInt());
|
|
FakeFeatureFactory.setupForTest(mContext);
|
|
}
|
|
|
|
@After
|
|
public void cleanUp() {
|
|
DatabaseTestUtils.clearDb(mContext);
|
|
}
|
|
|
|
@Test
|
|
public void testDatabaseSchema() {
|
|
Cursor dbCursor = mDb.query("prefs_index", null, null, null, null, null, null);
|
|
List<String> columnNames = new ArrayList<>(Arrays.asList(dbCursor.getColumnNames()));
|
|
// Note that docid is not included.
|
|
List<String> expColumnNames = Arrays.asList(
|
|
"locale",
|
|
"data_rank",
|
|
"data_title",
|
|
"data_title_normalized",
|
|
"data_summary_on",
|
|
"data_summary_on_normalized",
|
|
"data_summary_off",
|
|
"data_summary_off_normalized",
|
|
"data_entries",
|
|
"data_keywords",
|
|
"class_name",
|
|
"screen_title",
|
|
"intent_action",
|
|
"intent_target_package",
|
|
"intent_target_class",
|
|
"icon",
|
|
"enabled",
|
|
"data_key_reference",
|
|
"user_id",
|
|
"payload_type",
|
|
"payload"
|
|
);
|
|
// Prevent database schema regressions
|
|
assertThat(columnNames).containsAllIn(expColumnNames);
|
|
}
|
|
|
|
// Tests for the flow: IndexOneRaw -> UpdateOneRowWithFilteredData -> UpdateOneRow
|
|
|
|
@Test
|
|
public void testAddResource_withChildFragment_shouldUpdateSiteMapDb() {
|
|
// FIXME: This test was failing. (count = 6 at the end)
|
|
|
|
// SearchIndexableResource resource = getFakeResource(R.xml.network_and_internet);
|
|
// mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
|
// new HashMap<>());
|
|
// Cursor query = mDb.query(IndexDatabaseHelper.Tables.TABLE_SITE_MAP, SITE_MAP_COLUMNS,
|
|
// null, null, null, null, null);
|
|
// query.moveToPosition(-1);
|
|
// int count = 0;
|
|
// while (query.moveToNext()) {
|
|
// count++;
|
|
// assertThat(query.getString(query.getColumnIndex(SiteMapColumns.PARENT_CLASS)))
|
|
// .isEqualTo(className);
|
|
// assertThat(query.getString(query.getColumnIndex(SiteMapColumns.PARENT_TITLE)))
|
|
// .isEqualTo(mContext.getString(R.string.network_dashboard_title));
|
|
// assertThat(query.getString(query.getColumnIndex(SiteMapColumns.CHILD_CLASS)))
|
|
// .isNotEmpty();
|
|
// assertThat(query.getString(query.getColumnIndex(SiteMapColumns.CHILD_TITLE)))
|
|
// .isNotEmpty();
|
|
// }
|
|
// assertThat(count).isEqualTo(5);
|
|
}
|
|
|
|
// Test new public indexing flow
|
|
|
|
@Test
|
|
public void testPerformIndexing_fullIndex_getsDataFromProviders() {
|
|
SearchIndexableRaw rawData = getFakeRaw();
|
|
PreIndexData data = getPreIndexData(rawData);
|
|
doReturn(data).when(mManager).getIndexDataFromProviders(anyList(), anyBoolean());
|
|
doReturn(true).when(mManager).isFullIndex(any(Context.class), anyString(), anyString(),
|
|
anyString());
|
|
|
|
mManager.performIndexing();
|
|
|
|
verify(mManager).updateDatabase(data, true /* isFullIndex */,
|
|
Locale.getDefault().toString());
|
|
}
|
|
|
|
@Test
|
|
public void testPerformIndexing_fullIndex_databaseDropped() {
|
|
// Initialize the Manager and force rebuild
|
|
DatabaseIndexingManager manager =
|
|
spy(new DatabaseIndexingManager(mContext));
|
|
doReturn(false).when(mManager).isFullIndex(any(Context.class), anyString(), anyString(),
|
|
anyString());
|
|
|
|
// Insert data point which will be dropped
|
|
insertSpecialCase("Ceci n'est pas un pipe", true, "oui oui mon ami");
|
|
|
|
manager.performIndexing();
|
|
|
|
// Assert that the Old Title is no longer in the database, since it was dropped
|
|
final Cursor oldCursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
|
|
|
|
assertThat(oldCursor.getCount()).isEqualTo(0);
|
|
}
|
|
|
|
@Test
|
|
public void testPerformIndexing_isfullIndex() {
|
|
SearchIndexableRaw rawData = getFakeRaw();
|
|
PreIndexData data = getPreIndexData(rawData);
|
|
doReturn(data).when(mManager).getIndexDataFromProviders(anyList(), anyBoolean());
|
|
doReturn(true).when(mManager).isFullIndex(any(Context.class), anyString(), anyString(),
|
|
anyString());
|
|
|
|
mManager.performIndexing();
|
|
|
|
verify(mManager).updateDatabase(data, true /* isFullIndex */,
|
|
Locale.getDefault().toString());
|
|
}
|
|
|
|
@Test
|
|
public void testPerformIndexing_onPackageChange_fullIndex() {
|
|
final List<ResolveInfo> providers = getDummyResolveInfo();
|
|
final String buildNumber = Build.FINGERPRINT;
|
|
final String locale = Locale.getDefault().toString();
|
|
skipFullIndex(providers);
|
|
|
|
// This snapshot is already indexed. Should return false
|
|
assertThat(mManager.isFullIndex(
|
|
mContext, locale, buildNumber,
|
|
IndexDatabaseHelper.buildProviderVersionedNames(providers)))
|
|
.isFalse();
|
|
|
|
// Change provider version number, this should trigger full index.
|
|
providers.get(0).providerInfo.applicationInfo.versionCode++;
|
|
|
|
assertThat(mManager.isFullIndex(mContext, locale, buildNumber,
|
|
IndexDatabaseHelper.buildProviderVersionedNames(providers)))
|
|
.isTrue();
|
|
}
|
|
|
|
@Test
|
|
public void testPerformIndexing_onOta_buildNumberIsCached() {
|
|
mManager.performIndexing();
|
|
|
|
assertThat(IndexDatabaseHelper.isBuildIndexed(mContext, Build.FINGERPRINT)).isTrue();
|
|
}
|
|
|
|
@Test
|
|
public void testLocaleUpdated_afterIndexing_localeNotAdded() {
|
|
PreIndexData emptydata = new PreIndexData();
|
|
mManager.updateDatabase(emptydata, true /* isFullIndex */, localeStr);
|
|
|
|
assertThat(IndexDatabaseHelper.isLocaleAlreadyIndexed(mContext, localeStr)).isFalse();
|
|
}
|
|
|
|
@Test
|
|
public void testLocaleUpdated_afterFullIndexing_localeAdded() {
|
|
mManager.performIndexing();
|
|
assertThat(IndexDatabaseHelper.isLocaleAlreadyIndexed(mContext, localeStr)).isTrue();
|
|
}
|
|
|
|
@Test
|
|
public void testUpdateDatabase_newEligibleData_addedToDatabase() {
|
|
// Test that addDataToDatabase is called when dataToUpdate is non-empty
|
|
PreIndexData indexData = new PreIndexData();
|
|
indexData.dataToUpdate.add(getFakeRaw());
|
|
mManager.updateDatabase(indexData, true /* isFullIndex */, localeStr);
|
|
|
|
Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
|
|
cursor.moveToPosition(0);
|
|
|
|
// Locale
|
|
assertThat(cursor.getString(0)).isEqualTo(localeStr);
|
|
// Data Rank
|
|
assertThat(cursor.getInt(1)).isEqualTo(rank);
|
|
// Data Title
|
|
assertThat(cursor.getString(2)).isEqualTo(updatedTitle);
|
|
// Normalized Title
|
|
assertThat(cursor.getString(3)).isEqualTo(normalizedTitle);
|
|
// Summary On
|
|
assertThat(cursor.getString(4)).isEqualTo(updatedSummaryOn);
|
|
// Summary On Normalized
|
|
assertThat(cursor.getString(5)).isEqualTo(normalizedSummaryOn);
|
|
// Summary Off
|
|
assertThat(cursor.getString(6)).isEqualTo(updatedSummaryOff);
|
|
// Summary off normalized
|
|
assertThat(cursor.getString(7)).isEqualTo(normalizedSummaryOff);
|
|
// Entries
|
|
assertThat(cursor.getString(8)).isEqualTo(entries);
|
|
// Keywords
|
|
assertThat(cursor.getString(9)).isEqualTo(spaceDelimittedKeywords);
|
|
// Screen Title
|
|
assertThat(cursor.getString(10)).isEqualTo(screenTitle);
|
|
// Class Name
|
|
assertThat(cursor.getString(11)).isEqualTo(className);
|
|
// Icon
|
|
assertThat(cursor.getInt(12)).isEqualTo(iconResId);
|
|
// Intent Action
|
|
assertThat(cursor.getString(13)).isEqualTo(action);
|
|
// Target Package
|
|
assertThat(cursor.getString(14)).isEqualTo(targetPackage);
|
|
// Target Class
|
|
assertThat(cursor.getString(15)).isEqualTo(targetClass);
|
|
// Enabled
|
|
assertThat(cursor.getInt(16) == 1).isEqualTo(enabled);
|
|
// Data ref key
|
|
assertThat(cursor.getString(17)).isNotNull();
|
|
// User Id
|
|
assertThat(cursor.getInt(18)).isEqualTo(userId);
|
|
// Payload Type - default is 0
|
|
assertThat(cursor.getInt(19)).isEqualTo(0);
|
|
// Payload
|
|
byte[] payload = cursor.getBlob(20);
|
|
ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload,
|
|
ResultPayload.CREATOR);
|
|
assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class);
|
|
}
|
|
|
|
@Test
|
|
public void testUpdateDataInDatabase_enabledResultsAreNonIndexable_becomeDisabled() {
|
|
// Both results are enabled, and then TITLE_ONE gets disabled.
|
|
final boolean enabled = true;
|
|
insertSpecialCase(TITLE_ONE, enabled, KEY_ONE);
|
|
insertSpecialCase(TITLE_TWO, enabled, KEY_TWO);
|
|
Map<String, Set<String>> niks = new ArrayMap<>();
|
|
Set<String> keys = new HashSet<>();
|
|
keys.add(KEY_ONE);
|
|
niks.put(targetPackage, keys);
|
|
|
|
mManager.updateDataInDatabase(mDb, niks);
|
|
|
|
Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null);
|
|
cursor.moveToPosition(0);
|
|
|
|
assertThat(cursor.getString(2)).isEqualTo(TITLE_ONE);
|
|
}
|
|
|
|
@Test
|
|
public void testUpdateDataInDatabase_disabledResultsAreIndexable_becomeEnabled() {
|
|
// Both results are initially disabled, and then TITLE_TWO gets enabled.
|
|
final boolean enabled = false;
|
|
insertSpecialCase(TITLE_ONE, enabled, KEY_ONE);
|
|
insertSpecialCase(TITLE_TWO, enabled, KEY_TWO);
|
|
Map<String, Set<String>> niks = new ArrayMap<>();
|
|
Set<String> keys = new HashSet<>();
|
|
keys.add(KEY_ONE);
|
|
niks.put(targetPackage, keys);
|
|
|
|
mManager.updateDataInDatabase(mDb, niks);
|
|
|
|
Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null);
|
|
cursor.moveToPosition(0);
|
|
|
|
assertThat(cursor.getString(2)).isEqualTo(TITLE_TWO);
|
|
}
|
|
|
|
@Test
|
|
public void testEmptyNonIndexableKeys_emptyDataKeyResources_addedToDatabase() {
|
|
insertSpecialCase(TITLE_ONE, true /* enabled */, null /* dataReferenceKey */);
|
|
PreIndexData emptydata = new PreIndexData();
|
|
mManager.updateDatabase(emptydata, false /* needsReindexing */, localeStr);
|
|
|
|
Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null);
|
|
cursor.moveToPosition(0);
|
|
assertThat(cursor.getCount()).isEqualTo(1);
|
|
assertThat(cursor.getString(2)).isEqualTo(TITLE_ONE);
|
|
}
|
|
|
|
@Test
|
|
public void testUpdateAsyncTask_onPostExecute_performsCallback() {
|
|
IndexingCallback callback = mock(IndexingCallback.class);
|
|
|
|
DatabaseIndexingManager.IndexingTask task = mManager.new IndexingTask(callback);
|
|
task.execute();
|
|
|
|
Robolectric.flushForegroundThreadScheduler();
|
|
|
|
verify(callback).onIndexingFinished();
|
|
}
|
|
|
|
@Test
|
|
public void testUpdateAsyncTask_onPostExecute_setsIndexingComplete() {
|
|
SearchFeatureProviderImpl provider = new SearchFeatureProviderImpl();
|
|
DatabaseIndexingManager manager = spy(provider.getIndexingManager(mContext));
|
|
DatabaseIndexingManager.IndexingTask task = manager.new IndexingTask(null);
|
|
doNothing().when(manager).performIndexing();
|
|
|
|
task.execute();
|
|
Robolectric.flushForegroundThreadScheduler();
|
|
|
|
assertThat(provider.isIndexingComplete(mContext)).isTrue();
|
|
}
|
|
|
|
// Util functions
|
|
|
|
private void skipFullIndex(List<ResolveInfo> providers) {
|
|
IndexDatabaseHelper.setLocaleIndexed(mContext, Locale.getDefault().toString());
|
|
IndexDatabaseHelper.setBuildIndexed(mContext, Build.FINGERPRINT);
|
|
IndexDatabaseHelper.setProvidersIndexed(mContext,
|
|
IndexDatabaseHelper.buildProviderVersionedNames(providers));
|
|
}
|
|
|
|
private SearchIndexableRaw getFakeRaw() {
|
|
return getFakeRaw(localeStr);
|
|
}
|
|
|
|
private SearchIndexableRaw getFakeRaw(String localeStr) {
|
|
SearchIndexableRaw data = new SearchIndexableRaw(mContext);
|
|
data.locale = new Locale(localeStr);
|
|
data.rank = rank;
|
|
data.title = title;
|
|
data.summaryOn = summaryOn;
|
|
data.summaryOff = summaryOff;
|
|
data.entries = entries;
|
|
data.keywords = keywords;
|
|
data.screenTitle = screenTitle;
|
|
data.className = className;
|
|
data.packageName = packageName;
|
|
data.iconResId = iconResId;
|
|
data.intentAction = action;
|
|
data.intentTargetPackage = targetPackage;
|
|
data.intentTargetClass = targetClass;
|
|
data.key = key;
|
|
data.userId = userId;
|
|
data.enabled = enabled;
|
|
return data;
|
|
}
|
|
|
|
private void insertSpecialCase(String specialCase, boolean enabled, String key) {
|
|
ContentValues values = new ContentValues();
|
|
values.put(IndexDatabaseHelper.IndexColumns.DOCID, specialCase.hashCode());
|
|
values.put(IndexDatabaseHelper.IndexColumns.LOCALE, localeStr);
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_RANK, 1);
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, specialCase);
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves");
|
|
values.put(IndexDatabaseHelper.IndexColumns.INTENT_ACTION, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.INTENT_TARGET_PACKAGE, targetPackage);
|
|
values.put(IndexDatabaseHelper.IndexColumns.INTENT_TARGET_CLASS, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.ICON, "");
|
|
values.put(IndexDatabaseHelper.IndexColumns.ENABLED, enabled);
|
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEY_REF, key);
|
|
values.put(IndexDatabaseHelper.IndexColumns.USER_ID, 0);
|
|
values.put(IndexDatabaseHelper.IndexColumns.PAYLOAD_TYPE, 0);
|
|
values.put(IndexDatabaseHelper.IndexColumns.PAYLOAD, (String) null);
|
|
|
|
mDb.replaceOrThrow(IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX, null, values);
|
|
}
|
|
|
|
private PreIndexData getPreIndexData(SearchIndexableData fakeData) {
|
|
PreIndexData data = new PreIndexData();
|
|
data.dataToUpdate.add(fakeData);
|
|
return data;
|
|
}
|
|
|
|
private List<ResolveInfo> getDummyResolveInfo() {
|
|
List<ResolveInfo> infoList = new ArrayList<>();
|
|
ResolveInfo info = new ResolveInfo();
|
|
info.providerInfo = new ProviderInfo();
|
|
info.providerInfo.exported = true;
|
|
info.providerInfo.authority = AUTHORITY_ONE;
|
|
info.providerInfo.packageName = PACKAGE_ONE;
|
|
info.providerInfo.applicationInfo = new ApplicationInfo();
|
|
infoList.add(info);
|
|
|
|
return infoList;
|
|
}
|
|
}
|