19209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans/*
29209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans * Copyright (C) 2017 The Android Open Source Project
39209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans *
49209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans * Licensed under the Apache License, Version 2.0 (the "License");
59209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans * you may not use this file except in compliance with the License.
69209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans * You may obtain a copy of the License at
79209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans *
89209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans *      http://www.apache.org/licenses/LICENSE-2.0
99209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans *
109209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans * Unless required by applicable law or agreed to in writing, software
119209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans * distributed under the License is distributed on an "AS IS" BASIS,
129209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans * See the License for the specific language governing permissions and
149209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans * limitations under the License.
159209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans */
169209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
179209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evanspackage com.android.settings.applications.instantapps;
189209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
199209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static com.android.settings.applications.instantapps.InstantAppButtonsController
209209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        .ShowDialogDelegate;
219209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
229209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static com.google.common.truth.Truth.assertThat;
239209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
249209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static org.mockito.Matchers.eq;
259209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static org.mockito.Matchers.any;
269209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static org.mockito.Matchers.anyInt;
279209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static org.mockito.Matchers.isNull;
289209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static org.mockito.Mockito.doAnswer;
299209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static org.mockito.Mockito.mock;
309209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static org.mockito.Mockito.verify;
319209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static org.mockito.Mockito.verifyZeroInteractions;
329209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport static org.mockito.Mockito.when;
339209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
349209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.annotation.SuppressLint;
359209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.app.Fragment;
369209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.content.ComponentName;
379209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.content.Context;
389209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.content.DialogInterface;
399209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.content.Intent;
409209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.content.pm.ActivityInfo;
419209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.content.pm.PackageManager;
429209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.content.pm.ResolveInfo;
439209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.view.View;
449209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport android.widget.Button;
459209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
469209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport com.android.settings.R;
479f1e911759dc6fedaac9fa65afb79f6a93022bf4Andrew Sappersteinimport com.android.settings.testutils.SettingsRobolectricTestRunner;
489209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport com.android.settings.TestConfig;
499209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport com.android.settings.applications.PackageManagerWrapper;
509209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport com.android.settings.core.instrumentation.MetricsFeatureProvider;
519209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport com.android.settings.testutils.FakeFeatureFactory;
529209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
539209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport org.junit.Before;
549209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport org.junit.Test;
559209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport org.junit.runner.RunWith;
569209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport org.mockito.Answers;
579209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport org.mockito.Mock;
589209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport org.mockito.MockitoAnnotations;
599209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport org.robolectric.annotation.Config;
609209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evansimport org.robolectric.util.ReflectionHelpers;
619209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
629209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans/** Tests for the InstantAppButtonsController. */
639209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans@RunWith(SettingsRobolectricTestRunner.class)
649209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans@Config(manifest = TestConfig.MANIFEST_PATH, sdk = 23)
659209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evanspublic class InstantAppButtonsControllerTest {
669209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
679209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private static final String TEST_INSTALLER_PACKAGE_NAME = "com.installer";
689209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private static final String TEST_INSTALLER_ACTIVITY_NAME = "com.installer.InstallerActivity";
699209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private static final ComponentName TEST_INSTALLER_COMPONENT =
709209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans            new ComponentName(
719209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans                    TEST_INSTALLER_PACKAGE_NAME,
729209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans                    TEST_INSTALLER_ACTIVITY_NAME);
739209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private static final String TEST_AIA_PACKAGE_NAME = "test.aia.package";
749209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
759209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
769209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    Context mockContext;
779209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock
789209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    PackageManager mockPackageManager;
799209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock
809209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    PackageManagerWrapper mockPackageManagerWrapper;
819209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock
829209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    View mockView;
839209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock
849209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    ShowDialogDelegate mockShowDialogDelegate;
859209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock
869209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    Button mockInstallButton;
879209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock
889209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    Button mockClearButton;
899209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock
909209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    MetricsFeatureProvider mockMetricsFeatureProvider;
919209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock
929209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    ResolveInfo mockResolveInfo;
939209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Mock
949209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    ActivityInfo mockActivityInfo;
959209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
969209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private PackageManager stubPackageManager;
979209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
989209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private FakeFeatureFactory fakeFeatureFactory;
999209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private TestFragment testFragment;
1009209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private InstantAppButtonsController controller;
1019209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1029209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1039209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private View.OnClickListener receivedListener;
1049209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1059209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Before
1069209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    public void init() {
1079209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        MockitoAnnotations.initMocks(this);
1089209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        testFragment = new TestFragment();
1099209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        when(mockView.findViewById(R.id.install)).thenReturn(mockInstallButton);
1109209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        when(mockView.findViewById(R.id.clear_data)).thenReturn(mockClearButton);
1119209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        mockResolveInfo.activityInfo = mockActivityInfo;
1129209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        mockActivityInfo.packageName = TEST_INSTALLER_PACKAGE_NAME;
1139209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        mockActivityInfo.name = TEST_INSTALLER_ACTIVITY_NAME;
1149209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
1159209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        when(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(mockResolveInfo);
1169209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        controller = new InstantAppButtonsController(
1179209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans                mockContext, testFragment, mockView, mockShowDialogDelegate);
1189209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        controller.setPackageName(TEST_AIA_PACKAGE_NAME);
1199209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        ReflectionHelpers.setField(
1209209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans                controller, "mPackageManagerWrapper", mockPackageManagerWrapper);
1219209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        FakeFeatureFactory.setupForTest(mockContext);
1229209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    }
1239209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1249209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Test
1259209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    public void testInstallListenerTriggersInstall() {
1269209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        doAnswer(invocation -> {
1279209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans            receivedListener = (View.OnClickListener) invocation.getArguments()[0];
1289209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans            return null;
1299209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        }).when(mockInstallButton).setOnClickListener(any());
1309209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        controller.bindButtons();
1319209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1329209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        assertThat(receivedListener).isNotNull();
1339209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        receivedListener.onClick(mockInstallButton);
1349209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        assertThat(testFragment.getStartActivityIntent()).isNotNull();
1359209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        assertThat(testFragment.getStartActivityIntent().getComponent())
1369209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans                .isEqualTo(TEST_INSTALLER_COMPONENT);
1379209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    }
1389209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1399209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Test
1409209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    public void testClearListenerShowsDialog() {
1419209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        doAnswer(invocation -> {
1429209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans            receivedListener = (View.OnClickListener) invocation.getArguments()[0];
1439209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans            return null;
1449209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        }).when(mockClearButton).setOnClickListener(any());
1459209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        controller.bindButtons();
1469209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        assertThat(receivedListener).isNotNull();
1479209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        receivedListener.onClick(mockClearButton);
1489209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        verify(mockShowDialogDelegate).showDialog(InstantAppButtonsController.DLG_CLEAR_APP);
1499209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    }
1509209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1519209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Test
1529209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    public void testDialogInterfaceOnClick_positiveClearsApp() {
1539209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        controller.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_POSITIVE);
1549209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        verify(mockPackageManagerWrapper)
1559209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans                .deletePackageAsUser(eq(TEST_AIA_PACKAGE_NAME), any(), anyInt(),anyInt());
1569209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    }
1579209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1589209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @Test
1599209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    public void testDialogInterfaceOnClick_nonPositiveDoesNothing() {
1609209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        controller.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_NEGATIVE);
1619209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        controller.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_NEUTRAL);
1629209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        verifyZeroInteractions(mockPackageManagerWrapper);
1639209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    }
1649209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    @SuppressLint("ValidFragment")
1659209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    private class TestFragment extends Fragment {
1669209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1679209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        private Intent startActivityIntent;
1689209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1699209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        public Intent getStartActivityIntent() {
1709209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans            return startActivityIntent;
1719209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        }
1729209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans
1739209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        @Override
1749209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        public void startActivity(Intent intent) {
1759209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans            startActivityIntent = intent;
1769209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans        }
1779209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans    }
1789209ee53ed8545ab7461ba768db7921509f0afb6Jesse Evans}
179