Adding Nfc Tag App Preference setting to special_access settings

In the settings app, allow users to change the preference of the Nfc Tag apps.

Bug: 244272155
Test: make RunSettingsRoboTests ROBOTEST_FILTER=NfcTagAppsPreferenceControllerTest
Change-Id: I28903fae8935613a0e8618da21ca44e98b8801d5
This commit is contained in:
George
2023-01-02 18:13:43 +08:00
parent a72e62b3a3
commit 2c5d1f8d29
12 changed files with 469 additions and 7 deletions

View File

@@ -6916,6 +6916,9 @@
<!-- List of synonyms for the always show time and info [CHAR LIMIT=NONE] -->
<string name="keywords_always_show_time_info">always on display, AOD</string>
<!-- List of synonyms for the nfc tag apps control [CHAR LIMIT=NONE] -->
<string name="keywords_change_nfc_tag_apps_state">nfc, tag, reader</string>
<!-- Summary for sound settings, explaining a few important settings under it [CHAR LIMIT=NONE]-->
<string name="sound_dashboard_summary">Volume, vibration, Do Not Disturb</string>
@@ -10238,6 +10241,15 @@
<!-- Apps > App Details > Wifi access > Description. [CHAR LIMIT=NONE] -->
<string name="change_wifi_state_app_detail_summary">Allow this app to turn Wi-Fi on or off, scan and connect to Wi-Fi networks, add or remove networks, or start a local-only hotspot</string>
<!-- Title for Nfc Tag apps control [CHAR LIMIT=35] -->
<string name="change_nfc_tag_apps_title">NFC Tag apps control</string>
<!-- Apps > App Details > Nfc Tag apps control > Switch title. [CHAR LIMIT=NONE] -->
<string name="change_nfc_tag_apps_detail_switch">Allow app to popup upon NFC tags detected</string>
<!-- Apps > App Details > Nfc Tag apps control > Description. [CHAR LIMIT=NONE] -->
<string name="change_nfc_tag_apps_detail_summary">Allow this app to launch and get tag contents when the device detests NFC tags</string>
<!-- Title for media output settings -->
<string name="media_output_title">Play media to</string>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="change_nfc_tag_apps"
android:title="@string/change_nfc_tag_apps_title">
<com.android.settings.widget.FilterTouchesSwitchPreference
android:key="app_ops_settings_switch"
android:title="@string/change_nfc_tag_apps_detail_switch"/>
<com.android.settingslib.widget.FooterPreference
android:key="app_ops_settings_preference"
android:title="@string/change_nfc_tag_apps_detail_summary"
android:selectable="false"/>
</PreferenceScreen>

View File

@@ -197,4 +197,15 @@
android:title="@string/special_access_more"
android:order="-100"
settings:controller="com.android.settings.applications.specialaccess.MoreSpecialAccessPreferenceController" />
<Preference
android:key="change_nfc_tag_apps_state"
android:title="@string/change_nfc_tag_apps_title"
android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
settings:keywords="@string/keywords_change_nfc_tag_apps_state"
settings:controller="com.android.settings.nfc.NfcTagAppsPreferenceController">
<extra
android:name="classname"
android:value="com.android.settings.Settings$ChangeNfcTagAppsActivity" />
</Preference>
</PreferenceScreen>

View File

