Cleaning up pm SuspendPackagesTest

Removing all tests that are duplicated in CtsSuspendAppsTestCases. The
only remaining tests are testing launcher apps or app-ops. Currently,
these cannot be tested in CTS.

Fixed some bugs in package filtering implementation that broke the
callbacks

Test: atest FrameworksServicesTests:SuspendPackagesTest

Bug: 206578343
Change-Id: I636c1be44bdb175213efa8608fa336c83859f7c9
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 9c11cd4..07f3879 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -1648,14 +1648,12 @@
                             continue;
                         }
                         final String[] filteredPackagesWithoutExtras =
-                                getFilteredPackageNames(packages, cookie);
-                        // If all packages are filtered, skip notifying listener.
-                        if (ArrayUtils.isEmpty(filteredPackagesWithoutExtras)) {
-                            continue;
-                        }
+                                getFilteredPackageNames(packagesNullExtras, cookie);
                         try {
-                            listener.onPackagesSuspended(user, filteredPackagesWithoutExtras,
-                                    /* launcherExtras= */ null);
+                            if (!ArrayUtils.isEmpty(filteredPackagesWithoutExtras)) {
+                                listener.onPackagesSuspended(user, filteredPackagesWithoutExtras,
+                                        /* launcherExtras= */ null);
+                            }
                             for (int idx = 0; idx < packagesWithExtras.size(); idx++) {
                                 Pair<String, Bundle> packageExtraPair = packagesWithExtras.get(idx);
                                 if (!isPackageVisibleToListener(packageExtraPair.first, cookie)) {
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 80f2729..e756124 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -97,6 +97,10 @@
     <uses-permission
         android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
 
+    <queries>
+        <package android:name="com.android.servicestests.apps.suspendtestapp" />
+    </queries>
+
     <!-- Uses API introduced in O (26) -->
     <uses-sdk android:minSdkVersion="1"
          android:targetSdkVersion="26"/>
diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
index 2290ef7..398148f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
@@ -25,23 +25,16 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
 
 import android.app.AppGlobals;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.IPackageManager;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.content.pm.SuspendDialogInfo;
-import android.content.res.Resources;
 import android.os.BaseBundle;
 import android.os.Bundle;
 import android.os.Handler;
@@ -50,13 +43,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.util.Log;
-import android.view.IWindowManager;
-import android.view.WindowManagerGlobal;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.FlakyTest;
@@ -65,7 +51,6 @@
 
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.app.IAppOpsService;
-import com.android.servicestests.apps.suspendtestapp.SuspendTestActivity;
 import com.android.servicestests.apps.suspendtestapp.SuspendTestReceiver;
 
 import org.junit.After;
@@ -76,7 +61,6 @@
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -84,8 +68,6 @@
 @LargeTest
 @FlakyTest
 public class SuspendPackagesTest {
-    private static final String TAG = SuspendPackagesTest.class.getSimpleName();
-    private static final String TEST_APP_LABEL = "Suspend Test App";
     private static final String TEST_APP_PACKAGE_NAME = SuspendTestReceiver.PACKAGE_NAME;
     private static final String[] PACKAGES_TO_SUSPEND = new String[]{TEST_APP_PACKAGE_NAME};
 
@@ -105,75 +87,11 @@
     public static final String EXTRA_RECEIVED_PACKAGE_NAME =
             SuspendPackagesTest.INSTRUMENTATION_PACKAGE + ".extra.RECEIVED_PACKAGE_NAME";
 
-
     private Context mContext;
     private PackageManager mPackageManager;
     private LauncherApps mLauncherApps;
     private Handler mReceiverHandler;
-    private AppCommunicationReceiver mAppCommsReceiver;
     private StubbedCallback mTestCallback;
-    private UiDevice mUiDevice;
-    private ComponentName mDeviceAdminComponent;
-    private boolean mPoSet;
-    private boolean mDoSet;
-
-    private static final class AppCommunicationReceiver extends BroadcastReceiver {
-        private Context context;
-        private boolean registered;
-        private SynchronousQueue<Intent> intentQueue = new SynchronousQueue<>();
-
-        AppCommunicationReceiver(Context context) {
-            this.context = context;
-        }
-
-        void register(Handler handler, String... actions) {
-            registered = true;
-            final IntentFilter intentFilter = new IntentFilter();
-            for (String action : actions) {
-                intentFilter.addAction(action);
-            }
-            context.registerReceiver(this, intentFilter, null, handler);
-        }
-
-        void unregister() {
-            if (registered) {
-                context.unregisterReceiver(this);
-            }
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Log.d(TAG, "AppCommunicationReceiver#onReceive: " + intent.getAction());
-            try {
-                intentQueue.offer(intent, 5, TimeUnit.SECONDS);
-            } catch (InterruptedException ie) {
-                throw new RuntimeException("Receiver thread interrupted", ie);
-            }
-        }
-
-        Intent pollForIntent(long secondsToWait) {
-            if (!registered) {
-                throw new IllegalStateException("Receiver not registered");
-            }
-            final Intent intent;
-            try {
-                intent = intentQueue.poll(secondsToWait, TimeUnit.SECONDS);
-            } catch (InterruptedException ie) {
-                throw new RuntimeException("Interrupted while waiting for app broadcast", ie);
-            }
-            return intent;
-        }
-
-        void drainPendingBroadcasts() {
-            while (pollForIntent(5) != null) ;
-        }
-
-        Intent receiveIntentFromApp() {
-            final Intent intentReceived = pollForIntent(5);
-            assertNotNull("No intent received from app within 5 seconds", intentReceived);
-            return intentReceived;
-        }
-    }
 
     @Before
     public void setUp() {
@@ -181,9 +99,6 @@
         mPackageManager = mContext.getPackageManager();
         mLauncherApps = (LauncherApps) mContext.getSystemService(Context.LAUNCHER_APPS_SERVICE);
         mReceiverHandler = new Handler(Looper.getMainLooper());
-        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        mDeviceAdminComponent = new ComponentName(mContext,
-                "com.android.server.devicepolicy.DummyDeviceAdmins$Admin1");
         IPackageManager ipm = AppGlobals.getPackageManager();
         try {
             // Otherwise implicit broadcasts will not be delivered.
@@ -192,31 +107,6 @@
             e.rethrowAsRuntimeException();
         }
         unsuspendTestPackage();
-        mAppCommsReceiver = new AppCommunicationReceiver(mContext);
-    }
-
-    /**
-     * Care should be taken when used with {@link #mAppCommsReceiver} in the same test as both use
-     * the same handler.
-     */
-    private Bundle requestAppAction(String action) throws InterruptedException {
-        final AtomicReference<Bundle> result = new AtomicReference<>();
-        final CountDownLatch receiverLatch = new CountDownLatch(1);
-        final ComponentName testReceiverComponent = new ComponentName(TEST_APP_PACKAGE_NAME,
-                SuspendTestReceiver.class.getCanonicalName());
-        final Intent broadcastIntent = new Intent(action)
-                .setComponent(testReceiverComponent)
-                .setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        mContext.sendOrderedBroadcast(broadcastIntent, null, new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                result.set(getResultExtras(true));
-                receiverLatch.countDown();
-            }
-        }, mReceiverHandler, 0, null, null);
-
-        assertTrue("Test receiver timed out ", receiverLatch.await(5, TimeUnit.SECONDS));
-        return result.get();
     }
 
     private PersistableBundle getExtras(String keyPrefix, long lval, String sval, double dval) {
@@ -240,14 +130,6 @@
         assertTrue("setPackagesSuspended returned non-empty list", unchangedPackages.length == 0);
     }
 
-    private void startTestAppActivity() {
-        final Intent testActivity = new Intent()
-                .setComponent(new ComponentName(TEST_APP_PACKAGE_NAME,
-                        SuspendTestActivity.class.getCanonicalName()))
-                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(testActivity);
-    }
-
     private static boolean areSameExtras(BaseBundle expected, BaseBundle received) {
         if (expected != null) {
             expected.get(""); // hack to unparcel the bundles.
@@ -265,93 +147,6 @@
     }
 
     @Test
-    public void testIsPackageSuspended() throws Exception {
-        suspendTestPackage(null, null, null);
-        assertTrue("isPackageSuspended is false",
-                mPackageManager.isPackageSuspended(TEST_APP_PACKAGE_NAME));
-    }
-
-    @Test
-    public void testSuspendedStateFromApp() throws Exception {
-        Bundle resultFromApp = requestAppAction(SuspendTestReceiver.ACTION_GET_SUSPENDED_STATE);
-        assertFalse(resultFromApp.getBoolean(SuspendTestReceiver.EXTRA_SUSPENDED, true));
-        assertNull(resultFromApp.getBundle(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
-
-        final PersistableBundle appExtras = getExtras("testSuspendedStateFromApp", 20, "20", 0.2);
-        suspendTestPackage(appExtras, null, null);
-
-        resultFromApp = requestAppAction(SuspendTestReceiver.ACTION_GET_SUSPENDED_STATE);
-        assertTrue("resultFromApp:suspended is false",
-                resultFromApp.getBoolean(SuspendTestReceiver.EXTRA_SUSPENDED));
-        final Bundle receivedAppExtras =
-                resultFromApp.getBundle(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS);
-        assertSameExtras("Received app extras different to the ones supplied",
-                appExtras, receivedAppExtras);
-    }
-
-    @Test
-    public void testMyPackageSuspendedUnsuspended() {
-        mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_SUSPENDED,
-                ACTION_REPORT_MY_PACKAGE_UNSUSPENDED);
-        mAppCommsReceiver.drainPendingBroadcasts();
-        final PersistableBundle appExtras = getExtras("testMyPackageSuspendBroadcasts", 1, "1", .1);
-        suspendTestPackage(appExtras, null, null);
-        Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals("MY_PACKAGE_SUSPENDED delivery not reported",
-                ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
-        assertSameExtras("Received app extras different to the ones supplied", appExtras,
-                intentFromApp.getBundleExtra(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
-        unsuspendTestPackage();
-        intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals("MY_PACKAGE_UNSUSPENDED delivery not reported",
-                ACTION_REPORT_MY_PACKAGE_UNSUSPENDED, intentFromApp.getAction());
-    }
-
-    @Test
-    public void testUpdatingAppExtras() {
-        mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_SUSPENDED);
-        final PersistableBundle extras1 = getExtras("testMyPackageSuspendedOnChangingExtras", 1,
-                "1", 0.1);
-        suspendTestPackage(extras1, null, null);
-        Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals("MY_PACKAGE_SUSPENDED delivery not reported",
-                ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
-        assertSameExtras("Received app extras different to the ones supplied", extras1,
-                intentFromApp.getBundleExtra(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
-        final PersistableBundle extras2 = getExtras("testMyPackageSuspendedOnChangingExtras", 2,
-                "2", 0.2);
-        suspendTestPackage(extras2, null, null);
-        intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals("MY_PACKAGE_SUSPENDED delivery not reported",
-                ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
-        assertSameExtras("Received app extras different to the updated extras", extras2,
-                intentFromApp.getBundleExtra(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
-    }
-
-    @Test
-    public void testCannotSuspendSelf() {
-        final String[] unchangedPkgs = mPackageManager.setPackagesSuspended(
-                new String[]{mContext.getOpPackageName()}, true, null, null,
-                (SuspendDialogInfo) null);
-        assertTrue(unchangedPkgs.length == 1);
-        assertEquals(mContext.getOpPackageName(), unchangedPkgs[0]);
-    }
-
-    @Test
-    public void testActivityStoppedOnSuspend() {
-        mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_TEST_ACTIVITY_STARTED,
-                ACTION_REPORT_TEST_ACTIVITY_STOPPED);
-        startTestAppActivity();
-        Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals("Test activity start not reported",
-                ACTION_REPORT_TEST_ACTIVITY_STARTED, intentFromApp.getAction());
-        suspendTestPackage(null, null, null);
-        intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals("Test activity stop not reported on suspending the test app",
-                ACTION_REPORT_TEST_ACTIVITY_STOPPED, intentFromApp.getAction());
-    }
-
-    @Test
     public void testGetLauncherExtrasNonNull() {
         final Bundle extrasWhenUnsuspended = mLauncherApps.getSuspendedPackageLauncherExtras(
                 TEST_APP_PACKAGE_NAME, mContext.getUser());
@@ -383,14 +178,15 @@
     public void testOnPackagesSuspendedNewAndOld() throws InterruptedException {
         final PersistableBundle suppliedExtras = getExtras(
                 "testOnPackagesSuspendedNewAndOld", 2, "2", 0.2);
-        final AtomicReference<String> overridingBothCallbackResult = new AtomicReference<>("");
-        final CountDownLatch twoCallbackLatch = new CountDownLatch(2);
+        final AtomicReference<String> error = new AtomicReference<>("");
+        final CountDownLatch rightCallbackLatch = new CountDownLatch(1);
+        final CountDownLatch wrongCallbackLatch = new CountDownLatch(1);
         mTestCallback = new StubbedCallback() {
             @Override
             public void onPackagesSuspended(String[] packageNames, UserHandle user) {
-                overridingBothCallbackResult.set(overridingBothCallbackResult.get()
+                error.set(error.get()
                         + "Old callback called even when the new one is overriden. ");
-                twoCallbackLatch.countDown();
+                wrongCallbackLatch.countDown();
             }
 
             @Override
@@ -411,17 +207,16 @@
                     errorString.append("Unexpected launcherExtras, supplied: " + suppliedExtras
                             + ", received: " + launcherExtras + ". ");
                 }
-                overridingBothCallbackResult.set(overridingBothCallbackResult.get()
+                error.set(error.get()
                         + errorString.toString());
-                twoCallbackLatch.countDown();
+                rightCallbackLatch.countDown();
             }
         };
         mLauncherApps.registerCallback(mTestCallback, mReceiverHandler);
         suspendTestPackage(null, suppliedExtras, null);
-        assertFalse("Both callbacks were invoked", twoCallbackLatch.await(5, TimeUnit.SECONDS));
-        twoCallbackLatch.countDown();
-        assertTrue("No callback was invoked", twoCallbackLatch.await(2, TimeUnit.SECONDS));
-        final String result = overridingBothCallbackResult.get();
+        assertFalse("Wrong callback was invoked", wrongCallbackLatch.await(5, TimeUnit.SECONDS));
+        assertTrue("Right callback wasn't invoked", rightCallbackLatch.await(2, TimeUnit.SECONDS));
+        final String result = error.get();
         assertTrue("Callbacks did not complete as expected: " + result, result.isEmpty());
     }
 
@@ -457,103 +252,6 @@
         assertTrue("Callback did not complete as expected: " + result, result.isEmpty());
     }
 
-    private void turnScreenOn() throws Exception {
-        if (!mUiDevice.isScreenOn()) {
-            mUiDevice.wakeUp();
-        }
-        final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-        wm.dismissKeyguard(null, null);
-    }
-
-    @Test
-    public void testInterceptorActivity() throws Exception {
-        turnScreenOn();
-        mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MORE_DETAILS_ACTIVITY_STARTED,
-                ACTION_REPORT_TEST_ACTIVITY_STARTED);
-        final String testMessage = "This is a test message to report suspension of %1$s";
-        suspendTestPackage(null, null,
-                new SuspendDialogInfo.Builder().setMessage(testMessage).build());
-        startTestAppActivity();
-        assertNull("No broadcast was expected from app", mAppCommsReceiver.pollForIntent(2));
-        assertNotNull("Given dialog message not shown", mUiDevice.wait(
-                Until.findObject(By.text(String.format(testMessage, TEST_APP_LABEL))), 5000));
-        final String buttonText = mContext.getResources().getString(Resources.getSystem()
-                .getIdentifier("app_suspended_more_details", "string", "android"));
-        final UiObject2 moreDetailsButton = mUiDevice.findObject(
-                By.clickable(true).text(buttonText));
-        assertNotNull(buttonText + " button not shown", moreDetailsButton);
-        moreDetailsButton.click();
-        final Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals(buttonText + " activity start not reported",
-                ACTION_REPORT_MORE_DETAILS_ACTIVITY_STARTED, intentFromApp.getAction());
-        final String receivedPackageName = intentFromApp.getStringExtra(
-                EXTRA_RECEIVED_PACKAGE_NAME);
-        assertEquals("Wrong package name received by " + buttonText + " activity",
-                TEST_APP_PACKAGE_NAME, receivedPackageName);
-    }
-
-    private boolean setProfileOwner() throws IOException {
-        final String result = mUiDevice.executeShellCommand("dpm set-profile-owner --user cur "
-                + mDeviceAdminComponent.flattenToString());
-        return mPoSet = result.trim().startsWith("Success");
-    }
-
-    private boolean setDeviceOwner() throws IOException {
-        final String result = mUiDevice.executeShellCommand("dpm set-device-owner --user cur "
-                + mDeviceAdminComponent.flattenToString());
-        return mDoSet = result.trim().startsWith("Success");
-    }
-
-    private void removeProfileOrDeviceOwner() throws IOException {
-        if (mPoSet || mDoSet) {
-            mUiDevice.executeShellCommand("dpm remove-active-admin --user cur "
-                    + mDeviceAdminComponent.flattenToString());
-            mPoSet = mDoSet = false;
-        }
-    }
-
-    @Test
-    public void testCanSuspendWhenProfileOwner() throws IOException {
-        assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
-        assertTrue("Profile-owner could not be set", setProfileOwner());
-        suspendTestPackage(null, null, null);
-    }
-
-    @Test
-    public void testCanSuspendWhenDeviceOwner() throws IOException {
-        assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
-        assertTrue("Device-owner could not be set", setDeviceOwner());
-        suspendTestPackage(null, null, null);
-    }
-
-    @Test
-    public void testPackageUnsuspendedOnAddingDeviceOwner() throws IOException {
-        assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
-        mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_UNSUSPENDED,
-                ACTION_REPORT_MY_PACKAGE_SUSPENDED);
-        mAppCommsReceiver.drainPendingBroadcasts();
-        suspendTestPackage(null, null, null);
-        Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals(ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
-        assertTrue("Device-owner could not be set", setDeviceOwner());
-        intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals(ACTION_REPORT_MY_PACKAGE_UNSUSPENDED, intentFromApp.getAction());
-    }
-
-    @Test
-    public void testPackageUnsuspendedOnAddingProfileOwner() throws IOException {
-        assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
-        mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_UNSUSPENDED,
-                ACTION_REPORT_MY_PACKAGE_SUSPENDED);
-        mAppCommsReceiver.drainPendingBroadcasts();
-        suspendTestPackage(null, null, null);
-        Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals(ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
-        assertTrue("Profile-owner could not be set", setProfileOwner());
-        intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
-        assertEquals(ACTION_REPORT_MY_PACKAGE_UNSUSPENDED, intentFromApp.getAction());
-    }
-
     @Test
     public void testCameraBlockedOnSuspend() throws Exception {
         assertOpBlockedOnSuspend(OP_CAMERA);
@@ -596,13 +294,9 @@
 
     @After
     public void tearDown() throws IOException {
-        mAppCommsReceiver.unregister();
         if (mTestCallback != null) {
             mLauncherApps.unregisterCallback(mTestCallback);
         }
-        removeProfileOrDeviceOwner();
-        mContext.sendBroadcast(new Intent(ACTION_FINISH_TEST_ACTIVITY)
-                .setPackage(TEST_APP_PACKAGE_NAME));
     }
 
     private static abstract class StubbedCallback extends LauncherApps.Callback {