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

Unverified Commit 3467f151 authored by Michael Bestas's avatar Michael Bestas
Browse files

Merge tag 'android-security-15.0.0_r10' into staging/lineage-22.2_merge-android-security-15.0.0_r10

Android Security 15.0.0 Release 10 (13793697)

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCaLcitgAKCRDorT+BmrEO
# eKcQAJ9egQZPntvkA1gUOGO6gzQN2Y53EQCdF5qsX/O/3HFEIRXZfQKTy6e9VQ8=
# =ISOZ
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Sep  2 20:00:38 2025 EEST
# gpg:                using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [ultimate]

* tag 'android-security-15.0.0_r10': (23 commits)
  Ignore face settings extras when called by an external package.
  startActivityForResult with earlier new Intent
  Hide notification content in history
  Use correct API to get calling package name in CredentialStorage
  Drop PendingIntent extras from external packages during enrollment.
  Do not enable the Content Protection toggle for non-admin users.
  AppRestrictions - use vetted component
  Add ComponentName explicitly to make sure arbitary intents aren't launched from Settings.
  Disable the ContentProtection setting switch bar when current user is a guest user.
  [CDM] Checks NLS component name instead of package name
  Check package name format before using it for SPA nav
  [SPA] Add biometric authentication for package modification
  Remove incorrect call to Window.addFlags with a system flag
  Check the permission of the callingUid instead of the calling package
  Set component name only for ConfirmDeviceCredentialActivity.
  [Safer intents] App Time Spent Preference
  Don't let profiles open the UserSettings overflow [DO NOT MERGE]
  Block the content scheme intent in AccountTypePreferenceLoader
  [CDM][NLS] Check if the NLS service has an intent-filter
  Checks cross user permission before handling intent
  ...

 Conflicts:
	src/com/android/settings/accessibility/AccessibilitySettings.java
	src/com/android/settings/applications/AppInfoBase.java
	src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
	src/com/android/settings/security/ContentProtectionTogglePreferenceController.java
	src/com/android/settings/users/AppRestrictionsFragment.java
	src/com/android/settings/users/UserSettings.java
	tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
	tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
	tests/robotests/src/com/android/settings/security/ContentProtectionTogglePreferenceControllerTest.java

