Loading src/com/android/settings/shortcut/CreateShortcut.java +40 −18 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; Loading @@ -33,6 +34,7 @@ import android.graphics.drawable.Icon; import android.graphics.drawable.LayerDrawable; import android.net.ConnectivityManager; import android.os.AsyncTask; import android.util.Log; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; Loading @@ -52,6 +54,7 @@ import androidx.annotation.VisibleForTesting; public class CreateShortcut extends LauncherActivity { private static final String TAG = "CreateShortcut"; @VisibleForTesting static final String SHORTCUT_ID_PREFIX = "component-shortcut-"; Loading @@ -76,11 +79,12 @@ public class CreateShortcut extends LauncherActivity { ShortcutManager sm = getSystemService(ShortcutManager.class); ActivityInfo activityInfo = resolveInfo.activityInfo; Icon maskableIcon = activityInfo.icon != 0 ? Icon.createWithAdaptiveBitmap( createIcon(activityInfo.icon, Icon maskableIcon = activityInfo.icon != 0 && activityInfo.applicationInfo != null ? Icon.createWithAdaptiveBitmap( createIcon(activityInfo.applicationInfo, activityInfo.icon, R.layout.shortcut_badge_maskable, getResources().getDimensionPixelSize(R.dimen.shortcut_size_maskable))) : Icon.createWithResource(this, R.drawable.ic_launcher_settings); getResources().getDimensionPixelSize(R.dimen.shortcut_size_maskable))) : Icon.createWithResource(this, R.drawable.ic_launcher_settings); String shortcutId = SHORTCUT_ID_PREFIX + shortcutIntent.getComponent().flattenToShortString(); ShortcutInfo info = new ShortcutInfo.Builder(this, shortcutId) Loading @@ -98,7 +102,9 @@ public class CreateShortcut extends LauncherActivity { intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label); if (activityInfo.icon != 0) { intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(activityInfo.icon, intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon( activityInfo.applicationInfo, activityInfo.icon, R.layout.shortcut_badge, getResources().getDimensionPixelSize(R.dimen.shortcut_size))); } Loading @@ -114,20 +120,29 @@ public class CreateShortcut extends LauncherActivity { info.activityInfo.name); } private Bitmap createIcon(int resource, int layoutRes, int size) { Context context = new ContextThemeWrapper(this, android.R.style.Theme_Material); View view = LayoutInflater.from(context).inflate(layoutRes, null); Drawable iconDrawable = getDrawable(resource); private Bitmap createIcon(ApplicationInfo app, int resource, int layoutRes, int size) { final Context context = new ContextThemeWrapper(this, android.R.style.Theme_Material); final View view = LayoutInflater.from(context).inflate(layoutRes, null); final int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); view.measure(spec, spec); final Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Config.ARGB_8888); final Canvas canvas = new Canvas(bitmap); Drawable iconDrawable = null; try { iconDrawable = getPackageManager().getResourcesForApplication(app).getDrawable(resource); if (iconDrawable instanceof LayerDrawable) { iconDrawable = ((LayerDrawable) iconDrawable).getDrawable(1); } ((ImageView) view.findViewById(android.R.id.icon)).setImageDrawable(iconDrawable); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Cannot load icon from app " + app + ", returning a default icon"); Icon icon = Icon.createWithResource(this, R.drawable.ic_launcher_settings); ((ImageView) view.findViewById(android.R.id.icon)).setImageIcon(icon); } int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); view.measure(spec, spec); Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); view.draw(canvas); return bitmap; Loading @@ -147,12 +162,15 @@ public class CreateShortcut extends LauncherActivity { * Perform query on package manager for list items. The default * implementation queries for activities. */ @Override protected List<ResolveInfo> onQueryPackageManager(Intent queryIntent) { List<ResolveInfo> activities = getPackageManager().queryIntentActivities(queryIntent, PackageManager.GET_META_DATA); final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); if (activities == null) return null; if (activities == null) { return null; } for (int i = activities.size() - 1; i >= 0; i--) { ResolveInfo info = activities.get(i); if (info.activityInfo.name.endsWith(TetherSettingsActivity.class.getSimpleName())) { Loading @@ -160,6 +178,10 @@ public class CreateShortcut extends LauncherActivity { activities.remove(i); } } if (!info.activityInfo.applicationInfo.isSystemApp()) { Log.d(TAG, "Skipping non-system app: " + info.activityInfo); activities.remove(i); } } return activities; } Loading tests/unit/src/com/android/settings/shortcut/CreateShortcutTest.java→tests/robotests/src/com/android/settings/shortcut/CreateShortcutTest.java +179 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * 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. Loading @@ -16,33 +16,29 @@ package com.android.settings.shortcut; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; 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.Instrumentation; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; import android.support.test.InstrumentationRegistry; import android.support.test.espresso.matcher.ViewMatchers; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import com.android.settings.R; import com.android.settings.Settings; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowConnectivityManager; import org.junit.Before; import org.junit.Test; Loading @@ -51,6 +47,11 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowPackageManager; import java.util.Arrays; import java.util.List; Loading @@ -58,80 +59,110 @@ import java.util.List; /** * Tests for {@link CreateShortcutTest} */ @RunWith(AndroidJUnit4.class) @SmallTest @RunWith(SettingsRobolectricTestRunner.class) @Config(shadows = ShadowConnectivityManager.class) public class CreateShortcutTest { private static final String SHORTCUT_ID_PREFIX = CreateShortcut.SHORTCUT_ID_PREFIX; private Instrumentation mInstrumentation; private Context mContext; private ShadowConnectivityManager mShadowConnectivityManager; private ShadowPackageManager mPackageManager; @Mock ShortcutManager mShortcutManager; private ShortcutManager mShortcutManager; @Captor ArgumentCaptor<List<ShortcutInfo>> mListCaptor; private ArgumentCaptor<List<ShortcutInfo>> mListCaptor; @Before public void setup() { MockitoAnnotations.initMocks(this); mInstrumentation = InstrumentationRegistry.getInstrumentation(); mContext = mInstrumentation.getTargetContext(); } @Test public void test_layoutDoesNotHaveCancelButton() { mInstrumentation.startActivitySync(new Intent(Intent.ACTION_CREATE_SHORTCUT) .setClassName(mContext, CreateShortcut.class.getName()) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); onView(ViewMatchers.withText(R.string.cancel)).check(doesNotExist()); mContext = RuntimeEnvironment.application; mPackageManager = Shadow.extract(mContext.getPackageManager()); mShadowConnectivityManager = ShadowConnectivityManager.getShadow(); mShadowConnectivityManager.setTetheringSupported(true); } @Test public void createResultIntent() { CreateShortcut orgActivity = (CreateShortcut) mInstrumentation.startActivitySync( new Intent(Intent.ACTION_CREATE_SHORTCUT) .setClassName(mContext, CreateShortcut.class.getName()) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); CreateShortcut orgActivity = Robolectric.setupActivity(CreateShortcut.class); CreateShortcut activity = spy(orgActivity); doReturn(mShortcutManager).when(activity).getSystemService(eq(Context.SHORTCUT_SERVICE)); when(mShortcutManager.createShortcutResultIntent(any(ShortcutInfo.class))) .thenReturn(new Intent().putExtra("d1", "d2")); Intent intent = CreateShortcut.getBaseIntent() final Intent intent = CreateShortcut.getBaseIntent() .setClass(activity, Settings.ManageApplicationsActivity.class); ResolveInfo ri = activity.getPackageManager().resolveActivity(intent, 0); Intent result = activity.createResultIntent(intent, ri, "dummy"); assertEquals("d2", result.getStringExtra("d1")); assertNotNull(result.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT)); final ResolveInfo ri = activity.getPackageManager().resolveActivity(intent, 0); final Intent result = activity.createResultIntent(intent, ri, "dummy"); assertThat(result.getStringExtra("d1")).isEqualTo("d2"); assertThat((Object) result.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT)).isNotNull(); ArgumentCaptor<ShortcutInfo> infoCaptor = ArgumentCaptor.forClass(ShortcutInfo.class); verify(mShortcutManager, times(1)) .createShortcutResultIntent(infoCaptor.capture()); String expectedId = SHORTCUT_ID_PREFIX + intent.getComponent().flattenToShortString(); assertEquals(expectedId, infoCaptor.getValue().getId()); assertThat(infoCaptor.getValue().getId()) .isEqualTo(SHORTCUT_ID_PREFIX + intent.getComponent().flattenToShortString()); } @Test public void shortcutsUpdateTask() { mContext = spy(new ContextWrapper(mInstrumentation.getTargetContext())); mContext = spy(RuntimeEnvironment.application); doReturn(mShortcutManager).when(mContext).getSystemService(eq(Context.SHORTCUT_SERVICE)); List<ShortcutInfo> pinnedShortcuts = Arrays.asList( makeShortcut("d1"), makeShortcut("d2"), final Intent shortcut1 = CreateShortcut.getBaseIntent().setComponent( new ComponentName(mContext, Settings.ManageApplicationsActivity.class)); final ResolveInfo ri1 = mock(ResolveInfo.class); final Intent shortcut2 = CreateShortcut.getBaseIntent().setComponent( new ComponentName(mContext, Settings.SoundSettingsActivity.class)); final ResolveInfo ri2 = mock(ResolveInfo.class); when(ri1.loadLabel(any(PackageManager.class))).thenReturn("label1"); when(ri2.loadLabel(any(PackageManager.class))).thenReturn("label2"); mPackageManager.addResolveInfoForIntent(shortcut1, ri1); mPackageManager.addResolveInfoForIntent(shortcut2, ri2); final List<ShortcutInfo> pinnedShortcuts = Arrays.asList( makeShortcut("d1"), makeShortcut("d2"), makeShortcut(Settings.ManageApplicationsActivity.class), makeShortcut("d3"), makeShortcut(Settings.SoundSettingsActivity.class)); when(mShortcutManager.getPinnedShortcuts()).thenReturn(pinnedShortcuts); new CreateShortcut.ShortcutsUpdateTask(mContext).doInBackground(); verify(mShortcutManager, times(1)).updateShortcuts(mListCaptor.capture()); List<ShortcutInfo> updates = mListCaptor.getValue(); assertEquals(2, updates.size()); assertEquals(pinnedShortcuts.get(2).getId(), updates.get(0).getId()); assertEquals(pinnedShortcuts.get(4).getId(), updates.get(1).getId()); final List<ShortcutInfo> updates = mListCaptor.getValue(); assertThat(updates).hasSize(2); assertThat(pinnedShortcuts.get(2).getId()).isEqualTo(updates.get(0).getId()); assertThat(pinnedShortcuts.get(4).getId()).isEqualTo(updates.get(1).getId()); } @Test public void queryActivities_shouldOnlyIncludeSystemApp() { final ResolveInfo ri1 = new ResolveInfo(); ri1.activityInfo = new ActivityInfo(); ri1.activityInfo.name = "activity1"; ri1.activityInfo.applicationInfo = new ApplicationInfo(); ri1.activityInfo.applicationInfo.flags = 0; final ResolveInfo ri2 = new ResolveInfo(); ri2.activityInfo = new ActivityInfo(); ri2.activityInfo.name = "activity2"; ri2.activityInfo.applicationInfo = new ApplicationInfo(); ri2.activityInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; mPackageManager.addResolveInfoForIntent(CreateShortcut.getBaseIntent(), Arrays.asList(ri1, ri2)); TestClass orgActivity = Robolectric.setupActivity(TestClass.class); TestClass activity = spy(orgActivity); List<ResolveInfo> info = activity.onQueryPackageManager(CreateShortcut.getBaseIntent()); assertThat(info).hasSize(1); assertThat(info.get(0)).isEqualTo(ri2); } private ShortcutInfo makeShortcut(Class<?> className) { Loading @@ -142,4 +173,7 @@ public class CreateShortcutTest { private ShortcutInfo makeShortcut(String id) { return new ShortcutInfo.Builder(mContext, id).build(); } private static class TestClass extends CreateShortcut { } } tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java +7 −0 Original line number Diff line number Diff line Loading @@ -19,8 +19,10 @@ package com.android.settings.testutils.shadow; import android.net.ConnectivityManager; import android.util.SparseBooleanArray; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadow.api.Shadow; @Implements(value = ConnectivityManager.class, inheritImplementationMethods = true) public class ShadowConnectivityManager extends org.robolectric.shadows.ShadowConnectivityManager { Loading @@ -45,4 +47,9 @@ public class ShadowConnectivityManager extends org.robolectric.shadows.ShadowCon public boolean isTetheringSupported() { return mTetheringSupported; } public static ShadowConnectivityManager getShadow() { return Shadow.extract( RuntimeEnvironment.application.getSystemService(ConnectivityManager.class)); } } Loading
src/com/android/settings/shortcut/CreateShortcut.java +40 −18 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; Loading @@ -33,6 +34,7 @@ import android.graphics.drawable.Icon; import android.graphics.drawable.LayerDrawable; import android.net.ConnectivityManager; import android.os.AsyncTask; import android.util.Log; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; Loading @@ -52,6 +54,7 @@ import androidx.annotation.VisibleForTesting; public class CreateShortcut extends LauncherActivity { private static final String TAG = "CreateShortcut"; @VisibleForTesting static final String SHORTCUT_ID_PREFIX = "component-shortcut-"; Loading @@ -76,11 +79,12 @@ public class CreateShortcut extends LauncherActivity { ShortcutManager sm = getSystemService(ShortcutManager.class); ActivityInfo activityInfo = resolveInfo.activityInfo; Icon maskableIcon = activityInfo.icon != 0 ? Icon.createWithAdaptiveBitmap( createIcon(activityInfo.icon, Icon maskableIcon = activityInfo.icon != 0 && activityInfo.applicationInfo != null ? Icon.createWithAdaptiveBitmap( createIcon(activityInfo.applicationInfo, activityInfo.icon, R.layout.shortcut_badge_maskable, getResources().getDimensionPixelSize(R.dimen.shortcut_size_maskable))) : Icon.createWithResource(this, R.drawable.ic_launcher_settings); getResources().getDimensionPixelSize(R.dimen.shortcut_size_maskable))) : Icon.createWithResource(this, R.drawable.ic_launcher_settings); String shortcutId = SHORTCUT_ID_PREFIX + shortcutIntent.getComponent().flattenToShortString(); ShortcutInfo info = new ShortcutInfo.Builder(this, shortcutId) Loading @@ -98,7 +102,9 @@ public class CreateShortcut extends LauncherActivity { intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label); if (activityInfo.icon != 0) { intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(activityInfo.icon, intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon( activityInfo.applicationInfo, activityInfo.icon, R.layout.shortcut_badge, getResources().getDimensionPixelSize(R.dimen.shortcut_size))); } Loading @@ -114,20 +120,29 @@ public class CreateShortcut extends LauncherActivity { info.activityInfo.name); } private Bitmap createIcon(int resource, int layoutRes, int size) { Context context = new ContextThemeWrapper(this, android.R.style.Theme_Material); View view = LayoutInflater.from(context).inflate(layoutRes, null); Drawable iconDrawable = getDrawable(resource); private Bitmap createIcon(ApplicationInfo app, int resource, int layoutRes, int size) { final Context context = new ContextThemeWrapper(this, android.R.style.Theme_Material); final View view = LayoutInflater.from(context).inflate(layoutRes, null); final int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); view.measure(spec, spec); final Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Config.ARGB_8888); final Canvas canvas = new Canvas(bitmap); Drawable iconDrawable = null; try { iconDrawable = getPackageManager().getResourcesForApplication(app).getDrawable(resource); if (iconDrawable instanceof LayerDrawable) { iconDrawable = ((LayerDrawable) iconDrawable).getDrawable(1); } ((ImageView) view.findViewById(android.R.id.icon)).setImageDrawable(iconDrawable); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Cannot load icon from app " + app + ", returning a default icon"); Icon icon = Icon.createWithResource(this, R.drawable.ic_launcher_settings); ((ImageView) view.findViewById(android.R.id.icon)).setImageIcon(icon); } int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); view.measure(spec, spec); Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); view.draw(canvas); return bitmap; Loading @@ -147,12 +162,15 @@ public class CreateShortcut extends LauncherActivity { * Perform query on package manager for list items. The default * implementation queries for activities. */ @Override protected List<ResolveInfo> onQueryPackageManager(Intent queryIntent) { List<ResolveInfo> activities = getPackageManager().queryIntentActivities(queryIntent, PackageManager.GET_META_DATA); final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); if (activities == null) return null; if (activities == null) { return null; } for (int i = activities.size() - 1; i >= 0; i--) { ResolveInfo info = activities.get(i); if (info.activityInfo.name.endsWith(TetherSettingsActivity.class.getSimpleName())) { Loading @@ -160,6 +178,10 @@ public class CreateShortcut extends LauncherActivity { activities.remove(i); } } if (!info.activityInfo.applicationInfo.isSystemApp()) { Log.d(TAG, "Skipping non-system app: " + info.activityInfo); activities.remove(i); } } return activities; } Loading
tests/unit/src/com/android/settings/shortcut/CreateShortcutTest.java→tests/robotests/src/com/android/settings/shortcut/CreateShortcutTest.java +179 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * 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. Loading @@ -16,33 +16,29 @@ package com.android.settings.shortcut; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; 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.Instrumentation; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; import android.support.test.InstrumentationRegistry; import android.support.test.espresso.matcher.ViewMatchers; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import com.android.settings.R; import com.android.settings.Settings; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowConnectivityManager; import org.junit.Before; import org.junit.Test; Loading @@ -51,6 +47,11 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowPackageManager; import java.util.Arrays; import java.util.List; Loading @@ -58,80 +59,110 @@ import java.util.List; /** * Tests for {@link CreateShortcutTest} */ @RunWith(AndroidJUnit4.class) @SmallTest @RunWith(SettingsRobolectricTestRunner.class) @Config(shadows = ShadowConnectivityManager.class) public class CreateShortcutTest { private static final String SHORTCUT_ID_PREFIX = CreateShortcut.SHORTCUT_ID_PREFIX; private Instrumentation mInstrumentation; private Context mContext; private ShadowConnectivityManager mShadowConnectivityManager; private ShadowPackageManager mPackageManager; @Mock ShortcutManager mShortcutManager; private ShortcutManager mShortcutManager; @Captor ArgumentCaptor<List<ShortcutInfo>> mListCaptor; private ArgumentCaptor<List<ShortcutInfo>> mListCaptor; @Before public void setup() { MockitoAnnotations.initMocks(this); mInstrumentation = InstrumentationRegistry.getInstrumentation(); mContext = mInstrumentation.getTargetContext(); } @Test public void test_layoutDoesNotHaveCancelButton() { mInstrumentation.startActivitySync(new Intent(Intent.ACTION_CREATE_SHORTCUT) .setClassName(mContext, CreateShortcut.class.getName()) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); onView(ViewMatchers.withText(R.string.cancel)).check(doesNotExist()); mContext = RuntimeEnvironment.application; mPackageManager = Shadow.extract(mContext.getPackageManager()); mShadowConnectivityManager = ShadowConnectivityManager.getShadow(); mShadowConnectivityManager.setTetheringSupported(true); } @Test public void createResultIntent() { CreateShortcut orgActivity = (CreateShortcut) mInstrumentation.startActivitySync( new Intent(Intent.ACTION_CREATE_SHORTCUT) .setClassName(mContext, CreateShortcut.class.getName()) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); CreateShortcut orgActivity = Robolectric.setupActivity(CreateShortcut.class); CreateShortcut activity = spy(orgActivity); doReturn(mShortcutManager).when(activity).getSystemService(eq(Context.SHORTCUT_SERVICE)); when(mShortcutManager.createShortcutResultIntent(any(ShortcutInfo.class))) .thenReturn(new Intent().putExtra("d1", "d2")); Intent intent = CreateShortcut.getBaseIntent() final Intent intent = CreateShortcut.getBaseIntent() .setClass(activity, Settings.ManageApplicationsActivity.class); ResolveInfo ri = activity.getPackageManager().resolveActivity(intent, 0); Intent result = activity.createResultIntent(intent, ri, "dummy"); assertEquals("d2", result.getStringExtra("d1")); assertNotNull(result.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT)); final ResolveInfo ri = activity.getPackageManager().resolveActivity(intent, 0); final Intent result = activity.createResultIntent(intent, ri, "dummy"); assertThat(result.getStringExtra("d1")).isEqualTo("d2"); assertThat((Object) result.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT)).isNotNull(); ArgumentCaptor<ShortcutInfo> infoCaptor = ArgumentCaptor.forClass(ShortcutInfo.class); verify(mShortcutManager, times(1)) .createShortcutResultIntent(infoCaptor.capture()); String expectedId = SHORTCUT_ID_PREFIX + intent.getComponent().flattenToShortString(); assertEquals(expectedId, infoCaptor.getValue().getId()); assertThat(infoCaptor.getValue().getId()) .isEqualTo(SHORTCUT_ID_PREFIX + intent.getComponent().flattenToShortString()); } @Test public void shortcutsUpdateTask() { mContext = spy(new ContextWrapper(mInstrumentation.getTargetContext())); mContext = spy(RuntimeEnvironment.application); doReturn(mShortcutManager).when(mContext).getSystemService(eq(Context.SHORTCUT_SERVICE)); List<ShortcutInfo> pinnedShortcuts = Arrays.asList( makeShortcut("d1"), makeShortcut("d2"), final Intent shortcut1 = CreateShortcut.getBaseIntent().setComponent( new ComponentName(mContext, Settings.ManageApplicationsActivity.class)); final ResolveInfo ri1 = mock(ResolveInfo.class); final Intent shortcut2 = CreateShortcut.getBaseIntent().setComponent( new ComponentName(mContext, Settings.SoundSettingsActivity.class)); final ResolveInfo ri2 = mock(ResolveInfo.class); when(ri1.loadLabel(any(PackageManager.class))).thenReturn("label1"); when(ri2.loadLabel(any(PackageManager.class))).thenReturn("label2"); mPackageManager.addResolveInfoForIntent(shortcut1, ri1); mPackageManager.addResolveInfoForIntent(shortcut2, ri2); final List<ShortcutInfo> pinnedShortcuts = Arrays.asList( makeShortcut("d1"), makeShortcut("d2"), makeShortcut(Settings.ManageApplicationsActivity.class), makeShortcut("d3"), makeShortcut(Settings.SoundSettingsActivity.class)); when(mShortcutManager.getPinnedShortcuts()).thenReturn(pinnedShortcuts); new CreateShortcut.ShortcutsUpdateTask(mContext).doInBackground(); verify(mShortcutManager, times(1)).updateShortcuts(mListCaptor.capture()); List<ShortcutInfo> updates = mListCaptor.getValue(); assertEquals(2, updates.size()); assertEquals(pinnedShortcuts.get(2).getId(), updates.get(0).getId()); assertEquals(pinnedShortcuts.get(4).getId(), updates.get(1).getId()); final List<ShortcutInfo> updates = mListCaptor.getValue(); assertThat(updates).hasSize(2); assertThat(pinnedShortcuts.get(2).getId()).isEqualTo(updates.get(0).getId()); assertThat(pinnedShortcuts.get(4).getId()).isEqualTo(updates.get(1).getId()); } @Test public void queryActivities_shouldOnlyIncludeSystemApp() { final ResolveInfo ri1 = new ResolveInfo(); ri1.activityInfo = new ActivityInfo(); ri1.activityInfo.name = "activity1"; ri1.activityInfo.applicationInfo = new ApplicationInfo(); ri1.activityInfo.applicationInfo.flags = 0; final ResolveInfo ri2 = new ResolveInfo(); ri2.activityInfo = new ActivityInfo(); ri2.activityInfo.name = "activity2"; ri2.activityInfo.applicationInfo = new ApplicationInfo(); ri2.activityInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; mPackageManager.addResolveInfoForIntent(CreateShortcut.getBaseIntent(), Arrays.asList(ri1, ri2)); TestClass orgActivity = Robolectric.setupActivity(TestClass.class); TestClass activity = spy(orgActivity); List<ResolveInfo> info = activity.onQueryPackageManager(CreateShortcut.getBaseIntent()); assertThat(info).hasSize(1); assertThat(info.get(0)).isEqualTo(ri2); } private ShortcutInfo makeShortcut(Class<?> className) { Loading @@ -142,4 +173,7 @@ public class CreateShortcutTest { private ShortcutInfo makeShortcut(String id) { return new ShortcutInfo.Builder(mContext, id).build(); } private static class TestClass extends CreateShortcut { } }
tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java +7 −0 Original line number Diff line number Diff line Loading @@ -19,8 +19,10 @@ package com.android.settings.testutils.shadow; import android.net.ConnectivityManager; import android.util.SparseBooleanArray; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadow.api.Shadow; @Implements(value = ConnectivityManager.class, inheritImplementationMethods = true) public class ShadowConnectivityManager extends org.robolectric.shadows.ShadowConnectivityManager { Loading @@ -45,4 +47,9 @@ public class ShadowConnectivityManager extends org.robolectric.shadows.ShadowCon public boolean isTetheringSupported() { return mTetheringSupported; } public static ShadowConnectivityManager getShadow() { return Shadow.extract( RuntimeEnvironment.application.getSystemService(ConnectivityManager.class)); } }