Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39836d6c authored by Fan Wu's avatar Fan Wu Committed by Chris Antol
Browse files

Checks cross user permission before handling intent

Bug: 326057017

Test: atest

Flag: EXEMPT bug fix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d3b3edd45167515579ab156533754e56ac813f35)
Merged-In: I3444e55b22b7487f96b0e3e9deb3f844c4c4723a
Change-Id: I3444e55b22b7487f96b0e3e9deb3f844c4c4723a
parent dcd38287
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settings.applications;

import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
@@ -39,6 +40,7 @@ import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
@@ -135,8 +137,13 @@ public abstract class AppInfoBase extends SettingsPreferenceFragment
            }
        }
        if (intent != null && intent.hasExtra(Intent.EXTRA_USER_HANDLE)) {
            mUserId = ((UserHandle) intent.getParcelableExtra(
                    Intent.EXTRA_USER_HANDLE)).getIdentifier();
            mUserId = ((UserHandle) intent.getParcelableExtra(Intent.EXTRA_USER_HANDLE))
                    .getIdentifier();
            if (mUserId != UserHandle.myUserId() && !hasInteractAcrossUsersPermission()) {
                Log.w(TAG, "Intent not valid.");
                finish();
                return "";
            }
        } else {
            mUserId = UserHandle.myUserId();
        }
@@ -159,6 +166,28 @@ public abstract class AppInfoBase extends SettingsPreferenceFragment
        return mPackageName;
    }

    @VisibleForTesting
    protected boolean hasInteractAcrossUsersPermission() {
        Activity activity = getActivity();
        if (!(activity instanceof SettingsActivity)) {
            return false;
        }
        final String callingPackageName =
                ((SettingsActivity) activity).getInitialCallingPackage();

        if (TextUtils.isEmpty(callingPackageName)) {
            Log.w(TAG, "Not able to get calling package name for permission check");
            return false;
        }
        if (mPm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingPackageName)
                != PackageManager.PERMISSION_GRANTED) {
            Log.w(TAG, "Package " + callingPackageName + " does not have required permission "
                    + Manifest.permission.INTERACT_ACROSS_USERS_FULL);
            return false;
        }
        return true;
    }

    protected void setIntentAndFinish(boolean appChanged) {
        Log.i(TAG, "appChanged=" + appChanged);
        Intent intent = new Intent();
+0 −96
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.applications.appcompat;

import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_3_2;
import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_DEFAULT;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.IActivityManager;
import android.content.Context;
import android.os.RemoteException;

import androidx.test.core.app.ApplicationProvider;

import com.android.settings.testutils.shadow.ShadowActivityManager;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

/**
 * To run test: atest SettingsRoboTests:UserAspectRatioDetailsTest
 */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowActivityManager.class})
public class UserAspectRatioDetailsTest {

    @Mock
    private UserAspectRatioManager mUserAspectRatioManager;
    @Mock
    private IActivityManager mAm;

    private RadioWithImagePreference mRadioButtonPref;
    private Context mContext;
    private UserAspectRatioDetails mFragment;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mContext = spy(ApplicationProvider.getApplicationContext());
        mFragment = spy(new UserAspectRatioDetails());
        when(mFragment.getContext()).thenReturn(mContext);
        when(mFragment.getAspectRatioManager()).thenReturn(mUserAspectRatioManager);
        ShadowActivityManager.setService(mAm);
        mRadioButtonPref = new RadioWithImagePreference(mContext);
    }

    @Test
    public void onRadioButtonClicked_prefChange_shouldStopActivity() throws RemoteException {
        // Default was already selected
        mRadioButtonPref.setKey(KEY_PREF_DEFAULT);
        mFragment.onRadioButtonClicked(mRadioButtonPref);
        // Preference changed
        mRadioButtonPref.setKey(KEY_PREF_3_2);
        mFragment.onRadioButtonClicked(mRadioButtonPref);
        // Only triggered once when preference change
        verify(mAm).stopAppForUser(any(), anyInt());
    }

    @Test
    public void onRadioButtonClicked_prefChange_shouldSetAspectRatio() throws RemoteException {
        // Default was already selected
        mRadioButtonPref.setKey(KEY_PREF_DEFAULT);
        mFragment.onRadioButtonClicked(mRadioButtonPref);
        // Preference changed
        mRadioButtonPref.setKey(KEY_PREF_3_2);
        mFragment.onRadioButtonClicked(mRadioButtonPref);
        // Only triggered once when preference changes
        verify(mUserAspectRatioManager).setUserMinAspectRatio(
                any(), anyInt(), anyInt());
    }
}