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

Commit 115e1140 authored by Sunny Goyal's avatar Sunny Goyal Committed by Android (Google) Code Review
Browse files

Merge "Updating CreateShortcut activity to use the new ShortcutManager APIs for creating shortcuts"

parents b6143434 9a6b6750
Loading
Loading
Loading
Loading
+77 −14
Original line number Diff line number Diff line
@@ -17,15 +17,21 @@
package com.android.settings;

import android.app.LauncherActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.drawable.Icon;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.support.annotation.VisibleForTesting;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
@@ -35,34 +41,52 @@ import android.widget.ListView;

import com.android.settings.Settings.TetherSettingsActivity;

import java.util.ArrayList;
import java.util.List;

public class CreateShortcut extends LauncherActivity {

    @VisibleForTesting
    static final String SHORTCUT_ID_PREFIX = "component-shortcut-";

    @Override
    protected Intent getTargetIntent() {
        Intent targetIntent = new Intent(Intent.ACTION_MAIN, null);
        targetIntent.addCategory("com.android.settings.SHORTCUT");
        targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return targetIntent;
        return getBaseIntent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent shortcutIntent = intentForPosition(position);
        ListItem item = itemForPosition(position);
        setResult(RESULT_OK, createResultIntent(intentForPosition(position),
                item.resolveInfo, item.label));
        finish();
    }

    protected Intent createResultIntent(Intent shortcutIntent, ResolveInfo resolveInfo,
            CharSequence label) {
        shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        Intent intent = new Intent();

        ActivityInfo activityInfo = resolveInfo.activityInfo;
        Bitmap icon = activityInfo.icon != 0 ? createIcon(activityInfo.icon) : null;

        String shortcutId = SHORTCUT_ID_PREFIX +
                shortcutIntent.getComponent().flattenToShortString();
        ShortcutInfo info = new ShortcutInfo.Builder(this, shortcutId)
                .setShortLabel(label)
                .setIntent(shortcutIntent)
                .setIcon(icon != null ? Icon.createWithBitmap(icon) :
                        Icon.createWithResource(this, R.mipmap.ic_launcher_settings))
                .build();
        Intent intent = getSystemService(ShortcutManager.class).createShortcutResultIntent(info);
        if (intent == null) {
            intent = new Intent();
        }
        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
                Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_launcher_settings));
        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, itemForPosition(position).label);
        ResolveInfo resolveInfo = itemForPosition(position).resolveInfo;
        ActivityInfo activityInfo = resolveInfo.activityInfo;
        if (activityInfo.icon != 0) {
            intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(activityInfo.icon));
        }
        setResult(RESULT_OK, intent);
        finish();
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label);
        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon);
        return intent;
    }

    private Bitmap createIcon(int resource) {
@@ -110,4 +134,43 @@ public class CreateShortcut extends LauncherActivity {
        }
        return activities;
    }

    @VisibleForTesting
    static Intent getBaseIntent() {
        return new Intent(Intent.ACTION_MAIN).addCategory("com.android.settings.SHORTCUT");
    }

    public static class ShortcutsUpdateTask extends AsyncTask<Void, Void, Void> {

        private final Context mContext;

        public ShortcutsUpdateTask(Context context) {
            mContext = context;
        }

        @Override
        public Void doInBackground(Void... params) {
            ShortcutManager sm = mContext.getSystemService(ShortcutManager.class);
            PackageManager pm = mContext.getPackageManager();

            List<ShortcutInfo> updates = new ArrayList<>();
            for (ShortcutInfo info : sm.getPinnedShortcuts()) {
                if (!info.getId().startsWith(SHORTCUT_ID_PREFIX)) {
                    continue;
                }
                ComponentName cn = ComponentName.unflattenFromString(
                        info.getId().substring(SHORTCUT_ID_PREFIX.length()));
                ResolveInfo ri = pm.resolveActivity(getBaseIntent().setComponent(cn), 0);
                if (ri == null) {
                    continue;
                }
                updates.add(new ShortcutInfo.Builder(mContext, info.getId())
                    .setShortLabel(ri.loadLabel(pm)).build());
            }
            if (!updates.isEmpty()) {
                sm.updateShortcuts(updates);
            }
            return null;
        }
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.widget.CompoundButton;
import com.android.internal.app.LocalePicker;
import com.android.internal.app.LocaleStore;

import com.android.settings.CreateShortcut;
import com.android.settings.R;

import java.text.NumberFormat;
@@ -299,6 +300,8 @@ class LocaleDragAndDropAdapter

                LocalePicker.updateLocales(mLocalesToSetNext);
                mLocalesSetLast = mLocalesToSetNext;
                new CreateShortcut.ShortcutsUpdateTask(mContext).execute();

                mLocalesToSetNext = null;

                mNumberFormatter = NumberFormat.getNumberInstance(Locale.getDefault());
+108 −7
Original line number Diff line number Diff line
@@ -16,29 +16,130 @@

package com.android.settings;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
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.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import java.util.Arrays;
import java.util.List;

/**
 * Tests for {@link CreateShortcutTest}
 *
 m SettingsTests &&
 adb install \
 -r -g  ${ANDROID_PRODUCT_OUT}/data/app/SettingsTests/SettingsTests.apk &&
 adb shell am instrument -e class com.android.settings.CreateShortcutTest \
 -w com.android.settings.tests/android.support.test.runner.AndroidJUnitRunner
 */
@RunWith(AndroidJUnit4.class)
@SmallTest
public class CreateShortcutTest {

    private static final String SHORTCUT_ID_PREFIX = CreateShortcut.SHORTCUT_ID_PREFIX;

    private Instrumentation mInstrumentation;
    private Context mContext;

    @Mock ShortcutManager mShortcutManager;
    @Captor ArgumentCaptor<List<ShortcutInfo>> mListCaptor;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        mContext = mInstrumentation.getTargetContext();
    }

    @Test
    public void test_layoutDoesNotHaveCancelButton() {
        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
        instrumentation.startActivitySync(new Intent(Intent.ACTION_CREATE_SHORTCUT)
                .setClassName(instrumentation.getTargetContext(),
                        CreateShortcut.class.getName()));
        mInstrumentation.startActivitySync(new Intent(Intent.ACTION_CREATE_SHORTCUT)
                .setClassName(mContext, CreateShortcut.class.getName()));
        onView(withText(R.string.cancel)).check(doesNotExist());
    }

    @Test
    public void createResultIntent() {
        CreateShortcut orgActivity = (CreateShortcut) mInstrumentation.startActivitySync(
                new Intent(Intent.ACTION_CREATE_SHORTCUT)
                        .setClassName(mContext, CreateShortcut.class.getName()));
        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()
                .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));

        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());
    }

    @Test
    public void shortcutsUpdateTask() {
        mContext = spy(new ContextWrapper(mInstrumentation.getTargetContext()));
        doReturn(mShortcutManager).when(mContext).getSystemService(eq(Context.SHORTCUT_SERVICE));

        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());
    }

    private ShortcutInfo makeShortcut(Class<?> className) {
        ComponentName cn = new ComponentName(mContext, className);
        return makeShortcut(SHORTCUT_ID_PREFIX + cn.flattenToShortString());
    }

    private ShortcutInfo makeShortcut(String id) {
        return new ShortcutInfo.Builder(mContext, id).build();
    }
}