[nfc] Fix string injection in default payment app selector

Backwards compatible port of ag/35084316

Bug: 429417453
Test: Manually by installing settings app
Flag: EXEMPT security fix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:6c723a4361950e8e43cc5caf67455bd2f00911d1)
Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:b04265c1b84104884654d4957c5fb3a8ac84bc00
Merged-In: I670774a5efa6f543a5e1e06798a5d6ebb1c48c1d
Change-Id: I670774a5efa6f543a5e1e06798a5d6ebb1c48c1d
This commit is contained in:
James Eidson
2025-08-14 19:54:00 +00:00
committed by Android Build Coastguard Worker
parent 83447688f8
commit aa744e8988
2 changed files with 34 additions and 14 deletions

View File

@@ -17,7 +17,6 @@
package com.android.settings.nfc; package com.android.settings.nfc;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@@ -45,6 +44,9 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* DefaultPaymentSettings handles the NFC default payment app selection. * DefaultPaymentSettings handles the NFC default payment app selection.
@@ -53,7 +55,7 @@ public class DefaultPaymentSettings extends DefaultAppPickerFragment {
public static final String TAG = "DefaultPaymentSettings"; public static final String TAG = "DefaultPaymentSettings";
private PaymentBackend mPaymentBackend; private PaymentBackend mPaymentBackend;
private List<PaymentAppInfo> mAppInfos; private Map<String, PaymentAppInfo> mAppInfos;
private FooterPreference mFooterPreference; private FooterPreference mFooterPreference;
@Override @Override
@@ -67,22 +69,19 @@ public class DefaultPaymentSettings extends DefaultAppPickerFragment {
} }
@Override @Override
@SuppressWarnings("NullAway")
protected String getDefaultKey() { protected String getDefaultKey() {
PaymentAppInfo defaultAppInfo = mPaymentBackend.getDefaultApp(); PaymentAppInfo defaultAppInfo = mPaymentBackend.getDefaultApp();
if (defaultAppInfo != null) { if (defaultAppInfo == null) return null;
return defaultAppInfo.componentName.flattenToString() + " " return defaultAppInfo.getKey();
+ defaultAppInfo.userHandle.getIdentifier();
}
return null;
} }
@Override @Override
protected boolean setDefaultKey(String key) { protected boolean setDefaultKey(String key) {
String[] keys = key.split(" "); PaymentAppInfo appInfo = mAppInfos.get(key);
if (keys.length >= 2) { if (appInfo == null) return true;
mPaymentBackend.setDefaultPaymentApp(ComponentName.unflattenFromString(keys[0]), mPaymentBackend.setDefaultPaymentApp(
Integer.parseInt(keys[1])); appInfo.componentName, appInfo.userHandle.getIdentifier());
}
return true; return true;
} }
@@ -90,7 +89,9 @@ public class DefaultPaymentSettings extends DefaultAppPickerFragment {
public void onAttach(Context context) { public void onAttach(Context context) {
super.onAttach(context); super.onAttach(context);
mPaymentBackend = new PaymentBackend(getActivity()); mPaymentBackend = new PaymentBackend(getActivity());
mAppInfos = mPaymentBackend.getPaymentAppInfos(); mAppInfos = mPaymentBackend.getPaymentAppInfos()
.stream()
.collect(Collectors.toMap(PaymentAppInfo::getKey, Function.identity()));
} }
@Override @Override
@@ -147,7 +148,7 @@ public class DefaultPaymentSettings extends DefaultAppPickerFragment {
@Override @Override
protected List<? extends CandidateInfo> getCandidates() { protected List<? extends CandidateInfo> getCandidates() {
final List<NfcPaymentCandidateInfo> candidates = new ArrayList<>(); final List<NfcPaymentCandidateInfo> candidates = new ArrayList<>();
for (PaymentAppInfo appInfo: mAppInfos) { for (PaymentAppInfo appInfo: mAppInfos.values()) {
UserManager um = getContext().createContextAsUser( UserManager um = getContext().createContextAsUser(
appInfo.userHandle, /*flags=*/0).getSystemService(UserManager.class); appInfo.userHandle, /*flags=*/0).getSystemService(UserManager.class);
boolean isManagedProfile = um.isManagedProfile(appInfo.userHandle.getIdentifier()); boolean isManagedProfile = um.isManagedProfile(appInfo.userHandle.getIdentifier());

View File

@@ -36,6 +36,7 @@ import com.android.internal.content.PackageMonitor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
public class PaymentBackend { public class PaymentBackend {
public static final String TAG = "Settings.PaymentBackend"; public static final String TAG = "Settings.PaymentBackend";
@@ -52,6 +53,24 @@ public class PaymentBackend {
public ComponentName settingsComponent; public ComponentName settingsComponent;
public UserHandle userHandle; public UserHandle userHandle;
public Drawable icon; public Drawable icon;
public String getKey() {
return Integer.toString(hashCode());
}
@Override
public int hashCode() {
return Objects.hash(componentName, userHandle);
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof PaymentAppInfo)) return false;
PaymentAppInfo appInfo = (PaymentAppInfo) o;
return componentName.equals(appInfo.componentName)
&& userHandle.equals(appInfo.userHandle);
}
} }
/** /**