1658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal/*
2658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * Copyright (C) 2017 The Android Open Source Project
3658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal *
4658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * use this file except in compliance with the License. You may obtain a copy of
6658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * the License at
7658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal *
8658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * http://www.apache.org/licenses/LICENSE-2.0
9658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal *
10658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * Unless required by applicable law or agreed to in writing, software
11658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * License for the specific language governing permissions and limitations under
14658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal * the License.
15658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal */
16658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyalpackage com.android.launcher3.ui.widget;
1716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
1816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.appwidget.AppWidgetHost;
1916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.ComponentName;
2016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.ContentResolver;
2116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.ContentValues;
2216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.pm.PackageInstaller;
2316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.pm.PackageInstaller.SessionParams;
2416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.content.pm.PackageManager;
2516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.database.Cursor;
2616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.os.Bundle;
271d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport android.support.test.filters.LargeTest;
281d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport android.support.test.runner.AndroidJUnit4;
2916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport android.support.test.uiautomator.UiSelector;
3016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
3164a75aa305bdd1ca8f22d2b48dedc5cada8fabc5Sunny Goyalimport com.android.launcher3.LauncherAppWidgetHost;
32658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyalimport com.android.launcher3.LauncherAppWidgetHostView;
33658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyalimport com.android.launcher3.LauncherAppWidgetInfo;
34658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyalimport com.android.launcher3.LauncherAppWidgetProviderInfo;
35658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyalimport com.android.launcher3.LauncherModel;
36658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyalimport com.android.launcher3.LauncherSettings;
37658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyalimport com.android.launcher3.PendingAppWidgetHostView;
38658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyalimport com.android.launcher3.Workspace;
3916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport com.android.launcher3.compat.AppWidgetManagerCompat;
4016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport com.android.launcher3.compat.PackageInstallerCompat;
411d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport com.android.launcher3.ui.AbstractLauncherUiTest;
4232f3dda80240e707ad4467b6b65fb589f539c58eSunny Goyalimport com.android.launcher3.util.ContentWriter;
43b265ba74490d8ded8659db0d63f50c471d793802Sunny Goyalimport com.android.launcher3.util.LooperExecutor;
441d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport com.android.launcher3.util.rule.LauncherActivityRule;
451d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport com.android.launcher3.util.rule.ShellCommandRule;
4616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport com.android.launcher3.widget.PendingAddWidgetInfo;
4716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport com.android.launcher3.widget.WidgetHostViewLoader;
4816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
491d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport org.junit.After;
501d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport org.junit.Before;
511d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport org.junit.Rule;
521d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport org.junit.Test;
531d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport org.junit.runner.RunWith;
541d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal
5516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport java.util.Set;
5616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport java.util.concurrent.Callable;
5716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyalimport java.util.concurrent.TimeUnit;
5816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
591d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport static org.junit.Assert.assertEquals;
601d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport static org.junit.Assert.assertFalse;
611d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport static org.junit.Assert.assertNotNull;
621d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalimport static org.junit.Assert.assertTrue;
631d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal
6416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal/**
6516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal * Tests for bind widget flow.
6616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal *
6716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal * Note running these tests will clear the workspace on the device.
6816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal */
699345ebfc5c6e555938a153262fcd4243616183a6Hyunyoung Song@LargeTest
701d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal@RunWith(AndroidJUnit4.class)
711d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyalpublic class BindWidgetTest extends AbstractLauncherUiTest {
721d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal
731d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
741d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind();
7516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
7616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private ContentResolver mResolver;
7716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private AppWidgetManagerCompat mWidgetManager;
7816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
7916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    // Objects created during test, which should be cleaned up in the end.
8016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private Cursor mCursor;
8116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    // App install session id.
8216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private int mSessionId = -1;
8316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
8416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    @Override
851d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Before
861d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    public void setUp() throws Exception {
8716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        super.setUp();
8816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
8916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mResolver = mTargetContext.getContentResolver();
9016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mWidgetManager = AppWidgetManagerCompat.getInstance(mTargetContext);
9116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
9216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Clear all existing data
9316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
9416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
9516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
9616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
971d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @After
981d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    public void tearDown() throws Exception {
9916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        if (mCursor != null) {
10016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            mCursor.close();
10116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
10216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
10316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        if (mSessionId > -1) {
10416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
10516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
10616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
10716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
1081d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Test
10916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testBindNormalWidget_withConfig() {
11016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(true);
11116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, true);
11216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
11316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label);
11416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
11516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
1161d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Test
11716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testBindNormalWidget_withoutConfig() {
11816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
11916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, true);
12016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
12116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label);
12216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
12316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
1241d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Test
12516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testUnboundWidget_removed() throws Exception {
12616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
12716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, false);
1287eab3cc374aeaaa6e305a3f583901da9844dfe08Sunny Goyal        item.appWidgetId = -33;
12916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
13016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Since there is no widget to verify, just wait until the workspace is ready.
13116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, Workspace.class, null);
13216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
13316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
13416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Item deleted from db
13516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
13616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
13716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(0, mCursor.getCount());
13816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
13916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // The view does not exist
14016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertFalse(mDevice.findObject(new UiSelector().description(info.label)).exists());
14116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
14216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
1431d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Test
14416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_autoRestored() {
14516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // A non-restored widget with no config screen gets restored automatically.
14616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
14716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
14816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Do not bind the widget
14916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, false);
15016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID;
15116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
15216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label);
15316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
15416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
1551d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Test
15616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_withConfigScreen() throws Exception {
15716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // A non-restored widget with config screen get bound and shows a 'Click to setup' UI.
15816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetProviderInfo info = findWidgetProvider(true);
15916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
16016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Do not bind the widget
16116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = createWidgetInfo(info, false);
16216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID;
16316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
16416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, PendingAppWidgetHostView.class, null);
16516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
16616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Item deleted from db
16716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
16816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
16916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor.moveToNext();
17016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
17116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Widget has a valid Id now.
17216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(0, mCursor.getInt(mCursor.getColumnIndex(LauncherSettings.Favorites.RESTORED))
17316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
17416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertNotNull(mWidgetManager.getAppWidgetInfo(mCursor.getInt(mCursor.getColumnIndex(
17516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                LauncherSettings.Favorites.APPWIDGET_ID))));
17616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
17716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
1781d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Test
17916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_notRestored_removed() throws Exception {
18016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = getInvalidWidgetInfo();
18116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID
18216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                | LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
18316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
18416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, Workspace.class, null);
18516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // The view does not exist
18616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertFalse(mDevice.findObject(
18716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                new UiSelector().className(PendingAppWidgetHostView.class)).exists());
18816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
18916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Item deleted from db
19016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
19116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
19216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(0, mCursor.getCount());
19316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
19416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
1951d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Test
19616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_notRestored_brokenInstall() throws Exception {
19716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // A widget which is was being installed once, even if its not being
19816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // installed at the moment is not removed.
19916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = getInvalidWidgetInfo();
20016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID
20116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                | LauncherAppWidgetInfo.FLAG_RESTORE_STARTED
20216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                | LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
20316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
20416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, PendingAppWidgetHostView.class, null);
20516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Verify item still exists in db
20616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
20716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
20816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
20916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(1, mCursor.getCount());
21016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
21116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Widget still has an invalid id.
21216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor.moveToNext();
21316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID,
21416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                mCursor.getInt(mCursor.getColumnIndex(LauncherSettings.Favorites.RESTORED))
21516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                        & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
21616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
21716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
2181d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal    @Test
21916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    public void testPendingWidget_notRestored_activeInstall() throws Exception {
22016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // A widget which is being installed is not removed
22116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = getInvalidWidgetInfo();
22216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID
22316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                | LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
22416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
22516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Create an active installer session
22616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
22716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        params.setAppPackageName(item.providerName.getPackageName());
22816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        PackageInstaller installer = mTargetContext.getPackageManager().getPackageInstaller();
22916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mSessionId = installer.createSession(params);
23016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
23116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        setupAndVerifyContents(item, PendingAppWidgetHostView.class, null);
23216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Verify item still exists in db
23316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        waitUntilLoaderIdle();
23416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
23516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                null, null, null, null, null);
23616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(1, mCursor.getCount());
23716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
23816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Widget still has an invalid id.
23916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mCursor.moveToNext();
24016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        assertEquals(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID,
24116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                mCursor.getInt(mCursor.getColumnIndex(LauncherSettings.Favorites.RESTORED))
24216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                        & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
24316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
24416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
24516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    /**
24616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * Adds {@param item} on the homescreen on the 0th screen at 0,0, and verifies that the
24716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * widget class is displayed on the homescreen.
24816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * @param widgetClass the View class which is displayed on the homescreen
24916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * @param desc the content description of the view or null.
25016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     */
25116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private void setupAndVerifyContents(
25216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            LauncherAppWidgetInfo item, Class<?> widgetClass, String desc) {
253da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        long screenId = Workspace.FIRST_SCREEN_ID;
254da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        // Update the screen id counter for the provider.
255da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_NEW_SCREEN_ID);
256da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal
257da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        if (screenId > Workspace.FIRST_SCREEN_ID) {
258da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal            screenId = Workspace.FIRST_SCREEN_ID;
259da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        }
26016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        ContentValues v = new ContentValues();
26116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
26216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, 0);
26316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        mResolver.insert(LauncherSettings.WorkspaceScreens.CONTENT_URI, v);
26416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
26516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Insert the item
26632f3dda80240e707ad4467b6b65fb589f539c58eSunny Goyal        ContentWriter writer = new ContentWriter(mTargetContext);
26716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.id = LauncherSettings.Settings.call(
26816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                mResolver, LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
26916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                .getLong(LauncherSettings.Settings.EXTRA_VALUE);
27016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.screenId = screenId;
27132f3dda80240e707ad4467b6b65fb589f539c58eSunny Goyal        item.onAddToDatabase(writer);
27232f3dda80240e707ad4467b6b65fb589f539c58eSunny Goyal        writer.put(LauncherSettings.Favorites._ID, item.id);
27387f784c285fdeed9091a4de8b9b44db3eca677d8Sunny Goyal        mResolver.insert(LauncherSettings.Favorites.CONTENT_URI, writer.getValues(mTargetContext));
27487f784c285fdeed9091a4de8b9b44db3eca677d8Sunny Goyal        resetLoaderState();
27587f784c285fdeed9091a4de8b9b44db3eca677d8Sunny Goyal
27616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Launch the home activity
2771d7f45d8f8fafc46f23963e3b43c95a2c2120079Sunny Goyal        mActivityMonitor.startLauncher();
27816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        // Verify UI
27916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName())
28016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                .className(widgetClass);
28116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        if (desc != null) {
28216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            selector = selector.description(desc);
28316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
2846d02c7a0337d37e5b1c596a4acec0c292a9b7f93Sunny Goyal        assertTrue(mDevice.findObject(selector).waitForExists(DEFAULT_UI_TIMEOUT));
28516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
28616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
28716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    /**
28816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * Creates a LauncherAppWidgetInfo corresponding to {@param info}
28916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * @param bindWidget if true the info is bound and a valid widgetId is assigned to
29016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     *                   the LauncherAppWidgetInfo
29116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     */
29216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private LauncherAppWidgetInfo createWidgetInfo(
29316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            LauncherAppWidgetProviderInfo info, boolean bindWidget) {
29416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = new LauncherAppWidgetInfo(
29516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                LauncherAppWidgetInfo.NO_ID, info.provider);
29616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.spanX = info.minSpanX;
29716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.spanY = info.minSpanY;
29816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.minSpanX = info.minSpanX;
29916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.minSpanY = info.minSpanY;
300a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal        item.user = info.getUser();
30116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.cellX = 0;
302da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        item.cellY = 1;
30316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
30416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
30516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        if (bindWidget) {
306a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal            PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(info);
30716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pendingInfo.spanX = item.spanX;
30816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pendingInfo.spanY = item.spanY;
30916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pendingInfo.minSpanX = item.minSpanX;
31016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pendingInfo.minSpanY = item.minSpanY;
31116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(mTargetContext, pendingInfo);
31216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
31364a75aa305bdd1ca8f22d2b48dedc5cada8fabc5Sunny Goyal            AppWidgetHost host = new LauncherAppWidgetHost(mTargetContext);
31416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            int widgetId = host.allocateAppWidgetId();
31516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            if (!mWidgetManager.bindAppWidgetIdIfAllowed(widgetId, info, options)) {
31616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                host.deleteAppWidgetId(widgetId);
31716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                throw new IllegalArgumentException("Unable to bind widget id");
31816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            }
31916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            item.appWidgetId = widgetId;
32016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
32116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        return item;
32216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
32316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
32416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    /**
32516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * Returns a LauncherAppWidgetInfo with package name which is not present on the device
32616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     */
32716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    private LauncherAppWidgetInfo getInvalidWidgetInfo() {
32816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        String invalidPackage = "com.invalidpackage";
32916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        int count = 0;
33016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        String pkg = invalidPackage;
33116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
33216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        Set<String> activePackage = getOnUiThread(new Callable<Set<String>>() {
33316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            @Override
33416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            public Set<String> call() throws Exception {
33516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                return PackageInstallerCompat.getInstance(mTargetContext)
33616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                        .updateAndGetActiveSessionCache().keySet();
33716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            }
33816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        });
33916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        while(true) {
34016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            try {
34116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                mTargetContext.getPackageManager().getPackageInfo(
34216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                        pkg, PackageManager.GET_UNINSTALLED_PACKAGES);
34316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            } catch (Exception e) {
34416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                if (!activePackage.contains(pkg)) {
34516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                    break;
34616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                }
34716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            }
34816466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            pkg = invalidPackage + count;
34916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal            count ++;
35016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        }
35116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        LauncherAppWidgetInfo item = new LauncherAppWidgetInfo(10,
35216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal                new ComponentName(pkg, "com.test.widgetprovider"));
35316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.spanX = 2;
35416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.spanY = 2;
35516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.minSpanX = 2;
35616466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.minSpanY = 2;
35716466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.cellX = 0;
358da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal        item.cellY = 1;
35916466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        item.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
36016466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal        return item;
36116466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
36216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal
36316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    /**
36416466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     * Blocks the current thread until all the jobs in the main worker thread are complete.
36516466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal     */
366658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal    private void waitUntilLoaderIdle() throws Exception {
367b265ba74490d8ded8659db0d63f50c471d793802Sunny Goyal        new LooperExecutor(LauncherModel.getWorkerLooper())
368658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal                .submit(new Runnable() {
369658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal                    @Override
370658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal                    public void run() { }
371658058b960ef029fc70f0f3e131057a6ba0d10e2Sunny Goyal                }).get(DEFAULT_WORKER_TIMEOUT_SECS, TimeUnit.SECONDS);
37216466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal    }
37316466f1bbb935d56c01b10551ead416feb7fc943Sunny Goyal}
374