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