@@ -348,6 +348,8 @@ public class Settings extends SettingsActivity {
public static class AppMediaManagementAppsActivity extends SettingsActivity { /* empty */ }
public static class WriteSettingsActivity extends SettingsActivity { /* empty */ }
public static class ChangeWifiStateActivity extends SettingsActivity { /* empty */ }
/** Activity to manage NFC Tag applications. */
public static class ChangeNfcTagAppsActivity extends SettingsActivity { /* empty */ }
public static class AppDrawOverlaySettingsActivity extends SettingsActivity { /* empty */ }
public static class AppWriteSettingsActivity extends SettingsActivity { /* empty */ }
/** Activity to manage app battery usage details. */

View File

@@ -32,6 +32,7 @@ import com.android.settings.applications.AppStateOverlayBridge;
import com.android.settings.applications.AppStatePowerBridge;
import com.android.settings.applications.AppStateUsageBridge;
import com.android.settings.applications.AppStateWriteSettingsBridge;
import com.android.settings.nfc.AppStateNfcTagAppsBridge;
import com.android.settings.wifi.AppStateChangeWifiStateBridge;
import com.android.settingslib.applications.ApplicationsState;
@@ -65,6 +66,7 @@ public class AppFilterRegistry {
FILTER_APPS_BATTERY_RESTRICTED,
FILTER_LONG_BACKGROUND_TASKS,
FILTER_APPS_CLONE,
FILTER_APPS_NFC_TAG,
})
@interface FilterType {}
@@ -95,8 +97,9 @@ public class AppFilterRegistry {
public static final int FILTER_APPS_BATTERY_RESTRICTED = 23;
public static final int FILTER_LONG_BACKGROUND_TASKS = 24;
public static final int FILTER_APPS_CLONE = 25;
// Next id: 26. If you add an entry here, please change NUM_FILTER_ENTRIES.
private static final int NUM_FILTER_ENTRIES = 26;
public static final int FILTER_APPS_NFC_TAG = 26;
private static final int NUM_FILTER_ENTRIES = 27;
// Next id: 27. If you add an entry here, please change NUM_FILTER_ENTRIES.
private static AppFilterRegistry sRegistry;
@@ -261,6 +264,13 @@ public class AppFilterRegistry {
AppStateClonedAppsBridge.FILTER_APPS_CLONE,
FILTER_APPS_CLONE,
R.string.cloned_apps_dashboard_title);
// Apps that are nfc tag allowlisted.
mFilters[FILTER_APPS_NFC_TAG] =
new AppFilterItem(
AppStateNfcTagAppsBridge.FILTER_APPS_NFC_TAG,
FILTER_APPS_NFC_TAG,
R.string.change_nfc_tag_apps_title);
}
public static AppFilterRegistry getInstance() {
@@ -301,6 +311,8 @@ public class AppFilterRegistry {
return FILTER_LONG_BACKGROUND_TASKS;
case ManageApplications.LIST_TYPE_CLONED_APPS:
return FILTER_APPS_CLONE;
case ManageApplications.LIST_TYPE_NFC_TAG_APPS:
return FILTER_APPS_NFC_TAG;
default:
return FILTER_APPS_ALL;
}

View File

@@ -99,6 +99,7 @@ import com.android.internal.jank.InteractionJankMonitor;
import com.android.settings.R;
import com.android.settings.Settings.AlarmsAndRemindersActivity;
import com.android.settings.Settings.AppBatteryUsageActivity;
import com.android.settings.Settings.ChangeNfcTagAppsActivity;
import com.android.settings.Settings.ChangeWifiStateActivity;
import com.android.settings.Settings.ClonedAppsListActivity;
import com.android.settings.Settings.HighPowerApplicationsActivity;
@@ -148,6 +149,8 @@ import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
import com.android.settings.fuelgauge.HighPowerDetail;
import com.android.settings.localepicker.AppLocalePickerActivity;
import com.android.settings.nfc.AppStateNfcTagAppsBridge;
import com.android.settings.nfc.ChangeNfcTagAppsStateDetails;
import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.notification.app.AppNotificationSettings;
@@ -264,6 +267,7 @@ public class ManageApplications extends InstrumentedFragment
public static final int LIST_TYPE_BATTERY_OPTIMIZATION = 15;
public static final int LIST_TYPE_LONG_BACKGROUND_TASKS = 16;
public static final int LIST_TYPE_CLONED_APPS = 17;
public static final int LIST_TYPE_NFC_TAG_APPS = 18;
// List types that should show instant apps.
public static final Set<Integer> LIST_TYPES_WITH_INSTANT = new ArraySet<>(Arrays.asList(
@@ -362,6 +366,9 @@ public class ManageApplications extends InstrumentedFragment
1); // USER_INTERACTED
}
break;
case LIST_TYPE_NFC_TAG_APPS:
mShowSystem = true;
break;
}
final AppFilterRegistry appFilterRegistry = AppFilterRegistry.getInstance();
mFilter = appFilterRegistry.get(appFilterRegistry.getDefaultFilterType(mListType));
@@ -560,6 +567,8 @@ public class ManageApplications extends InstrumentedFragment
return SettingsEnums.LONG_BACKGROUND_TASKS;
case LIST_TYPE_CLONED_APPS:
return SettingsEnums.CLONED_APPS;
case LIST_TYPE_NFC_TAG_APPS:
return SettingsEnums.CONFIG_NFC_TAG_APP_PREF;
default:
return SettingsEnums.PAGE_UNKNOWN;
}
@@ -629,10 +638,9 @@ public class ManageApplications extends InstrumentedFragment
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
if (mListType == LIST_TYPE_NOTIFICATION) {
mApplications.mExtraInfoBridge.forceUpdate(mCurrentPkgName, mCurrentUid);
} else if (mListType == LIST_TYPE_HIGH_POWER || mListType == LIST_TYPE_OVERLAY
|| mListType == LIST_TYPE_WRITE_SETTINGS) {
if (mListType == LIST_TYPE_NOTIFICATION || mListType == LIST_TYPE_HIGH_POWER
|| mListType == LIST_TYPE_OVERLAY || mListType == LIST_TYPE_WRITE_SETTINGS
|| mListType == LIST_TYPE_NFC_TAG_APPS) {
mApplications.mExtraInfoBridge.forceUpdate(mCurrentPkgName, mCurrentUid);
} else {
mApplicationsState.requestSize(mCurrentPkgName, UserHandle.getUserId(mCurrentUid));
@@ -727,6 +735,10 @@ public class ManageApplications extends InstrumentedFragment
.getRoute(mCurrentPkgName, userId));
}
break;
case LIST_TYPE_NFC_TAG_APPS:
startAppInfoFragment(ChangeNfcTagAppsStateDetails.class,
R.string.change_nfc_tag_apps_title);
break;
// TODO: Figure out if there is a way where we can spin up the profile's settings
// process ahead of time, to avoid a long load of data when user clicks on a managed
// app. Maybe when they load the list of apps that contains managed profile apps.
@@ -1052,6 +1064,8 @@ public class ManageApplications extends InstrumentedFragment
screenTitle = R.string.long_background_tasks_title;
} else if (className.equals(ClonedAppsListActivity.class.getName())) {
screenTitle = R.string.cloned_apps_dashboard_title;
} else if (className.equals(ChangeNfcTagAppsActivity.class.getName())) {
screenTitle = R.string.change_nfc_tag_apps_title;
} else {
if (screenTitle == -1) {
screenTitle = R.string.all_apps;
@@ -1260,6 +1274,8 @@ public class ManageApplications extends InstrumentedFragment
mExtraInfoBridge = new AppStateLongBackgroundTasksBridge(mContext, mState, this);
} else if (mManageApplications.mListType == LIST_TYPE_CLONED_APPS) {
mExtraInfoBridge = new AppStateClonedAppsBridge(mContext, mState, this);
} else if (mManageApplications.mListType == LIST_TYPE_NFC_TAG_APPS) {
mExtraInfoBridge = new AppStateNfcTagAppsBridge(mContext, mState, this);
} else {
mExtraInfoBridge = null;
}
@@ -1810,6 +1826,10 @@ public class ManageApplications extends InstrumentedFragment
case LIST_TYPE_CLONED_APPS:
holder.setSummary(null);
break;
case LIST_TYPE_NFC_TAG_APPS:
holder.setSummary(
ChangeNfcTagAppsStateDetails.getSummary(mContext, entry));
break;
default:
holder.updateSizeText(entry, mManageApplications.mInvalidSizeStr, mWhichSize);
break;

View File

@@ -20,6 +20,7 @@ import android.content.Context
import android.util.FeatureFlagUtils
import com.android.settings.Settings.AlarmsAndRemindersActivity
import com.android.settings.Settings.AppBatteryUsageActivity
import com.android.settings.Settings.ChangeNfcTagAppsActivity
import com.android.settings.Settings.ChangeWifiStateActivity
import com.android.settings.Settings.ClonedAppsListActivity
import com.android.settings.Settings.GamesStorageActivity
@@ -46,6 +47,7 @@ import com.android.settings.applications.manageapplications.ManageApplications.L
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MANAGE_SOURCES
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MEDIA_MANAGEMENT_APPS
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NFC_TAG_APPS
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_OVERLAY
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_STORAGE
@@ -85,6 +87,7 @@ object ManageApplicationsUtil {
AppBatteryUsageActivity::class to LIST_TYPE_BATTERY_OPTIMIZATION,
LongBackgroundTasksActivity::class to LIST_TYPE_LONG_BACKGROUND_TASKS,
ClonedAppsListActivity::class to LIST_TYPE_CLONED_APPS,
ChangeNfcTagAppsActivity::class to LIST_TYPE_NFC_TAG_APPS,
)
@JvmField

View File

@@ -0,0 +1,136 @@
/*
* 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.nfc;
import static com.android.settingslib.applications.ApplicationsState.AppEntry;
import static com.android.settingslib.applications.ApplicationsState.AppFilter;
import android.app.ActivityManager;
import android.content.Context;
import android.nfc.NfcAdapter;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import com.android.settings.applications.AppStateBaseBridge;
import com.android.settingslib.applications.ApplicationsState;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Filter to display only in the Tag preference listed Apps on Nfc Tag Apps page.
*/
public class AppStateNfcTagAppsBridge extends AppStateBaseBridge{
private static final String TAG = "AppStateNfcTagAppsBridge";
private final Context mContext;
private final NfcAdapter mNfcAdapter;
// preference list cache
private static Map<Integer, Map<String, Boolean>> sList = new HashMap<>();
public AppStateNfcTagAppsBridge(Context context, ApplicationsState appState,
Callback callback) {
super(appState, callback);
mContext = context;
mNfcAdapter = NfcAdapter.getDefaultAdapter(mContext);
if (mNfcAdapter != null && mNfcAdapter.isTagIntentAppPreferenceSupported()) {
UserManager um = mContext.createContextAsUser(
UserHandle.of(ActivityManager.getCurrentUser()), 0)
.getSystemService(UserManager.class);
List<UserHandle> luh = um.getEnabledProfiles();
for (UserHandle uh : luh) {
int userId = uh.getIdentifier();
sList.put(userId, mNfcAdapter.getTagIntentAppPreferenceForUser(userId));
}
}
}
/**
* Update the system and cached tag app preference lists.
*/
public boolean updateApplist(int userId, String pkg, boolean allowed) {
if (mNfcAdapter.setTagIntentAppPreferenceForUser(
userId, pkg, allowed) == NfcAdapter.TAG_INTENT_APP_PREF_RESULT_SUCCESS) {
sList.put(userId, mNfcAdapter.getTagIntentAppPreferenceForUser(userId));
return true;
} else {
return false;
}
}
@Override
protected void loadAllExtraInfo() {
final List<ApplicationsState.AppEntry> allApps = mAppSession.getAllApps();
for (int i = 0; i < allApps.size(); i++) {
ApplicationsState.AppEntry app = allApps.get(i);
this.updateExtraInfo(app, app.info.packageName, app.info.uid);
}
}
@Override
protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
// Display package if is in the app preference list.
int userId = UserHandle.getUserId(uid);
Map<String, Boolean> map = sList.getOrDefault(userId, new HashMap<>());
if (map.containsKey(pkg)) {
app.extraInfo = new NfcTagAppState(/* exist */ true, /* allowed */ map.get(pkg));
} else {
app.extraInfo = new NfcTagAppState(/* exist */ false, /* allowed */ false);
}
}
/**
* Class to denote the nfc tag app preference state of the AppEntry
*/
public static class NfcTagAppState {
private boolean mIsExisted;
private boolean mIsAllowed;
public NfcTagAppState(boolean exist, boolean allowed) {
mIsExisted = exist;
mIsAllowed = allowed;
}
public boolean isExisted() {
return mIsExisted;
}
public boolean isAllowed() {
return mIsAllowed;
}
}
public static final AppFilter FILTER_APPS_NFC_TAG =
new AppFilter() {
@Override
public void init() {
}
@Override
public boolean filterApp(AppEntry entry) {
if (entry.extraInfo == null) {
Log.d(TAG, "[" + entry.info.packageName + "]" + " has No extra info.");
return false;
}
NfcTagAppState state = (NfcTagAppState) entry.extraInfo;
return state.isExisted();
}
};
}

