Home | History | Annotate | Download | only in am
      1 /*
      2  * Copyright 2017, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.am;
     18 
     19 import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
     20 
     21 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
     22 
     23 import static org.junit.Assert.assertEquals;
     24 import static org.junit.Assert.assertFalse;
     25 import static org.junit.Assert.assertTrue;
     26 import static org.mockito.ArgumentMatchers.eq;
     27 import static org.mockito.ArgumentMatchers.nullable;
     28 import static org.mockito.Mockito.when;
     29 
     30 import android.app.KeyguardManager;
     31 import android.app.admin.DevicePolicyManagerInternal;
     32 import android.content.Context;
     33 import android.content.Intent;
     34 import android.content.pm.ActivityInfo;
     35 import android.content.pm.ApplicationInfo;
     36 import android.content.pm.PackageManagerInternal;
     37 import android.content.pm.UserInfo;
     38 import android.os.UserHandle;
     39 import android.os.UserManager;
     40 import android.support.test.filters.SmallTest;
     41 import android.testing.DexmakerShareClassLoaderRule;
     42 
     43 import com.android.internal.app.SuspendedAppActivity;
     44 import com.android.internal.app.UnlaunchableAppActivity;
     45 import com.android.server.LocalServices;
     46 import com.android.server.pm.PackageManagerService;
     47 
     48 import org.junit.Before;
     49 import org.junit.Rule;
     50 import org.junit.Test;
     51 import org.mockito.Mock;
     52 import org.mockito.MockitoAnnotations;
     53 
     54 /**
     55  * Unit tests for {@link ActivityStartInterceptorTest}.
     56  *
     57  * Build/Install/Run:
     58  *  bit FrameworksServicesTests:com.android.server.am.ActivityStartInterceptorTest
     59  */
     60 @SmallTest
     61 public class ActivityStartInterceptorTest {
     62     private static final int TEST_USER_ID = 1;
     63     private static final int TEST_REAL_CALLING_UID = 2;
     64     private static final int TEST_REAL_CALLING_PID = 3;
     65     private static final String TEST_CALLING_PACKAGE = "com.test.caller";
     66     private static final int TEST_START_FLAGS = 4;
     67     private static final Intent ADMIN_SUPPORT_INTENT =
     68             new Intent("com.test.ADMIN_SUPPORT");
     69     private static final Intent CONFIRM_CREDENTIALS_INTENT =
     70             new Intent("com.test.CONFIRM_CREDENTIALS");
     71     private static final UserInfo PARENT_USER_INFO = new UserInfo(0 /* userId */, "parent",
     72             0 /* flags */);
     73     private static final String TEST_PACKAGE_NAME = "com.test.package";
     74 
     75     @Rule
     76     public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
     77             new DexmakerShareClassLoaderRule();
     78 
     79     @Mock
     80     private Context mContext;
     81     @Mock
     82     private ActivityManagerService mService;
     83     @Mock
     84     private ActivityStackSupervisor mSupervisor;
     85     @Mock
     86     private DevicePolicyManagerInternal mDevicePolicyManager;
     87     @Mock
     88     private PackageManagerInternal mPackageManagerInternal;
     89     @Mock
     90     private UserManager mUserManager;
     91     @Mock
     92     private UserController mUserController;
     93     @Mock
     94     private KeyguardManager mKeyguardManager;
     95     @Mock
     96     private PackageManagerService mPackageManager;
     97 
     98     private ActivityStartInterceptor mInterceptor;
     99     private ActivityInfo mAInfo = new ActivityInfo();
    100 
    101     @Before
    102     public void setUp() {
    103         MockitoAnnotations.initMocks(this);
    104         mInterceptor = new ActivityStartInterceptor(mService, mSupervisor, mContext,
    105                 mUserController);
    106         mInterceptor.setStates(TEST_USER_ID, TEST_REAL_CALLING_PID, TEST_REAL_CALLING_UID,
    107                 TEST_START_FLAGS, TEST_CALLING_PACKAGE);
    108 
    109         // Mock DevicePolicyManagerInternal
    110         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
    111         LocalServices.addService(DevicePolicyManagerInternal.class,
    112                 mDevicePolicyManager);
    113         when(mDevicePolicyManager
    114                         .createShowAdminSupportIntent(TEST_USER_ID, true))
    115                 .thenReturn(ADMIN_SUPPORT_INTENT);
    116         when(mService.getPackageManagerInternalLocked()).thenReturn(mPackageManagerInternal);
    117 
    118         // Mock UserManager
    119         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
    120         when(mUserManager.getProfileParent(TEST_USER_ID)).thenReturn(PARENT_USER_INFO);
    121 
    122         // Mock KeyguardManager
    123         when(mContext.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(mKeyguardManager);
    124         when(mKeyguardManager.createConfirmDeviceCredentialIntent(
    125                 nullable(CharSequence.class), nullable(CharSequence.class), eq(TEST_USER_ID))).
    126                 thenReturn(CONFIRM_CREDENTIALS_INTENT);
    127 
    128         // Mock PackageManager
    129         when(mService.getPackageManager()).thenReturn(mPackageManager);
    130         when(mPackageManager.getHarmfulAppWarning(TEST_PACKAGE_NAME, TEST_USER_ID))
    131                 .thenReturn(null);
    132 
    133         // Initialise activity info
    134         mAInfo.applicationInfo = new ApplicationInfo();
    135         mAInfo.packageName = mAInfo.applicationInfo.packageName = TEST_PACKAGE_NAME;
    136     }
    137 
    138     @Test
    139     public void testSuspendedByAdminPackage() {
    140         // GIVEN the package we're about to launch is currently suspended
    141         mAInfo.applicationInfo.flags = FLAG_SUSPENDED;
    142 
    143         when(mPackageManagerInternal.getSuspendingPackage(TEST_PACKAGE_NAME, TEST_USER_ID))
    144                 .thenReturn(PLATFORM_PACKAGE_NAME);
    145 
    146         // THEN calling intercept returns true
    147         assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
    148 
    149         // THEN the returned intent is the admin support intent
    150         assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent);
    151     }
    152 
    153     @Test
    154     public void testSuspendedPackage() {
    155         mAInfo.applicationInfo.flags = FLAG_SUSPENDED;
    156         final String suspendingPackage = "com.test.suspending.package";
    157         final String dialogMessage = "Test Message";
    158         when(mPackageManagerInternal.getSuspendingPackage(TEST_PACKAGE_NAME, TEST_USER_ID))
    159                 .thenReturn(suspendingPackage);
    160         when(mPackageManagerInternal.getSuspendedDialogMessage(TEST_PACKAGE_NAME, TEST_USER_ID))
    161                 .thenReturn(dialogMessage);
    162         // THEN calling intercept returns true
    163         assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
    164 
    165         // Check intent parameters
    166         assertEquals(dialogMessage,
    167                 mInterceptor.mIntent.getStringExtra(SuspendedAppActivity.EXTRA_DIALOG_MESSAGE));
    168         assertEquals(suspendingPackage,
    169                 mInterceptor.mIntent.getStringExtra(SuspendedAppActivity.EXTRA_SUSPENDING_PACKAGE));
    170         assertEquals(TEST_PACKAGE_NAME,
    171                 mInterceptor.mIntent.getStringExtra(SuspendedAppActivity.EXTRA_SUSPENDED_PACKAGE));
    172         assertEquals(TEST_USER_ID, mInterceptor.mIntent.getIntExtra(Intent.EXTRA_USER_ID, -1000));
    173     }
    174 
    175     @Test
    176     public void testInterceptQuietProfile() {
    177         // GIVEN that the user the activity is starting as is currently in quiet mode
    178         when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true);
    179 
    180         // THEN calling intercept returns true
    181         assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
    182 
    183         // THEN the returned intent is the quiet mode intent
    184         assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID)
    185                 .filterEquals(mInterceptor.mIntent));
    186     }
    187 
    188     @Test
    189     public void testWorkChallenge() {
    190         // GIVEN that the user the activity is starting as is currently locked
    191         when(mUserController.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true);
    192 
    193         // THEN calling intercept returns true
    194         mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null);
    195 
    196         // THEN the returned intent is the quiet mode intent
    197         assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent));
    198     }
    199 
    200     @Test
    201     public void testNoInterception() {
    202         // GIVEN that none of the interception conditions are met
    203 
    204         // THEN calling intercept returns false
    205         assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
    206     }
    207 }
    208