116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalpackage com.android.launcher3;
216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.annotation.TargetApi;
416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.appwidget.AppWidgetHost;
516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.ComponentName;
616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.ContentResolver;
716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.ContentValues;
816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.pm.PackageInstaller;
916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.pm.PackageInstaller.SessionParams;
1016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.pm.PackageManager;
1116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.database.Cursor;
1216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.os.Build;
1316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.os.Bundle;
1416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.support.test.uiautomator.UiSelector;
159345ebfc5c6e555938a153262fcd4243616183a6Hyunyoung Songimport android.test.suitebuilder.annotation.LargeTest;
1616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
1716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport com.android.launcher3.compat.AppWidgetManagerCompat;
1816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport com.android.launcher3.compat.PackageInstallerCompat;
196d02c7a0337d37e5b1c596a4acec0c292a9b7f93Sunny Goyalimport com.android.launcher3.ui.LauncherInstrumentationTestCase;
2016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport com.android.launcher3.util.ManagedProfileHeuristic;
2116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport com.android.launcher3.widget.PendingAddWidgetInfo;
2216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport com.android.launcher3.widget.WidgetHostViewLoader;
2316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
2416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport java.util.Set;
2516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport java.util.concurrent.Callable;
2616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport java.util.concurrent.CountDownLatch;
2716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport java.util.concurrent.TimeUnit;
2816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
2916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal/**
3016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal * Tests for bind widget flow.
3116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal *
3216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal * Note running these tests will clear the workspace on the device.
3316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal */
349345ebfc5c6e555938a153262fcd4243616183a6Hyunyoung Song@LargeTest
3516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal@TargetApi(Build.VERSION_CODES.LOLLIPOP)
366d02c7a0337d37e5b1c596a4acec0c292a9b7f93Sunny Goyalpublic class BindWidgetTest extends LauncherInstrumentationTestCase {
3716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
3816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private ContentResolver mResolver;
3916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private AppWidgetManagerCompat mWidgetManager;
4016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
4116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    // Objects created during test, which should be cleaned up in the end.
4216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private Cursor mCursor;
4316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    // App install session id.
4416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private int mSessionId = -1;
4516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
4616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    @Override
4716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    protected void setUp() throws Exception {
4816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        super.setUp();
4916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
5016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mResolver = mTargetContext.getContentResolver();
5116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mWidgetManager = AppWidgetManagerCompat.getInstance(mTargetContext);
526d02c7a0337d37e5b1c596a4acec0c292a9b7f93Sunny Goyal        grantWidgetPermission();
5316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
5416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Clear all existing data
5516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
5616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
5716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
5816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
5916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    @Override
6016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    protected void tearDown() throws Exception {
6116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        super.tearDown();
6216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        if (mCursor != null) {
6316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            mCursor.close();
6416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
6516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
6616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        if (mSessionId > -1) {
6716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
6816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
6916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
7016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
7116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testBindNormalWidget_withConfig() {
7216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(true);
7316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, true);
7416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
7516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label);
7616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
7716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
7816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testBindNormalWidget_withoutConfig() {
7916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
8016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, true);
8116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
8216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label);
8316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
8416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
8516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testUnboundWidget_removed() throws Exception {
8616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
8716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, false);
887eab3cc374aeaaa6e305a3f583901da9844dfe08Sunny Goyal        item.appWidgetId = -33;
8916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
9016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Since there is no widget to verify, just wait until the workspace is ready.
9116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, Workspace.class, null);
9216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
9316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
9416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Item deleted from db
9516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
9616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
9716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(0, mCursor.getCount());
9816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
9916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // The view does not exist
10016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertFalse(mDevice.findObject(new UiSelector().description(info.label)).exists());
10116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
10216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
10316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_autoRestored() {
10416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // A non-restored widget with no config screen gets restored automatically.
10516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
10616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
10716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Do not bind the widget
10816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, false);
10916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID;
11016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
11116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label);
11216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
11316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
11416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_withConfigScreen() throws Exception {
11516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // A non-restored widget with config screen get bound and shows a 'Click to setup' UI.
11616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(true);
11716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
11816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Do not bind the widget
11916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, false);
12016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID;
12116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
12216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, PendingAppWidgetHostView.class, null);
12316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
12416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Item deleted from db
12516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
12616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
12716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor.moveToNext();
12816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
12916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Widget has a valid Id now.
13016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(0, mCursor.getInt(mCursor.getColumnIndex(LauncherSettings.Favorites.RESTORED))
13116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
13216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertNotNull(mWidgetManager.getAppWidgetInfo(mCursor.getInt(mCursor.getColumnIndex(
13316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                LauncherSettings.Favorites.APPWIDGET_ID))));
13416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
13516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
13616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_notRestored_removed() throws Exception {
13716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = getInvalidWidgetInfo();
13816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID
13916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                | LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
14016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
14116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, Workspace.class, null);
14216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // The view does not exist
14316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertFalse(mDevice.findObject(
14416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                new UiSelector().className(PendingAppWidgetHostView.class)).exists());
14516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
14616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Item deleted from db
14716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
14816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
14916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(0, mCursor.getCount());
15016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
15116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
15216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_notRestored_brokenInstall() throws Exception {
15316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // A widget which is was being installed once, even if its not being
15416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // installed at the moment is not removed.
15516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = getInvalidWidgetInfo();
15616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID
15716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                | LauncherAppWidgetInfo.FLAG_RESTORE_STARTED
15816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                | LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
15916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
16016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, PendingAppWidgetHostView.class, null);
16116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Verify item still exists in db
16216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
16316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
16416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
16516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(1, mCursor.getCount());
16616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
16716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Widget still has an invalid id.
16816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor.moveToNext();
16916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID,
17016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                mCursor.getInt(mCursor.getColumnIndex(LauncherSettings.Favorites.RESTORED))
17116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                        & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
17216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
17316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
17416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_notRestored_activeInstall() throws Exception {
17516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // A widget which is being installed is not removed
17616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = getInvalidWidgetInfo();
17716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID
17816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                | LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
17916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
18016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Create an active installer session
18116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
18216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        params.setAppPackageName(item.providerName.getPackageName());
18316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        PackageInstaller installer = mTargetContext.getPackageManager().getPackageInstaller();
18416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mSessionId = installer.createSession(params);
18516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
18616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, PendingAppWidgetHostView.class, null);
18716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Verify item still exists in db
18816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
18916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
19016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
19116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(1, mCursor.getCount());
19216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
19316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Widget still has an invalid id.
19416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor.moveToNext();
19516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID,
19616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                mCursor.getInt(mCursor.getColumnIndex(LauncherSettings.Favorites.RESTORED))
19716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                        & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
19816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
19916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
20016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    /**
20116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * Adds {@param item} on the homescreen on the 0th screen at 0,0, and verifies that the
20216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * widget class is displayed on the homescreen.
20316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * @param widgetClass the View class which is displayed on the homescreen
20416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * @param desc the content description of the view or null.
20516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     */
20616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private void setupAndVerifyContents(
20716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            LauncherAppWidgetInfo item, Class<?> widgetClass, String desc) {
208da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        long screenId = Workspace.FIRST_SCREEN_ID;
209da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        // Update the screen id counter for the provider.
210da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_NEW_SCREEN_ID);
211da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal
212da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        if (screenId > Workspace.FIRST_SCREEN_ID) {
213da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal            screenId = Workspace.FIRST_SCREEN_ID;
214da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        }
21516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        ContentValues v = new ContentValues();
21616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
21716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, 0);
21816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mResolver.insert(LauncherSettings.WorkspaceScreens.CONTENT_URI, v);
21916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
22016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Insert the item
22116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        v = new ContentValues();
22216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.id = LauncherSettings.Settings.call(
22316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                mResolver, LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
22416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                .getLong(LauncherSettings.Settings.EXTRA_VALUE);
22516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.screenId = screenId;
22616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.onAddToDatabase(mTargetContext, v);
22716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        v.put(LauncherSettings.Favorites._ID, item.id);
22816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mResolver.insert(LauncherSettings.Favorites.CONTENT_URI, v);
22916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
23016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Reset loader
23116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        try {
23216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            runTestOnUiThread(new Runnable() {
23316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                @Override
23416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                public void run() {
2357eab3cc374aeaaa6e305a3f583901da9844dfe08Sunny Goyal                    LauncherClings.markFirstRunClingDismissed(mTargetContext);
23616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                    ManagedProfileHeuristic.markExistingUsersForNoFolderCreation(mTargetContext);
23716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                    LauncherAppState.getInstance().getModel().resetLoadedState(true, true);
23816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                }
23916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            });
24016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        } catch (Throwable t) {
24116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            throw new IllegalArgumentException(t);
24216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
24316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Launch the home activity
2446d02c7a0337d37e5b1c596a4acec0c292a9b7f93Sunny Goyal        startLauncher();
24516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Verify UI
24616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName())
24716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                .className(widgetClass);
24816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        if (desc != null) {
24916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            selector = selector.description(desc);
25016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
2516d02c7a0337d37e5b1c596a4acec0c292a9b7f93Sunny Goyal        assertTrue(mDevice.findObject(selector).waitForExists(DEFAULT_UI_TIMEOUT));
25216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
25316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
25416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    /**
25516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * Creates a LauncherAppWidgetInfo corresponding to {@param info}
25616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * @param bindWidget if true the info is bound and a valid widgetId is assigned to
25716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     *                   the LauncherAppWidgetInfo
25816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     */
25916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private LauncherAppWidgetInfo createWidgetInfo(
26016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            LauncherAppWidgetProviderInfo info, boolean bindWidget) {
26116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = new LauncherAppWidgetInfo(
26216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                LauncherAppWidgetInfo.NO_ID, info.provider);
26316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.spanX = info.minSpanX;
26416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.spanY = info.minSpanY;
26516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.minSpanX = info.minSpanX;
26616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.minSpanY = info.minSpanY;
26716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.user = mWidgetManager.getUser(info);
26816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.cellX = 0;
269da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        item.cellY = 1;
27016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
27116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
27216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        if (bindWidget) {
27316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(mTargetContext, info);
27416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pendingInfo.spanX = item.spanX;
27516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pendingInfo.spanY = item.spanY;
27616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pendingInfo.minSpanX = item.minSpanX;
27716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pendingInfo.minSpanY = item.minSpanY;
27816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(mTargetContext, pendingInfo);
27916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
28016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            AppWidgetHost host = new AppWidgetHost(mTargetContext, Launcher.APPWIDGET_HOST_ID);
28116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            int widgetId = host.allocateAppWidgetId();
28216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            if (!mWidgetManager.bindAppWidgetIdIfAllowed(widgetId, info, options)) {
28316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                host.deleteAppWidgetId(widgetId);
28416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                throw new IllegalArgumentException("Unable to bind widget id");
28516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            }
28616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            item.appWidgetId = widgetId;
28716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
28816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        return item;
28916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
29016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
29116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    /**
29216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * Returns a LauncherAppWidgetInfo with package name which is not present on the device
29316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     */
29416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private LauncherAppWidgetInfo getInvalidWidgetInfo() {
29516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        String invalidPackage = "com.invalidpackage";
29616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        int count = 0;
29716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        String pkg = invalidPackage;
29816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
29916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        Set<String> activePackage = getOnUiThread(new Callable<Set<String>>() {
30016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            @Override
30116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            public Set<String> call() throws Exception {
30216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                return PackageInstallerCompat.getInstance(mTargetContext)
30316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                        .updateAndGetActiveSessionCache().keySet();
30416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            }
30516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        });
30616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        while(true) {
30716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            try {
30816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                mTargetContext.getPackageManager().getPackageInfo(
30916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                        pkg, PackageManager.GET_UNINSTALLED_PACKAGES);
31016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            } catch (Exception e) {
31116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                if (!activePackage.contains(pkg)) {
31216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                    break;
31316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                }
31416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            }
31516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pkg = invalidPackage + count;
31616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            count ++;
31716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
31816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = new LauncherAppWidgetInfo(10,
31916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                new ComponentName(pkg, "com.test.widgetprovider"));
32016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.spanX = 2;
32116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.spanY = 2;
32216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.minSpanX = 2;
32316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.minSpanY = 2;
32416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.cellX = 0;
325da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        item.cellY = 1;
32616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
32716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        return item;
32816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
32916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
33016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    /**
33116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * Blocks the current thread until all the jobs in the main worker thread are complete.
33216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     */
33316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private void waitUntilLoaderIdle() throws InterruptedException {
33416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        final CountDownLatch latch = new CountDownLatch(1);
33516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherModel.sWorker.post(new Runnable() {
33616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            @Override
33716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            public void run() {
33816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                latch.countDown();
33916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            }
34016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        });
34116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertTrue(latch.await(5, TimeUnit.SECONDS));
34216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
34316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal}
344