View File

@@ -0,0 +1,118 @@
/*
* 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.nfc;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.applications.AppInfoWithHeader;
import com.android.settings.nfc.AppStateNfcTagAppsBridge.NfcTagAppState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
/**
* Class for displaying app info of the Nfc Tag App
*/
public class ChangeNfcTagAppsStateDetails extends AppInfoWithHeader
implements OnPreferenceChangeListener {
private static final String KEY_APP_OPS_SETTINGS_SWITCH = "app_ops_settings_switch";
private static final String LOG_TAG = "ChangeNfcTagAppsStateDetails";
private AppStateNfcTagAppsBridge mAppBridge;
private SwitchPreference mSwitchPref;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Context context = getActivity();
mAppBridge = new AppStateNfcTagAppsBridge(context, mState, null);
// find preferences
addPreferencesFromResource(R.xml.change_nfc_tag_apps_details);
mSwitchPref = (SwitchPreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
// set title/summary for all of them
mSwitchPref.setTitle(R.string.change_nfc_tag_apps_detail_switch);
// install event listeners
mSwitchPref.setOnPreferenceChangeListener(this);
}
@Override
protected AlertDialog createDialog(int id, int errorCode) {
return null;
}
@Override
public int getMetricsCategory() {
return SettingsEnums.CONFIG_NFC_TAG_APP_PREF;
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Boolean enable = (Boolean) newValue;
if (preference == mSwitchPref) {
if (mAppBridge != null && mAppBridge.updateApplist(mUserId, mPackageName, enable)) {
refreshUi();
return true;
} else {
Log.e(LOG_TAG, "Set [" + mPackageName + "]" + " failed.");
return false;
}
}
return false;
}
@Override
protected boolean refreshUi() {
if (mPackageInfo == null || mPackageInfo.applicationInfo == null) {
return false;
}
retrieveAppEntry();
NfcTagAppState state;
if (mAppEntry.extraInfo instanceof NfcTagAppState) {
state = (NfcTagAppState) mAppEntry.extraInfo;
} else {
state = new NfcTagAppState(/* exist */ false, /* allowed */ false);
}
mSwitchPref.setChecked(state.isAllowed());
mSwitchPref.setEnabled(state.isExisted());
return true;
}
/** Returns the summary string for this setting preference. */
public static CharSequence getSummary(Context context, AppEntry entry) {
NfcTagAppState state;
if (entry.extraInfo instanceof NfcTagAppState) {
state = (NfcTagAppState) entry.extraInfo;
} else {
state = new NfcTagAppState(/* exist */ false, /* allowed */ false);
}
return context.getString(state.isAllowed()
? R.string.app_permission_summary_allowed
: R.string.app_permission_summary_not_allowed);
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.nfc;
import android.content.Context;
import android.nfc.NfcAdapter;
import com.android.settings.core.BasePreferenceController;
/**
* A PreferenceController handling the logic for the Nfc Tag App preference
*/
public class NfcTagAppsPreferenceController extends BasePreferenceController {
private NfcAdapter mNfcAdapter;
public NfcTagAppsPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mNfcAdapter = NfcAdapter.getDefaultAdapter(context.getApplicationContext());
}
@Override
public int getAvailabilityStatus() {
if (mNfcAdapter != null) {
return mNfcAdapter.isTagIntentAppPreferenceSupported()
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
return UNSUPPORTED_ON_DEVICE;
}
}

View File

@@ -0,0 +1,66 @@
/*
* 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.nfc;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import android.content.Context;
import android.nfc.NfcAdapter;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.testutils.shadow.ShadowNfcAdapter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowNfcAdapter.class)
public class NfcTagAppsPreferenceControllerTest {
private NfcTagAppsPreferenceController mController;
private static final String KEY = "key";
private ShadowNfcAdapter mShadowNfcAdapter;
private Context mContext;
@Before
public void setUp() {
mContext = spy(ApplicationProvider.getApplicationContext());
mController = new NfcTagAppsPreferenceController(mContext, KEY);
mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext));
}
@Test
public void getAvailabilityStatus_featureNotEnabled_shouldNotReturnAvailable() {
mShadowNfcAdapter.setTagIntentAppPreferenceSupported(false);
assertThat(mController.getAvailabilityStatus()).isNotEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_featureEnabled_shouldReturnAvailable() {
mShadowNfcAdapter.setTagIntentAppPreferenceSupported(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
}

View File

@@ -38,6 +38,7 @@ public class ShadowNfcAdapter extends org.robolectric.shadows.ShadowNfcAdapter {
private boolean mIsNfcEnabled = false;
private int mState = NfcAdapter.STATE_ON;
private boolean mIsSecureNfcSupported = false;
private boolean mIsTagIntentAppPreferenceSupported = false;
@Implementation
protected void enableReaderMode(Activity activity, NfcAdapter.ReaderCallback callback,
@@ -97,4 +98,13 @@ public class ShadowNfcAdapter extends org.robolectric.shadows.ShadowNfcAdapter {
public static void reset() {
sReaderModeEnabled = false;
}
}
public void setTagIntentAppPreferenceSupported(boolean supported) {
mIsTagIntentAppPreferenceSupported = supported;
}
@Implementation
protected boolean isTagIntentAppPreferenceSupported() {
return mIsTagIntentAppPreferenceSupported;
}
}