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;
public interface DeviceIndexFeatureProvider {
-
String TAG = "DeviceIndex";
String INDEX_VERSION = "settings:index_version";
default void updateIndex(Context context, boolean force) {
if (!isIndexingEnabled()) {
- Log.w(TAG, "Skipping: device index is not enabled");
+ Log.i(TAG, "Skipping: device index is not enabled");
return;
}
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 ComponentName jobComponent = new ComponentName(context.getPackageName(),
- DeviceIndexUpdateJobService.class.getName());
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.
package com.android.settings.search;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
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
when(mProvider.isIndexingEnabled()).thenReturn(false);
mProvider.updateIndex(mActivity, false);
- verify(mProvider, never()).index(any(), any(), any(), any(), any());
+ verify(mJobScheduler, never()).schedule(any());
}
@Test
mProvider.updateIndex(mActivity, false);
- verify(mProvider, never()).index(any(), any(), any(), any(), any());
+ verify(mJobScheduler, never()).schedule(any());
}
@Test
public void updateIndex_enabled_provisioned_shouldIndex() {
Settings.Global.putInt(mActivity.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 1);
- JobScheduler jobScheduler = mock(JobScheduler.class);
when(mProvider.isIndexingEnabled()).thenReturn(true);
- when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler);
mProvider.updateIndex(mActivity, false);
- verify(jobScheduler).schedule(any());
+ verify(mJobScheduler).schedule(any());
}
@Test
Settings.Global.putString(mActivity.getContentResolver(),
DeviceIndexFeatureProvider.LANGUAGE.toString(),
DeviceIndexFeatureProvider.INDEX_LANGUAGE);
- JobScheduler jobScheduler = mock(JobScheduler.class);
when(mProvider.isIndexingEnabled()).thenReturn(true);
- when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler);
mProvider.updateIndex(mActivity, false);
- verify(jobScheduler).schedule(any());
+ 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
DeviceIndexFeatureProvider.setIndexState(mActivity);
Settings.Global.putString(mActivity.getContentResolver(),
DeviceIndexFeatureProvider.INDEX_LANGUAGE, "new language");
- JobScheduler jobScheduler = mock(JobScheduler.class);
+
when(mProvider.isIndexingEnabled()).thenReturn(true);
- when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler);
mProvider.updateIndex(mActivity, false);
- verify(jobScheduler).schedule(any());
+ verify(mJobScheduler).schedule(any());
}
@Test
// Same build and same language
DeviceIndexFeatureProvider.setIndexState(mActivity);
- final JobScheduler jobScheduler = mock(JobScheduler.class);
- when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler);
-
mProvider.updateIndex(mActivity, false);
- verify(jobScheduler, never()).schedule(any());
+ verify(mJobScheduler, never()).schedule(any());
}
}