Change-Id: I8cb282480b2a75cca58e381c17e72ebba2aceb0d
parents e27df4fd 220efa84
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -265,7 +265,14 @@ public class AccountTypePreferenceLoader {
        try {
            // Allows to launch only authenticator owned activities.
            ApplicationInfo authenticatorAppInf = pm.getApplicationInfo(authDesc.packageName, 0);
            return resolvedAppInfo.uid == authenticatorAppInf.uid;
            if (resolvedAppInfo.uid == authenticatorAppInf.uid) {
                // Explicitly set the component to be same as authenticator to
                // prevent launching arbitrary activities.
                intent.setComponent(resolvedActivityInfo.getComponentName());
                return true;
            } else {
                return false;
            }
        } catch (NameNotFoundException e) {
            Log.e(TAG,
                "Intent considered unsafe due to exception.",
+18 −2
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ import com.google.android.setupdesign.span.LinkSpan;
import com.google.android.setupdesign.template.RequireScrollMixin;
import com.google.android.setupdesign.util.DynamicColorPalette;

import java.util.List;

/**
 * Abstract base class for the intro onboarding activity for biometric enrollment.
 */
@@ -242,6 +244,19 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
                !isScrollNeeded && !enrollmentCompleted ? View.VISIBLE : View.INVISIBLE);
    }

    @Override
    protected void onStart() {
        super.onStart();

        if (!getPackageName().equals(getCallingPackage())) {
            for (String key : List.of(MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL,
                    MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE,
                    MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT)) {
                getIntent().removeExtra(key);
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
@@ -490,14 +505,15 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
        getIntent().removeExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT);
    }

    protected void removeEnrollNextBiometricIfSkipEnroll(@Nullable Intent data) {
    private void removeEnrollNextBiometricIfSkipEnroll(@Nullable Intent data) {
        if (data != null
                && data.getBooleanExtra(
                        MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL, false)) {
            removeEnrollNextBiometric();
        }
    }
    protected void handleBiometricResultSkipOrFinished(int resultCode, @Nullable Intent data) {

    private void handleBiometricResultSkipOrFinished(int resultCode, @Nullable Intent data) {
        removeEnrollNextBiometricIfSkipEnroll(data);
        if (resultCode == RESULT_SKIP) {
            onEnrollmentSkipped(data);
+14 −7
Original line number Diff line number Diff line
@@ -83,8 +83,8 @@ public class FaceSettings extends DashboardFragment {
    private FaceManager mFaceManager;
    private DevicePolicyManager mDevicePolicyManager;
    private int mUserId;
    private int mSensorId;
    private long mChallenge;
    private int mSensorId = -1;
    private long mChallenge = 0;
    private byte[] mToken;
    private FaceSettingsAttentionPreferenceController mAttentionController;
    private FaceSettingsRemoveButtonPreferenceController mRemoveController;
@@ -166,12 +166,19 @@ public class FaceSettings extends DashboardFragment {
        mUserManager = context.getSystemService(UserManager.class);
        mFaceManager = context.getSystemService(FaceManager.class);
        mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);

        final SettingsActivity activity = (SettingsActivity) requireActivity();
        final String callingPackage = activity.getInitialCallingPackage();
        if (callingPackage == null || !callingPackage.equals(activity.getPackageName())) {
            mUserId = UserHandle.myUserId();
        } else {
            // only allow these extras when called internally by Settings
            mToken = getIntent().getByteArrayExtra(KEY_TOKEN);
            mSensorId = getIntent().getIntExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, -1);
            mChallenge = getIntent().getLongExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, 0L);
            mUserId = getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId());
        }

        mUserId = getActivity().getIntent().getIntExtra(
                Intent.EXTRA_USER_ID, UserHandle.myUserId());
        mFaceFeatureProvider = FeatureFactory.getFeatureFactory().getFaceFeatureProvider();

        if (mUserManager.getUserInfo(mUserId).isManagedProfile()) {
+28 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.settings.notification.history;

import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS;
import static android.provider.Settings.Secure.NOTIFICATION_HISTORY_ENABLED;

import static androidx.core.view.accessibility.AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
@@ -25,9 +26,11 @@ import android.annotation.ColorInt;
import android.app.ActionBar;
import android.app.ActivityManager;
import android.app.INotificationManager;
import android.app.KeyguardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Outline;
@@ -58,6 +61,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.NotificationExpandButton;
import com.android.settings.R;
import com.android.settings.notification.NotificationBackend;
@@ -68,6 +72,7 @@ import com.android.settingslib.widget.MainSwitchBar;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@@ -113,6 +118,9 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
    };
    private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();

    // List of users that have the setting "hide sensitive content" enabled on the lockscreen
    private ArrayList<Integer> mContentRestrictedUsers = new ArrayList<>();

    enum NotificationHistoryEvent implements UiEventLogger.UiEventEnum {
        @UiEvent(doc = "User turned on notification history")
        NOTIFICATION_HISTORY_ON(504),
@@ -212,14 +220,14 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {

            final NotificationHistoryRecyclerView rv =
                    viewForPackage.findViewById(R.id.notification_list);
            rv.setAdapter(new NotificationHistoryAdapter(mNm, rv,
            rv.setAdapter(new NotificationHistoryAdapter(NotificationHistoryActivity.this, mNm, rv,
                    newCount -> {
                        count.setText(StringUtil.getIcuPluralsString(this, newCount,
                                R.string.notification_history_count));
                        if (newCount == 0) {
                            viewForPackage.setVisibility(View.GONE);
                        }
                    }, mUiEventLogger));
                    }, mUiEventLogger, mContentRestrictedUsers));
            ((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete(
                    new ArrayList<>(nhp.notifications));

@@ -263,6 +271,21 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {

        mPm = getPackageManager();
        mUm = getSystemService(UserManager.class);

        mContentRestrictedUsers.clear();
        List<UserInfo> users = mUm.getProfiles(getUserId());
        mContentRestrictedUsers.clear();
        for (UserInfo user : users) {
            if (Settings.Secure.getIntForUser(getContentResolver(),
                    LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, user.id) == 0) {
                LockPatternUtils lpu = new LockPatternUtils(this);
                KeyguardManager km = getSystemService(KeyguardManager.class);
                if (lpu.isSecure(user.id) && km.isDeviceLocked(user.id)) {
                    mContentRestrictedUsers.add(user.id);
                }
            }
        }

        // wait for history loading and recent/snooze loading
        mCountdownLatch = new CountDownLatch(2);

@@ -317,6 +340,7 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
        if (mCountdownFuture != null) {
            mCountdownFuture.cancel(true);
        }
        mContentRestrictedUsers.clear();
        super.onDestroy();
    }

@@ -406,7 +430,7 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
            mSnoozedRv.setLayoutManager(lm);
            mSnoozedRv.setAdapter(
                    new NotificationSbnAdapter(NotificationHistoryActivity.this, mPm, mUm,
                            true, mUiEventLogger));
                            true, mUiEventLogger, mContentRestrictedUsers));
            mSnoozedRv.setNestedScrollingEnabled(false);

            if (snoozed == null || snoozed.length == 0) {
@@ -422,7 +446,7 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
            mDismissedRv.setLayoutManager(dismissLm);
            mDismissedRv.setAdapter(
                    new NotificationSbnAdapter(NotificationHistoryActivity.this, mPm, mUm,
                            false, mUiEventLogger));
                            false, mUiEventLogger, mContentRestrictedUsers));
            mDismissedRv.setNestedScrollingEnabled(false);

            if (dismissed == null || dismissed.length == 0) {
+18 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.provider.Settings.EXTRA_CONVERSATION_ID;

import android.app.INotificationManager;
import android.app.NotificationHistory.HistoricalNotification;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
@@ -53,16 +54,23 @@ public class NotificationHistoryAdapter extends
    private List<HistoricalNotification> mValues;
    private OnItemDeletedListener mListener;
    private UiEventLogger mUiEventLogger;
    public NotificationHistoryAdapter(INotificationManager nm,
    private ArrayList<Integer> mContentRestrictedUsers = new ArrayList<>();
    Context mContext;

    public NotificationHistoryAdapter(Context context,
            INotificationManager nm,
            NotificationHistoryRecyclerView listView,
            OnItemDeletedListener listener,
            UiEventLogger uiEventLogger) {
            UiEventLogger uiEventLogger,
            ArrayList<Integer> contentRestrictedUsers) {
        mContext = context;
        mValues = new ArrayList<>();
        setHasStableIds(true);
        listView.setOnItemSwipeDeleteListener(this);
        mNm = nm;
        mListener = listener;
        mUiEventLogger = uiEventLogger;
        mContentRestrictedUsers = contentRestrictedUsers;
    }

    @Override
@@ -81,8 +89,14 @@ public class NotificationHistoryAdapter extends
    public void onBindViewHolder(final @NonNull NotificationHistoryViewHolder holder,
            int position) {
        final HistoricalNotification hn = mValues.get(position);
        // Redact sensitive notification content if needed
        if (mContentRestrictedUsers.contains(hn.getUserId())) {
            holder.setSummary(mContext.getString(
                    com.android.internal.R.string.notification_hidden_text));
        } else {
            holder.setTitle(hn.getTitle());
            holder.setSummary(hn.getText());
        }
        holder.setPostedTime(hn.getPostedTimeMs());
        final View.OnClickListener onClick = v -> {
            mUiEventLogger.logWithPosition(NotificationHistoryActivity.NotificationHistoryEvent
Loading