diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 94be61c9312..e64a9b38b12 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3029,9 +3029,6 @@ android:exported="true" android:permission="android.permission.DUMP" /> - - indexProvider.updateIndex(SettingsActivity.this, false /* force */)); - } - private void doUpdateTilesList() { PackageManager pm = getPackageManager(); final UserManager um = UserManager.get(this); diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java index ef8d1eef11d..38d48c83402 100644 --- a/src/com/android/settings/overlay/FeatureFactory.java +++ b/src/com/android/settings/overlay/FeatureFactory.java @@ -29,7 +29,6 @@ import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider; import com.android.settings.fuelgauge.PowerUsageFeatureProvider; import com.android.settings.gestures.AssistGestureFeatureProvider; import com.android.settings.localepicker.LocaleFeatureProvider; -import com.android.settings.search.DeviceIndexFeatureProvider; import com.android.settings.search.SearchFeatureProvider; import com.android.settings.security.SecurityFeatureProvider; import com.android.settings.slices.SlicesFeatureProvider; @@ -106,8 +105,6 @@ public abstract class FeatureFactory { public abstract AccountFeatureProvider getAccountFeatureProvider(); - public abstract DeviceIndexFeatureProvider getDeviceIndexFeatureProvider(); - public static final class FactoryNotFoundException extends RuntimeException { public FactoryNotFoundException(Throwable throwable) { super("Unable to create factory. Did you misconfigure Proguard?", throwable); diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java index 61be109d4f8..1f575293033 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.java +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java @@ -41,8 +41,6 @@ import com.android.settings.gestures.AssistGestureFeatureProvider; import com.android.settings.gestures.AssistGestureFeatureProviderImpl; import com.android.settings.localepicker.LocaleFeatureProvider; import com.android.settings.localepicker.LocaleFeatureProviderImpl; -import com.android.settings.search.DeviceIndexFeatureProvider; -import com.android.settings.search.DeviceIndexFeatureProviderImpl; import com.android.settings.search.SearchFeatureProvider; import com.android.settings.search.SearchFeatureProviderImpl; import com.android.settings.security.SecurityFeatureProvider; @@ -73,7 +71,6 @@ public class FeatureFactoryImpl extends FeatureFactory { private UserFeatureProvider mUserFeatureProvider; private SlicesFeatureProvider mSlicesFeatureProvider; private AccountFeatureProvider mAccountFeatureProvider; - private DeviceIndexFeatureProviderImpl mDeviceIndexFeatureProvider; @Override public SupportFeatureProvider getSupportFeatureProvider(Context context) { @@ -211,12 +208,4 @@ public class FeatureFactoryImpl extends FeatureFactory { } return mAccountFeatureProvider; } - - @Override - public DeviceIndexFeatureProvider getDeviceIndexFeatureProvider() { - if (mDeviceIndexFeatureProvider == null) { - mDeviceIndexFeatureProvider = new DeviceIndexFeatureProviderImpl(); - } - return mDeviceIndexFeatureProvider; - } } diff --git a/src/com/android/settings/search/DeviceIndexFeatureProvider.java b/src/com/android/settings/search/DeviceIndexFeatureProvider.java deleted file mode 100644 index f777f710fe9..00000000000 --- a/src/com/android/settings/search/DeviceIndexFeatureProvider.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2018 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.android.settings.slices.SliceDeepLinkSpringBoard.INTENT; -import static com.android.settings.slices.SliceDeepLinkSpringBoard.SETTINGS; - -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.PackageManager; -import android.content.pm.ServiceInfo; -import android.net.Uri; -import android.os.Binder; -import android.os.Build; -import android.provider.Settings; -import android.text.TextUtils; -import android.util.Log; - -import com.android.settings.R; -import com.android.settings.Utils; -import com.android.settings.slices.SettingsSliceProvider; - -import java.util.List; -import java.util.Locale; - -public interface DeviceIndexFeatureProvider { - - String TAG = "DeviceIndex"; - - String INDEX_VERSION = "settings:index_version"; - String INDEX_LANGUAGE = "settings:language"; - - // Increment when new items are added to ensure they get pushed to the device index. - String VERSION = Build.FINGERPRINT; - - // When the device language changes, re-index so Slices trigger in device language. - Locale LANGUAGE = Locale.getDefault(); - - default boolean isIndexingEnabled() { - return false; - } - - void index(Context context, CharSequence title, Uri sliceUri, Uri launchUri, - List keywords); - - void clearIndex(Context context); - - default void updateIndex(Context context, boolean force) { - if (!isIndexingEnabled()) { - Log.i(TAG, "Skipping: device index is not enabled"); - return; - } - - if (!Utils.isDeviceProvisioned(context)) { - Log.w(TAG, "Skipping: device is not provisioned"); - return; - } - - final ComponentName jobComponent = new ComponentName(context.getPackageName(), - DeviceIndexUpdateJobService.class.getName()); - - try { - final int callerUid = Binder.getCallingUid(); - final ServiceInfo si = context.getPackageManager().getServiceInfo(jobComponent, - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); - if (si == null) { - Log.w(TAG, "Skipping: No such service " + jobComponent); - return; - } - if (si.applicationInfo.uid != callerUid) { - Log.w(TAG, "Skipping: Uid cannot schedule DeviceIndexUpdate: " + callerUid); - return; - } - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Skipping: error finding DeviceIndexUpdateJobService from packageManager"); - return; - } - - if (!force && skipIndex(context)) { - Log.i(TAG, "Skipping: already indexed."); - // No need to update. - return; - } - - // Prevent scheduling multiple jobs - setIndexState(context); - - final int jobId = context.getResources().getInteger(R.integer.device_index_update); - // Schedule a job so that we know it'll be able to complete, but try to run as - // soon as possible. - context.getSystemService(JobScheduler.class).schedule( - new JobInfo.Builder(jobId, jobComponent) - .setPersisted(false) - .setMinimumLatency(1000) - .setOverrideDeadline(1) - .build()); - - } - - static Uri createDeepLink(String s) { - return new Uri.Builder().scheme(SETTINGS) - .authority(SettingsSliceProvider.SLICE_AUTHORITY) - .appendQueryParameter(INTENT, s) - .build(); - } - - static boolean skipIndex(Context context) { - final boolean isSameVersion = TextUtils.equals( - Settings.Secure.getString(context.getContentResolver(), INDEX_VERSION), VERSION); - final boolean isSameLanguage = TextUtils.equals( - Settings.Secure.getString(context.getContentResolver(), INDEX_LANGUAGE), - LANGUAGE.toString()); - return isSameLanguage && isSameVersion; - } - - static void setIndexState(Context context) { - Settings.Secure.putString(context.getContentResolver(), INDEX_VERSION, VERSION); - Settings.Secure.putString(context.getContentResolver(), INDEX_LANGUAGE, - LANGUAGE.toString()); - } -} diff --git a/src/com/android/settings/search/DeviceIndexFeatureProviderImpl.java b/src/com/android/settings/search/DeviceIndexFeatureProviderImpl.java deleted file mode 100644 index 8fd1606452f..00000000000 --- a/src/com/android/settings/search/DeviceIndexFeatureProviderImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2018 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 android.content.Context; -import android.net.Uri; - -import java.util.List; - -public class DeviceIndexFeatureProviderImpl implements DeviceIndexFeatureProvider { - - @Override - public void index(Context context, CharSequence title, Uri sliceUri, Uri launchUri, - List keywords) { - // Not enabled by default. - } - - @Override - public void clearIndex(Context context) { - // Not enabled by default. - } -} diff --git a/src/com/android/settings/search/DeviceIndexUpdateJobService.java b/src/com/android/settings/search/DeviceIndexUpdateJobService.java deleted file mode 100644 index 1f7ee31e6f6..00000000000 --- a/src/com/android/settings/search/DeviceIndexUpdateJobService.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2018 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 android.app.slice.Slice.HINT_LARGE; -import static android.app.slice.Slice.HINT_TITLE; -import static android.app.slice.SliceItem.FORMAT_TEXT; - -import static com.android.settings.search.DeviceIndexFeatureProvider.createDeepLink; - -import android.app.job.JobParameters; -import android.app.job.JobService; -import android.content.ContentResolver; -import android.content.Intent; -import android.net.Uri; -import android.net.Uri.Builder; -import android.provider.SettingsSlicesContract; -import android.util.Log; - -import androidx.annotation.VisibleForTesting; -import androidx.slice.Slice; -import androidx.slice.SliceItem; -import androidx.slice.SliceMetadata; -import androidx.slice.SliceViewManager; -import androidx.slice.SliceViewManager.SliceCallback; -import androidx.slice.core.SliceQuery; -import androidx.slice.widget.ListContent; -import androidx.slice.widget.SliceContent; - -import com.android.settings.overlay.FeatureFactory; -import com.android.settings.slices.SettingsSliceProvider; -import com.android.settings.slices.SliceDeepLinkSpringBoard; - -import java.util.Collection; -import java.util.concurrent.CountDownLatch; - -public class DeviceIndexUpdateJobService extends JobService { - - private static final String TAG = "DeviceIndexUpdate"; - private static final boolean DEBUG = false; - @VisibleForTesting - protected boolean mRunningJob; - - @Override - public boolean onStartJob(JobParameters params) { - if (DEBUG) Log.d(TAG, "onStartJob"); - if (!mRunningJob) { - mRunningJob = true; - Thread thread = new Thread(() -> updateIndex(params)); - thread.setPriority(Thread.MIN_PRIORITY); - thread.start(); - } - return true; - } - - @Override - public boolean onStopJob(JobParameters params) { - if (DEBUG) Log.d(TAG, "onStopJob " + mRunningJob); - if (mRunningJob) { - mRunningJob = false; - return true; - } - return false; - } - - @VisibleForTesting - protected void updateIndex(JobParameters params) { - if (DEBUG) { - Log.d(TAG, "Starting index"); - } - final DeviceIndexFeatureProvider indexProvider = FeatureFactory.getFactory(this) - .getDeviceIndexFeatureProvider(); - final SliceViewManager manager = getSliceViewManager(); - final Uri baseUri = new Builder() - .scheme(ContentResolver.SCHEME_CONTENT) - .authority(SettingsSliceProvider.SLICE_AUTHORITY) - .build(); - final Uri platformBaseUri = new Builder() - .scheme(ContentResolver.SCHEME_CONTENT) - .authority(SettingsSlicesContract.AUTHORITY) - .build(); - final Collection slices = manager.getSliceDescendants(baseUri); - slices.addAll(manager.getSliceDescendants(platformBaseUri)); - - if (DEBUG) { - Log.d(TAG, "Indexing " + slices.size() + " slices"); - } - - indexProvider.clearIndex(this /* context */); - - for (Uri slice : slices) { - if (!mRunningJob) { - return; - } - Slice loadedSlice = bindSliceSynchronous(manager, slice); - // TODO: Get Title APIs on SliceMetadata and use that. - SliceMetadata metaData = getMetadata(loadedSlice); - CharSequence title = findTitle(loadedSlice, metaData); - if (title != null) { - if (DEBUG) { - Log.d(TAG, "Indexing: " + slice + " " + title + " " + loadedSlice); - } - indexProvider.index(this, title, slice, createDeepLink( - new Intent(SliceDeepLinkSpringBoard.ACTION_VIEW_SLICE) - .setPackage(getPackageName()) - .putExtra(SliceDeepLinkSpringBoard.EXTRA_SLICE, slice.toString()) - .toUri(Intent.URI_ANDROID_APP_SCHEME)), - metaData.getSliceKeywords()); - } - } - if (DEBUG) { - Log.d(TAG, "Done indexing"); - } - jobFinished(params, false); - } - - protected SliceViewManager getSliceViewManager() { - return SliceViewManager.getInstance(this); - } - - protected SliceMetadata getMetadata(Slice loadedSlice) { - return SliceMetadata.from(this, loadedSlice); - } - - protected CharSequence findTitle(Slice loadedSlice, SliceMetadata metaData) { - ListContent content = new ListContent(null, loadedSlice); - SliceContent headerItem = content.getHeader(); - if (headerItem == null) { - if (content.getRowItems().size() != 0) { - headerItem = content.getRowItems().get(0); - } else { - return null; - } - } - // Look for a title, then large text, then any text at all. - SliceItem title = SliceQuery.find(headerItem.getSliceItem(), FORMAT_TEXT, HINT_TITLE, null); - if (title != null) { - return title.getText(); - } - title = SliceQuery.find(headerItem.getSliceItem(), FORMAT_TEXT, HINT_LARGE, null); - if (title != null) { - return title.getText(); - } - title = SliceQuery.find(headerItem.getSliceItem(), FORMAT_TEXT); - if (title != null) { - return title.getText(); - } - return null; - } - - protected Slice bindSliceSynchronous(SliceViewManager manager, Uri slice) { - final Slice[] returnSlice = new Slice[1]; - CountDownLatch latch = new CountDownLatch(1); - SliceCallback callback = new SliceCallback() { - @Override - public void onSliceUpdated(Slice s) { - try { - SliceMetadata m = SliceMetadata.from(DeviceIndexUpdateJobService.this, s); - if (m.getLoadingState() == SliceMetadata.LOADED_ALL) { - returnSlice[0] = s; - latch.countDown(); - manager.unregisterSliceCallback(slice, this); - } - } catch (Exception e) { - Log.w(TAG, slice + " cannot be indexed", e); - returnSlice[0] = s; - } - } - }; - // Register a callback until we get a loaded slice. - manager.registerSliceCallback(slice, callback); - // Trigger the first bind in case no loading is needed. - callback.onSliceUpdated(manager.bindSlice(slice)); - try { - latch.await(); - } catch (InterruptedException e) { - } - return returnSlice[0]; - } -} diff --git a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java index 5d36d737134..75317788ef3 100644 --- a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java +++ b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java @@ -21,6 +21,8 @@ import android.os.Bundle; import android.provider.Settings; import android.util.Log; +import androidx.annotation.Keep; + import com.android.settings.bluetooth.BluetoothSliceBuilder; import com.android.settings.location.LocationSliceBuilder; import com.android.settings.notification.ZenModeSliceBuilder; @@ -90,6 +92,14 @@ public class SliceDeepLinkSpringBoard extends Activity { } } + @Keep + public static Uri createDeepLink(String s) { + return new Uri.Builder().scheme(SETTINGS) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendQueryParameter(INTENT, s) + .build(); + } + public static Intent parse(Uri uri, String pkg) throws URISyntaxException { Intent intent = Intent.parseUri(uri.getQueryParameter(INTENT), Intent.URI_ANDROID_APP_SCHEME); diff --git a/tests/robotests/src/com/android/settings/search/DeviceIndexFeatureProviderTest.java b/tests/robotests/src/com/android/settings/search/DeviceIndexFeatureProviderTest.java deleted file mode 100644 index b49ef1d0683..00000000000 --- a/tests/robotests/src/com/android/settings/search/DeviceIndexFeatureProviderTest.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2018 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 org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.app.job.JobScheduler; -import android.os.Binder; -import android.provider.Settings; - -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -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.shadows.ShadowBinder; - -@RunWith(SettingsRobolectricTestRunner.class) -public class DeviceIndexFeatureProviderTest { - - @Mock - private JobScheduler mJobScheduler; - private DeviceIndexFeatureProvider mProvider; - private Activity mActivity; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - ShadowBinder.reset(); - FakeFeatureFactory.setupForTest(); - mActivity = spy(Robolectric.buildActivity(Activity.class).create().visible().get()); - mProvider = spy(new DeviceIndexFeatureProviderImpl()); - when(mActivity.getSystemService(JobScheduler.class)).thenReturn(mJobScheduler); - } - - @After - public void tearDown() { - ShadowBinder.reset(); - } - - @Test - public void updateIndex_disabled_shouldDoNothing() { - when(mProvider.isIndexingEnabled()).thenReturn(false); - - mProvider.updateIndex(mActivity, false); - verify(mJobScheduler, never()).schedule(any()); - } - - @Test - public void updateIndex_enabled_unprovisioned_shouldDoNothing() { - when(mProvider.isIndexingEnabled()).thenReturn(true); - Settings.Global.putInt(mActivity.getContentResolver(), - Settings.Global.DEVICE_PROVISIONED, 0); - - mProvider.updateIndex(mActivity, false); - - verify(mJobScheduler, never()).schedule(any()); - } - - @Test - public void updateIndex_enabled_provisioned_shouldIndex() { - Settings.Global.putInt(mActivity.getContentResolver(), - Settings.Global.DEVICE_PROVISIONED, 1); - when(mProvider.isIndexingEnabled()).thenReturn(true); - - mProvider.updateIndex(mActivity, false); - verify(mJobScheduler).schedule(any()); - } - - @Test - public void updateIndex_enabled_provisioned_newBuild_shouldIndex() { - Settings.Global.putInt(mActivity.getContentResolver(), - Settings.Global.DEVICE_PROVISIONED, 1); - DeviceIndexFeatureProvider.setIndexState(mActivity); - Settings.Global.putString(mActivity.getContentResolver(), - DeviceIndexFeatureProvider.INDEX_VERSION, "new version"); - Settings.Global.putString(mActivity.getContentResolver(), - DeviceIndexFeatureProvider.LANGUAGE.toString(), - DeviceIndexFeatureProvider.INDEX_LANGUAGE); - when(mProvider.isIndexingEnabled()).thenReturn(true); - - mProvider.updateIndex(mActivity, false); - verify(mJobScheduler).schedule(any()); - } - - @Test - public void updateIndex_enabled_provisioned_differentUid_shouldNotIndex() { - Settings.Global.putInt(mActivity.getContentResolver(), - Settings.Global.DEVICE_PROVISIONED, 1); - when(mProvider.isIndexingEnabled()).thenReturn(true); - - ShadowBinder.setCallingUid(Binder.getCallingUid() + 2000); - - mProvider.updateIndex(mActivity, false); - verify(mJobScheduler, never()).schedule(any()); - } - - @Test - public void updateIndex_enabled_provisioned_newIndex_shouldIndex() { - Settings.Global.putInt(mActivity.getContentResolver(), - Settings.Global.DEVICE_PROVISIONED, 1); - DeviceIndexFeatureProvider.setIndexState(mActivity); - Settings.Global.putString(mActivity.getContentResolver(), - DeviceIndexFeatureProvider.INDEX_LANGUAGE, "new language"); - - when(mProvider.isIndexingEnabled()).thenReturn(true); - - mProvider.updateIndex(mActivity, false); - verify(mJobScheduler).schedule(any()); - } - - @Test - public void updateIndex_enabled_provisioned_sameBuild_sameLang_shouldNotIndex() { - // Enabled - when(mProvider.isIndexingEnabled()).thenReturn(true); - // Provisioned - Settings.Global.putInt(mActivity.getContentResolver(), - Settings.Global.DEVICE_PROVISIONED, 1); - // Same build and same language - DeviceIndexFeatureProvider.setIndexState(mActivity); - - mProvider.updateIndex(mActivity, false); - - verify(mJobScheduler, never()).schedule(any()); - } -} diff --git a/tests/robotests/src/com/android/settings/search/DeviceIndexUpdateJobServiceTest.java b/tests/robotests/src/com/android/settings/search/DeviceIndexUpdateJobServiceTest.java deleted file mode 100644 index 43ce96611d0..00000000000 --- a/tests/robotests/src/com/android/settings/search/DeviceIndexUpdateJobServiceTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2018 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 org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -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 static org.mockito.Mockito.when; - -import android.app.Activity; -import android.content.ContentResolver; -import android.net.Uri; - -import androidx.slice.Slice; -import androidx.slice.SliceMetadata; -import androidx.slice.SliceViewManager; - -import com.android.settings.slices.SettingsSliceProvider; -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.Robolectric; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(SettingsRobolectricTestRunner.class) -public class DeviceIndexUpdateJobServiceTest { - private static final Uri BASE_URI = new Uri.Builder() - .scheme(ContentResolver.SCHEME_CONTENT) - .authority(SettingsSliceProvider.SLICE_AUTHORITY) - .build(); - - private Activity mActivity; - private DeviceIndexUpdateJobService mJob; - private SliceViewManager mSliceManager; - - @Before - public void setup() { - FakeFeatureFactory.setupForTest(); - mActivity = spy(Robolectric.buildActivity(Activity.class).create().visible().get()); - mJob = spy(new DeviceIndexUpdateJobService()); - mSliceManager = mock(SliceViewManager.class); - - doReturn(mActivity.getPackageName()).when(mJob).getPackageName(); - doReturn(mSliceManager).when(mJob).getSliceViewManager(); - doNothing().when(mJob).jobFinished(null, false); - } - - @Test - public void testGetsSlices() { - setSlices(); - - mJob.updateIndex(null); - verify(mSliceManager).getSliceDescendants(eq(BASE_URI)); - } - - @Test - public void testIndexesSlices() { - setSlices(genSlice("path1"), genSlice("path2")); - - mJob.mRunningJob = true; - mJob.updateIndex(null); - verify(mSliceManager).getSliceDescendants(eq(BASE_URI)); - - DeviceIndexFeatureProvider indexFeatureProvider = FakeFeatureFactory.getFactory(mActivity) - .getDeviceIndexFeatureProvider(); - verify(indexFeatureProvider, times(2)).index(any(), any(), any(), any(), any()); - } - - @Test - public void testDoNotIndexWithoutTitle() { - Slice testSlice = genSlice("path2"); - setSlices(genSlice("path1"), testSlice); - doReturn(null).when(mJob).findTitle(testSlice, mJob.getMetadata(testSlice)); - - mJob.mRunningJob = true; - mJob.updateIndex(null); - verify(mSliceManager).getSliceDescendants(eq(BASE_URI)); - - DeviceIndexFeatureProvider indexFeatureProvider = FakeFeatureFactory.getFactory(mActivity) - .getDeviceIndexFeatureProvider(); - verify(indexFeatureProvider, times(1)).index(any(), any(), any(), any(), any()); - } - - @Test - public void testStopIndexing() { - Slice testSlice = genSlice("path1"); - setSlices(testSlice, genSlice("path2")); - mJob.mRunningJob = true; - - doAnswer(invocation -> { - // Stop running after the first iteration - mJob.mRunningJob = false; - return testSlice; - }).when(mJob).bindSliceSynchronous(mSliceManager, testSlice.getUri()); - - mJob.updateIndex(null); - verify(mSliceManager).getSliceDescendants(eq(BASE_URI)); - - DeviceIndexFeatureProvider indexFeatureProvider = FakeFeatureFactory.getFactory(mActivity) - .getDeviceIndexFeatureProvider(); - verify(indexFeatureProvider).clearIndex(any()); - verify(indexFeatureProvider, times(1)).index(any(), any(), any(), any(), any()); - } - - private Slice genSlice(String path) { - return new Slice.Builder(BASE_URI.buildUpon().path(path).build()).build(); - } - - private void setSlices(Slice... slice) { - List mUris = new ArrayList<>(); - for (Slice slouse : slice) { - SliceMetadata m = mock(SliceMetadata.class); - mUris.add(slouse.getUri()); - doReturn(slouse).when(mJob).bindSliceSynchronous(mSliceManager, slouse.getUri()); - doReturn(m).when(mJob).getMetadata(slouse); - doReturn(slouse.getUri().getPath()).when(mJob).findTitle(slouse, m); - } - when(mSliceManager.getSliceDescendants(BASE_URI)).thenReturn(mUris); - } - -} diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java index 39d4417b063..24db8298c80 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -33,7 +33,6 @@ import com.android.settings.overlay.DockUpdaterFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.SupportFeatureProvider; import com.android.settings.overlay.SurveyFeatureProvider; -import com.android.settings.search.DeviceIndexFeatureProvider; import com.android.settings.search.SearchFeatureProvider; import com.android.settings.security.SecurityFeatureProvider; import com.android.settings.slices.SlicesFeatureProvider; @@ -62,7 +61,6 @@ public class FakeFeatureFactory extends FeatureFactory { public final UserFeatureProvider userFeatureProvider; public final AssistGestureFeatureProvider assistGestureFeatureProvider; public final AccountFeatureProvider mAccountFeatureProvider; - public final DeviceIndexFeatureProvider deviceIndexFeatureProvider; public SlicesFeatureProvider slicesFeatureProvider; public SearchFeatureProvider searchFeatureProvider; @@ -104,7 +102,6 @@ public class FakeFeatureFactory extends FeatureFactory { assistGestureFeatureProvider = mock(AssistGestureFeatureProvider.class); slicesFeatureProvider = mock(SlicesFeatureProvider.class); mAccountFeatureProvider = mock(AccountFeatureProvider.class); - deviceIndexFeatureProvider = mock(DeviceIndexFeatureProvider.class); } @Override @@ -186,9 +183,4 @@ public class FakeFeatureFactory extends FeatureFactory { public AccountFeatureProvider getAccountFeatureProvider() { return mAccountFeatureProvider; } - - @Override - public DeviceIndexFeatureProvider getDeviceIndexFeatureProvider() { - return deviceIndexFeatureProvider; - } } diff --git a/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java b/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java index dfeca5fd0e4..81f1face0c3 100644 --- a/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java +++ b/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java @@ -16,7 +16,7 @@ package com.android.settings.slices; -import static com.android.settings.search.DeviceIndexFeatureProvider.createDeepLink; +import static com.android.settings.slices.SliceDeepLinkSpringBoard.createDeepLink; import android.content.Context; import android.content.Intent;