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

Commit e259e601 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['ag/20533028', 'ag/20690601', 'ag/20727213',...

Merge cherrypicks of ['ag/20533028', 'ag/20690601', 'ag/20727213', 'ag/20640992', 'ag/20871683'] into security-aosp-sc-v2-release.

Change-Id: I0ec23b6e01c93fa35e2281aeac9a5d0f949e3e8d
parents 157a48d6 d83753d6
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import com.android.settingslib.search.Indexable;
import com.android.settingslib.widget.LayoutPreference;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.setupcompat.util.WizardManagerHelper;

import java.util.UUID;

@@ -63,7 +64,7 @@ import java.util.UUID;
public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceFragment
        implements DialogCreatable, HelpResourceProvider, Indexable {

    private static final String TAG = "SettingsPreference";
    private static final String TAG = "SettingsPreferenceFragment";

    private static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";

@@ -121,6 +122,15 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
    public HighlightablePreferenceGroupAdapter mAdapter;
    private boolean mPreferenceHighlighted = false;

    @Override
    public void onAttach(Context context) {
        if (shouldSkipForInitialSUW() && !WizardManagerHelper.isDeviceProvisioned(getContext())) {
            Log.w(TAG, "Skip " + getClass().getSimpleName() + " before SUW completed.");
            finish();
        }
        super.onAttach(context);
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
@@ -267,6 +277,16 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
                || (mAdapter.getPreferenceAdapterPosition(preference) != RecyclerView.NO_POSITION));
    }

    /**
     * Whether UI should be skipped in the initial SUW flow.
     *
     * @return {@code true} when UI should be skipped in the initial SUW flow.
     * {@code false} when UI should not be skipped in the initial SUW flow.
     */
    protected boolean shouldSkipForInitialSUW() {
        return false;
    }

    protected void onDataSetChanged() {
        highlightPreferenceIfNeeded();
        updateEmptyView();
+5 −0
Original line number Diff line number Diff line
@@ -84,6 +84,11 @@ public class AccountDashboardFragment extends DashboardFragment {
        return controllers;
    }

    @Override
    protected boolean shouldSkipForInitialSUW() {
        return true;
    }

    static void buildAutofillPreferenceControllers(
            Context context, List<AbstractPreferenceController> controllers) {
        controllers.add(new DefaultAutofillPreferenceController(context));
+12 −1
Original line number Diff line number Diff line
@@ -385,7 +385,13 @@ public class AppInfoDashboardFragment extends DashboardFragment
            return;
        }
        super.onPrepareOptionsMenu(menu);
        menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry));
        final MenuItem uninstallAllUsersItem = menu.findItem(UNINSTALL_ALL_USERS_MENU);
        uninstallAllUsersItem.setVisible(
                shouldShowUninstallForAll(mAppEntry) && !mAppsControlDisallowedBySystem);
        if (uninstallAllUsersItem.isVisible()) {
            RestrictedLockUtilsInternal.setMenuItemAsDisabledByAdmin(getActivity(),
                    uninstallAllUsersItem, mAppsControlDisallowedAdmin);
        }
        mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
        final MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES);
        final boolean uninstallUpdateDisabled = getContext().getResources().getBoolean(
@@ -503,6 +509,11 @@ public class AppInfoDashboardFragment extends DashboardFragment
        return true;
    }

    @Override
    protected boolean shouldSkipForInitialSUW() {
        return true;
    }

    private void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) {
        stopListeningToPackageRemove();
        // Create new intent to launch Uninstaller activity
+5 −0
Original line number Diff line number Diff line
@@ -215,6 +215,11 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
        }
    }

    @Override
    protected boolean shouldSkipForInitialSUW() {
        return true;
    }

    /**
     * Long-pressing a developer options quick settings tile will by default (see
     * QS_TILE_PREFERENCES in the manifest) take you to the developer options page.
+92 −0
Original line number Diff line number Diff line
@@ -25,8 +25,13 @@ import android.app.ActivityManager;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.FeatureFlagUtils;
@@ -38,6 +43,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toolbar;

import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
@@ -55,6 +61,7 @@ import com.android.settings.core.CategoryMixin;
import com.android.settings.core.FeatureFlags;
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.PasswordUtils;
import com.android.settingslib.Utils;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;

@@ -351,6 +358,40 @@ public class SettingsHomepageActivity extends FragmentActivity implements
            finish();
            return;
        }

        ActivityInfo targetActivityInfo = null;
        try {
            targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName,
                    /* flags= */ 0);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "Failed to get target ActivityInfo: " + e);
            finish();
            return;
        }

        int callingUid = -1;
        try {
            callingUid = ActivityManager.getService().getLaunchedFromUid(getActivityToken());
        } catch (RemoteException re) {
            Log.e(TAG, "Not able to get callingUid: " + re);
            finish();
            return;
        }

        if (!hasPrivilegedAccess(callingUid, targetActivityInfo)) {
            if (!targetActivityInfo.exported) {
                Log.e(TAG, "Target Activity is not exported");
                finish();
                return;
            }

            if (!isCallingAppPermitted(targetActivityInfo.permission)) {
                Log.e(TAG, "Calling app must have the permission of deep link Activity");
                finish();
                return;
            }
        }

        targetIntent.setComponent(targetComponentName);

        // To prevent launchDeepLinkIntentToRight again for configuration change.
@@ -368,6 +409,19 @@ public class SettingsHomepageActivity extends FragmentActivity implements
        targetIntent.setData(intent.getParcelableExtra(
                SettingsHomepageActivity.EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA));

        // Only allow FLAG_GRANT_READ/WRITE_URI_PERMISSION if calling app has the permission to
        // access specified Uri.
        int uriPermissionFlags = targetIntent.getFlags()
                & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        if (targetIntent.getData() != null
                && uriPermissionFlags != 0
                && checkUriPermission(targetIntent.getData(), /* pid= */ -1, callingUid,
                        uriPermissionFlags) == PackageManager.PERMISSION_DENIED) {
            Log.e(TAG, "Calling app must have the permission to access Uri and grant permission");
            finish();
            return;
        }

        // Set 2-pane pair rule for the deep link page.
        ActivityEmbeddingRulesController.registerTwoPanePairRule(this,
                new ComponentName(getApplicationContext(), getClass()),
@@ -386,6 +440,44 @@ public class SettingsHomepageActivity extends FragmentActivity implements
        startActivity(targetIntent);
    }

    // Check if calling app has privileged access to launch Activity of activityInfo.
    private boolean hasPrivilegedAccess(int callingUid, ActivityInfo activityInfo) {
        if (TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()),
                    getPackageName())) {
            return true;
        }

        int targetUid = -1;
        try {
            targetUid = getPackageManager().getApplicationInfo(activityInfo.packageName,
                    /* flags= */ 0).uid;
        } catch (PackageManager.NameNotFoundException nnfe) {
            Log.e(TAG, "Not able to get targetUid: " + nnfe);
            return false;
        }

        // When activityInfo.exported is false, Activity still can be launched if applications have
        // the same user ID.
        if (UserHandle.isSameApp(callingUid, targetUid)) {
            return true;
        }

        // When activityInfo.exported is false, Activity still can be launched if calling app has
        // root or system privilege.
        int callingAppId = UserHandle.getAppId(callingUid);
        if (callingAppId == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID) {
            return true;
        }

        return false;
    }

    @VisibleForTesting
    boolean isCallingAppPermitted(String permission) {
        return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted(
                this, getActivityToken(), permission);
    }

    private String getHighlightMenuKey() {
        final Intent intent = getIntent();
        if (intent != null && TextUtils.equals(intent.getAction(),
Loading