Snap for 12032182 from 1d838f62ea to 24Q4-release
Change-Id: I612f427a24db345e0c0f3c316d7f1c937ed18b33
This commit is contained in:
@@ -1427,6 +1427,19 @@
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".Settings$ManageAdaptiveNotificationsActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.settings.MANAGE_ADAPTIVE_NOTIFICATIONS"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.notification.PoliteNotificationsPreferenceFragment" />
|
||||
<meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
|
||||
android:value="@string/menu_key_notifications"/>
|
||||
</activity>
|
||||
|
||||
<activity android:name="Settings$WallpaperSettingsActivity"
|
||||
android:label="@string/wallpaper_settings_fragment_title"
|
||||
android:icon="@drawable/ic_wallpaper"
|
||||
|
||||
@@ -65,3 +65,6 @@
|
||||
-keep class androidx.window.extensions.** { *; }
|
||||
-dontwarn androidx.window.extensions.**
|
||||
-keep class androidx.window.** { *; }
|
||||
|
||||
# Keep the com.android.settings.media_drm.FakeFeatureFlagsImpl
|
||||
-keep class com.android.settings.media_drm.FakeFeatureFlagsImpl { *; }
|
||||
|
||||
@@ -12383,7 +12383,7 @@
|
||||
<!-- Toast on failure to reformat data to ext4 -->
|
||||
<string name="format_ext4_failure_toast">Failed to reformat and wipe the data partition to ext4.</string>
|
||||
<!-- Dialog to OEM unlock the device before using 16K developer option -->
|
||||
<string name="confirm_oem_unlock_for_16k_title">Bootloader Unlock Required for 16KB Mode</string>
|
||||
<string name="confirm_oem_unlock_for_16k_title">Bootloader Unlock Required</string>
|
||||
<string name="confirm_oem_unlock_for_16k_text">This device needs to have the bootloader unlocked before using the 16KB developer option.
|
||||
Software integrity cannot be guaranteed in this mode, and any data stored on the phone while the bootloader is unlocked may be at risk.
|
||||
All user data and settings will be wiped when activating 16KB mode. Once the bootloader is unlocked, activating the 16KB option will require two reboots.
|
||||
@@ -12412,10 +12412,10 @@
|
||||
<!-- persistent notification 16k page agnostic mode text -->
|
||||
<string name="page_agnostic_16k_pages_text_short">You are in the 16KB mode of the page-agnostic mode. Software integrity cannot be guaranteed in this mode,
|
||||
and any data stored on the phone while the bootloader is unlocked may be at risk. Some features will be disabled in these modes, so some applications may not work.
|
||||
In order to re-enter the production mode, you must, switch back to 4K mode and then lock the bootloader of the device. Tap to read more.</string>
|
||||
In order to re-enter the production mode, you must, switch back to 4KB mode and then lock the bootloader of the device. Tap to read more.</string>
|
||||
<string name="page_agnostic_16k_pages_text">You are in the 16KB mode of the page-agnostic mode. Software integrity cannot be guaranteed in this mode,
|
||||
and any data stored on the phone while the bootloader is unlocked may be at risk. Some features will be disabled in these modes, so some applications may not work.
|
||||
In order to re-enter the production mode, you must, switch back to 4K mode and then lock the bootloader of the device. This would factory reset the device again and
|
||||
In order to re-enter the production mode, you must, switch back to 4KB mode and then lock the bootloader of the device. This would factory reset the device again and
|
||||
restore it to production settings. After the device successfully boots into Android, disable OEM unlocking in Developer options.
|
||||
If the device fails to boot into Android or is unstable, re-flash the device with the latest factory images from
|
||||
<a href=\"https://developers.google.com/android/images\">https://developers.google.com/android/images</a>
|
||||
|
||||
@@ -303,6 +303,7 @@ public class Settings extends SettingsActivity {
|
||||
public static class UserSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class NotificationAccessSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class NotificationAccessDetailsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class ManageAdaptiveNotificationsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class VrListenersSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class PremiumSmsAccessActivity extends SettingsActivity { /* empty */ }
|
||||
public static class PictureInPictureSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
|
||||
@@ -156,6 +156,7 @@ import com.android.settings.nfc.PaymentSettings;
|
||||
import com.android.settings.notification.ConfigureNotificationSettings;
|
||||
import com.android.settings.notification.NotificationAccessSettings;
|
||||
import com.android.settings.notification.NotificationAssistantPicker;
|
||||
import com.android.settings.notification.PoliteNotificationsPreferenceFragment;
|
||||
import com.android.settings.notification.SoundSettings;
|
||||
import com.android.settings.notification.app.AppBubbleNotificationSettings;
|
||||
import com.android.settings.notification.app.AppNotificationSettings;
|
||||
@@ -314,6 +315,7 @@ public class SettingsGateway {
|
||||
AppInfoDashboardFragment.class.getName(),
|
||||
BatterySaverSettings.class.getName(),
|
||||
AppNotificationSettings.class.getName(),
|
||||
PoliteNotificationsPreferenceFragment.class.getName(),
|
||||
NotificationAssistantPicker.class.getName(),
|
||||
ChannelNotificationSettings.class.getName(),
|
||||
SatelliteSetting.class.getName(),
|
||||
|
||||
@@ -33,13 +33,10 @@ import com.android.settings.R
|
||||
import com.android.settings.dashboard.DashboardFragment
|
||||
import com.android.settings.datausage.lib.BillingCycleRepository
|
||||
import com.android.settings.datausage.lib.NetworkUsageData
|
||||
import com.android.settings.network.MobileNetworkRepository
|
||||
import com.android.settings.network.SubscriptionUtil
|
||||
import com.android.settings.network.telephony.requireSubscriptionManager
|
||||
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity
|
||||
import com.android.settings.network.telephony.SubscriptionRepository
|
||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||
import com.android.settingslib.spaprivileged.framework.common.userManager
|
||||
import com.android.settingslib.utils.ThreadUtils
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
/**
|
||||
@@ -59,7 +56,6 @@ open class DataUsageList : DashboardFragment() {
|
||||
private lateinit var billingCycleRepository: BillingCycleRepository
|
||||
|
||||
private var usageAmount: Preference? = null
|
||||
private var subscriptionInfoEntity: SubscriptionInfoEntity? = null
|
||||
private var dataUsageListAppsController: DataUsageListAppsController? = null
|
||||
private var chartDataUsagePreferenceController: ChartDataUsagePreferenceController? = null
|
||||
private var dataUsageListHeaderController: DataUsageListHeaderController? = null
|
||||
@@ -90,7 +86,6 @@ open class DataUsageList : DashboardFragment() {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
updateSubscriptionInfoEntity()
|
||||
dataUsageListAppsController = use(DataUsageListAppsController::class.java).apply {
|
||||
init(template)
|
||||
}
|
||||
@@ -132,6 +127,16 @@ open class DataUsageList : DashboardFragment() {
|
||||
viewModel.chartDataFlow.collectLatestWithLifecycle(viewLifecycleOwner) { chartData ->
|
||||
chartDataUsagePreferenceController?.update(chartData)
|
||||
}
|
||||
finishIfSubscriptionDisabled()
|
||||
}
|
||||
|
||||
private fun finishIfSubscriptionDisabled() {
|
||||
if (SubscriptionManager.isUsableSubscriptionId(subId)) {
|
||||
SubscriptionRepository(requireContext()).isSubscriptionEnabledFlow(subId)
|
||||
.collectLatestWithLifecycle(viewLifecycleOwner) { isSubscriptionEnabled ->
|
||||
if (!isSubscriptionEnabled) finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPreferenceScreenResId() = R.xml.data_usage_list
|
||||
@@ -155,23 +160,12 @@ open class DataUsageList : DashboardFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSubscriptionInfoEntity() {
|
||||
ThreadUtils.postOnBackgroundThread {
|
||||
subscriptionInfoEntity =
|
||||
MobileNetworkRepository.getInstance(context).getSubInfoById(subId.toString())
|
||||
}
|
||||
}
|
||||
|
||||
/** Update chart sweeps and cycle list to reflect [NetworkPolicy] for current [template]. */
|
||||
private fun updatePolicy(isModifiable: Boolean) {
|
||||
val isBillingCycleModifiable = isModifiable && isActiveSubscription()
|
||||
dataUsageListHeaderController?.setConfigButtonVisible(isBillingCycleModifiable)
|
||||
chartDataUsagePreferenceController?.setBillingCycleModifiable(isBillingCycleModifiable)
|
||||
dataUsageListHeaderController?.setConfigButtonVisible(isModifiable)
|
||||
chartDataUsagePreferenceController?.setBillingCycleModifiable(isModifiable)
|
||||
}
|
||||
|
||||
private fun isActiveSubscription(): Boolean =
|
||||
requireContext().requireSubscriptionManager().getActiveSubscriptionInfo(subId) != null
|
||||
|
||||
/**
|
||||
* Updates the chart and detail data when initial loaded or selected cycle changed.
|
||||
*/
|
||||
@@ -187,7 +181,7 @@ open class DataUsageList : DashboardFragment() {
|
||||
/** Updates applications data usage. */
|
||||
private fun updateApps(usageData: NetworkUsageData) {
|
||||
dataUsageListAppsController?.update(
|
||||
carrierId = subscriptionInfoEntity?.carrierId,
|
||||
subId = subId,
|
||||
startTime = usageData.startTime,
|
||||
endTime = usageData.endTime,
|
||||
)
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.app.ActivityManager
|
||||
import android.content.Context
|
||||
import android.net.NetworkTemplate
|
||||
import android.os.Bundle
|
||||
import android.telephony.SubscriptionManager
|
||||
import androidx.annotation.OpenForTesting
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
@@ -32,6 +33,7 @@ import com.android.settings.core.BasePreferenceController
|
||||
import com.android.settings.core.SubSettingLauncher
|
||||
import com.android.settings.datausage.lib.AppDataUsageRepository
|
||||
import com.android.settings.datausage.lib.NetworkUsageData
|
||||
import com.android.settings.network.telephony.requireSubscriptionManager
|
||||
import com.android.settingslib.AppItem
|
||||
import com.android.settingslib.net.UidDetailProvider
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -74,8 +76,11 @@ open class DataUsageListAppsController(context: Context, preferenceKey: String)
|
||||
this.cycleData = cycleData
|
||||
}
|
||||
|
||||
fun update(carrierId: Int?, startTime: Long, endTime: Long) = lifecycleScope.launch {
|
||||
fun update(subId: Int, startTime: Long, endTime: Long) = lifecycleScope.launch {
|
||||
val apps = withContext(Dispatchers.Default) {
|
||||
val carrierId = if (SubscriptionManager.isValidSubscriptionId(subId)) {
|
||||
mContext.requireSubscriptionManager().getActiveSubscriptionInfo(subId)?.carrierId
|
||||
} else null
|
||||
repository.getAppPercent(carrierId, startTime, endTime).map { (appItem, percent) ->
|
||||
AppDataUsagePreference(mContext, appItem, percent, uidDetailProvider).apply {
|
||||
setOnPreferenceClickListener {
|
||||
|
||||
@@ -96,13 +96,13 @@ public class PageAgnosticNotificationService extends Service {
|
||||
notifyPendingIntent)
|
||||
.build();
|
||||
|
||||
// TODO:(b/349860833) Change text style to BigTextStyle once the ellipsis issue is fixed.
|
||||
Notification.Builder builder =
|
||||
new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
|
||||
.setContentTitle(title)
|
||||
.setContentText(text)
|
||||
.setOngoing(true)
|
||||
.setSmallIcon(R.drawable.ic_settings_24dp)
|
||||
.setStyle(new Notification.BigTextStyle().bigText(text))
|
||||
.setContentIntent(notifyPendingIntent)
|
||||
.addAction(action);
|
||||
|
||||
|
||||
@@ -53,7 +53,8 @@ public class BatteryInfo {
|
||||
public int batteryStatus;
|
||||
public int pluggedStatus;
|
||||
public boolean discharging = true;
|
||||
public boolean isBatteryDefender;
|
||||
public boolean isBatteryDefender = false;
|
||||
public boolean isLongLife = false;
|
||||
public boolean isFastCharging;
|
||||
public long remainingTimeUs = 0;
|
||||
public long averageTimeToDischarge = EstimateKt.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN;
|
||||
@@ -306,7 +307,7 @@ public class BatteryInfo {
|
||||
info.pluggedStatus = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
|
||||
info.mCharging = info.pluggedStatus != 0;
|
||||
info.averageTimeToDischarge = estimate.getAverageDischargeTime();
|
||||
info.isBatteryDefender =
|
||||
info.isLongLife =
|
||||
batteryBroadcast.getIntExtra(
|
||||
BatteryManager.EXTRA_CHARGING_STATUS,
|
||||
BatteryManager.CHARGING_POLICY_DEFAULT)
|
||||
@@ -319,7 +320,7 @@ public class BatteryInfo {
|
||||
info.isFastCharging =
|
||||
BatteryStatus.getChargingSpeed(context, batteryBroadcast)
|
||||
== BatteryStatus.CHARGING_FAST;
|
||||
if (info.isBatteryDefender) {
|
||||
if (info.isLongLife) {
|
||||
info.isBatteryDefender =
|
||||
FeatureFactory.getFeatureFactory()
|
||||
.getPowerUsageFeatureProvider()
|
||||
|
||||
@@ -600,12 +600,12 @@ public class BatteryUtils {
|
||||
context.getContentResolver(), SETTINGS_GLOBAL_DOCK_DEFENDER_BYPASS, 0)
|
||||
== 1) {
|
||||
return DockDefenderMode.TEMPORARILY_BYPASSED;
|
||||
} else if (batteryInfo.isBatteryDefender
|
||||
} else if (batteryInfo.isLongLife
|
||||
&& FeatureFactory.getFeatureFactory()
|
||||
.getPowerUsageFeatureProvider()
|
||||
.isExtraDefend()) {
|
||||
return DockDefenderMode.ACTIVE;
|
||||
} else if (!batteryInfo.isBatteryDefender) {
|
||||
} else if (!batteryInfo.isLongLife) {
|
||||
return DockDefenderMode.FUTURE_BYPASS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider
|
||||
|
||||
@Override
|
||||
public boolean isBatteryDefend(BatteryInfo info) {
|
||||
return info.isBatteryDefender && !isExtraDefend();
|
||||
return info.isLongLife && !isExtraDefend();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.content.Context;
|
||||
import com.android.settings.fuelgauge.BatteryInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryDefenderTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
/** Detect whether the battery is overheated */
|
||||
public class BatteryDefenderDetector implements BatteryTipDetector {
|
||||
@@ -35,12 +34,10 @@ public class BatteryDefenderDetector implements BatteryTipDetector {
|
||||
|
||||
@Override
|
||||
public BatteryTip detect() {
|
||||
final boolean isBasicBatteryDefend =
|
||||
FeatureFactory.getFeatureFactory()
|
||||
.getPowerUsageFeatureProvider()
|
||||
.isBatteryDefend(mBatteryInfo);
|
||||
final int state =
|
||||
isBasicBatteryDefend ? BatteryTip.StateType.NEW : BatteryTip.StateType.INVISIBLE;
|
||||
mBatteryInfo.isBatteryDefender
|
||||
? BatteryTip.StateType.NEW
|
||||
: BatteryTip.StateType.INVISIBLE;
|
||||
final boolean isPluggedIn = mBatteryInfo.pluggedStatus != 0;
|
||||
return new BatteryDefenderTip(state, isPluggedIn);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
|
||||
import com.android.internal.telephony.flags.Flags;
|
||||
import com.android.settings.network.telephony.MobileNetworkUtils;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.mobile.dataservice.MobileNetworkDatabase;
|
||||
@@ -435,7 +434,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
mMetricsFeatureProvider.action(mContext,
|
||||
SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_SUB_INFO, subId);
|
||||
insertUiccInfo(subId, telephonyManager);
|
||||
insertMobileNetworkInfo(context, subId, telephonyManager);
|
||||
insertMobileNetworkInfo(subId, telephonyManager);
|
||||
}
|
||||
} else if (DEBUG) {
|
||||
Log.d(TAG, "Can not insert subInfo, the entity is null");
|
||||
@@ -517,20 +516,13 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
}
|
||||
}
|
||||
|
||||
private void insertMobileNetworkInfo(Context context, int subId,
|
||||
TelephonyManager telephonyManager) {
|
||||
MobileNetworkInfoEntity mobileNetworkInfoEntity = convertToMobileNetworkInfoEntity(context,
|
||||
subId, telephonyManager);
|
||||
|
||||
private void insertMobileNetworkInfo(int subId, TelephonyManager telephonyManager) {
|
||||
MobileNetworkInfoEntity mobileNetworkInfoEntity =
|
||||
convertToMobileNetworkInfoEntity(subId, telephonyManager);
|
||||
|
||||
Log.d(TAG, "insertMobileNetworkInfo, mobileNetworkInfoEntity = "
|
||||
+ mobileNetworkInfoEntity);
|
||||
|
||||
|
||||
if (mobileNetworkInfoEntity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sCacheMobileNetworkInfoEntityMap.containsKey(subId)
|
||||
|| !sCacheMobileNetworkInfoEntityMap.get(subId).equals(mobileNetworkInfoEntity)) {
|
||||
sCacheMobileNetworkInfoEntityMap.put(subId, mobileNetworkInfoEntity);
|
||||
@@ -540,7 +532,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
}
|
||||
}
|
||||
|
||||
private MobileNetworkInfoEntity convertToMobileNetworkInfoEntity(Context context, int subId,
|
||||
private MobileNetworkInfoEntity convertToMobileNetworkInfoEntity(int subId,
|
||||
TelephonyManager telephonyManager) {
|
||||
boolean isDataEnabled = false;
|
||||
if (telephonyManager != null) {
|
||||
@@ -549,18 +541,8 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
Log.d(TAG, "TelephonyManager is null, subId = " + subId);
|
||||
}
|
||||
|
||||
return new MobileNetworkInfoEntity(String.valueOf(subId),
|
||||
MobileNetworkUtils.isContactDiscoveryEnabled(context, subId),
|
||||
MobileNetworkUtils.isContactDiscoveryVisible(context, subId),
|
||||
isDataEnabled,
|
||||
MobileNetworkUtils.isCdmaOptions(context, subId),
|
||||
MobileNetworkUtils.isGsmOptions(context, subId),
|
||||
MobileNetworkUtils.isWorldMode(context, subId),
|
||||
MobileNetworkUtils.shouldDisplayNetworkSelectOptions(context, subId),
|
||||
MobileNetworkUtils.isTdscdmaSupported(context, subId),
|
||||
MobileNetworkUtils.activeNetworkIsCellular(context),
|
||||
SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager),
|
||||
/* deprecated isDataRoamingEnabled = */ false
|
||||
return new MobileNetworkInfoEntity(String.valueOf(subId), isDataEnabled,
|
||||
SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -681,8 +663,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
public void onUserMobileDataStateChanged(boolean enabled) {
|
||||
Log.d(TAG, "onUserMobileDataStateChanged enabled " + enabled + " on SUB " + mSubId);
|
||||
sExecutor.execute(() -> {
|
||||
insertMobileNetworkInfo(mContext, mSubId,
|
||||
getTelephonyManagerBySubId(mContext, mSubId));
|
||||
insertMobileNetworkInfo(mSubId, getTelephonyManagerBySubId(mContext, mSubId));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.os.PowerManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.EventLog;
|
||||
@@ -370,7 +371,7 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
mDataUsagePreference = findPreference(PREF_KEY_DATA_USAGE);
|
||||
mDataUsagePreference.setVisible(DataUsageUtils.hasWifiRadio(getContext()));
|
||||
mDataUsagePreference.setTemplate(new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI)
|
||||
.build(), 0 /*subId*/);
|
||||
.build(), SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
mResetInternetPreference = findPreference(PREF_KEY_RESET_INTERNET);
|
||||
if (mResetInternetPreference != null) {
|
||||
mResetInternetPreference.setVisible(false);
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.search;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settingslib.search.SearchIndexableResources;
|
||||
import com.android.settingslib.search.SearchIndexableResourcesMobile;
|
||||
|
||||
/**
|
||||
* FeatureProvider for the refactored search code.
|
||||
*/
|
||||
public class SearchFeatureProviderImpl implements SearchFeatureProvider {
|
||||
|
||||
private SearchIndexableResources mSearchIndexableResources;
|
||||
|
||||
@Override
|
||||
public void verifyLaunchSearchResultPageCaller(@NonNull Context context,
|
||||
@NonNull String callerPackage) {
|
||||
if (TextUtils.isEmpty(callerPackage)) {
|
||||
throw new IllegalArgumentException("ExternalSettingsTrampoline intents "
|
||||
+ "must be called with startActivityForResult");
|
||||
}
|
||||
final boolean isSettingsPackage = TextUtils.equals(callerPackage, context.getPackageName())
|
||||
|| TextUtils.equals(getSettingsIntelligencePkgName(context), callerPackage);
|
||||
final boolean isAllowlistedPackage = isSignatureAllowlisted(context, callerPackage);
|
||||
if (isSettingsPackage || isAllowlistedPackage) {
|
||||
return;
|
||||
}
|
||||
throw new SecurityException("Search result intents must be called with from an "
|
||||
+ "allowlisted package.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchIndexableResources getSearchIndexableResources() {
|
||||
if (mSearchIndexableResources == null) {
|
||||
mSearchIndexableResources = new SearchIndexableResourcesMobile();
|
||||
}
|
||||
return mSearchIndexableResources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent buildSearchIntent(Context context, int pageId) {
|
||||
return new Intent(Settings.ACTION_APP_SEARCH_SETTINGS)
|
||||
.setPackage(getSettingsIntelligencePkgName(context))
|
||||
.putExtra(Intent.EXTRA_REFERRER, buildReferrer(context, pageId));
|
||||
}
|
||||
|
||||
protected boolean isSignatureAllowlisted(Context context, String callerPackage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Uri buildReferrer(Context context, int pageId) {
|
||||
return new Uri.Builder()
|
||||
.scheme("android-app")
|
||||
.authority(context.getPackageName())
|
||||
.path(String.valueOf(pageId))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
64
src/com/android/settings/search/SearchFeatureProviderImpl.kt
Normal file
64
src/com/android/settings/search/SearchFeatureProviderImpl.kt
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.search
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import com.android.settings.search.SearchIndexableResourcesFactory.createSearchIndexableResources
|
||||
import com.android.settingslib.search.SearchIndexableResources
|
||||
|
||||
/** FeatureProvider for the refactored search code. */
|
||||
open class SearchFeatureProviderImpl : SearchFeatureProvider {
|
||||
private val lazySearchIndexableResources by lazy { createSearchIndexableResources() }
|
||||
|
||||
override fun verifyLaunchSearchResultPageCaller(context: Context, callerPackage: String) {
|
||||
require(callerPackage.isNotEmpty()) {
|
||||
"ExternalSettingsTrampoline intents must be called with startActivityForResult"
|
||||
}
|
||||
val isSettingsPackage = callerPackage == context.packageName
|
||||
if (isSettingsPackage ||
|
||||
callerPackage == getSettingsIntelligencePkgName(context) ||
|
||||
isSignatureAllowlisted(context, callerPackage)) {
|
||||
return
|
||||
}
|
||||
throw SecurityException(
|
||||
"Search result intents must be called with from an allowlisted package.")
|
||||
}
|
||||
|
||||
override fun getSearchIndexableResources(): SearchIndexableResources =
|
||||
lazySearchIndexableResources
|
||||
|
||||
override fun buildSearchIntent(context: Context, pageId: Int): Intent =
|
||||
Intent(Settings.ACTION_APP_SEARCH_SETTINGS)
|
||||
.setPackage(getSettingsIntelligencePkgName(context))
|
||||
.putExtra(Intent.EXTRA_REFERRER, buildReferrer(context, pageId))
|
||||
|
||||
protected open fun isSignatureAllowlisted(context: Context, callerPackage: String): Boolean =
|
||||
false
|
||||
|
||||
companion object {
|
||||
private fun buildReferrer(context: Context, pageId: Int): Uri =
|
||||
Uri.Builder()
|
||||
.scheme("android-app")
|
||||
.authority(context.packageName)
|
||||
.path(pageId.toString())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.search;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settingslib.search.SearchIndexableResources;
|
||||
import com.android.settingslib.search.SearchIndexableResourcesMobile;
|
||||
|
||||
/**
|
||||
* Creates the {@link SearchIndexableResourcesMobile}.
|
||||
* <p>
|
||||
* Since this class is generated by annotation processor, so it can only be created in Java now.
|
||||
*/
|
||||
class SearchIndexableResourcesFactory {
|
||||
@NonNull
|
||||
static SearchIndexableResources createSearchIndexableResources() {
|
||||
return new SearchIndexableResourcesMobile();
|
||||
}
|
||||
}
|
||||
@@ -789,6 +789,40 @@ public class BatteryInfoTest {
|
||||
expectedChargeLabel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBatteryInfo_longlife_shouldSetLonglife() {
|
||||
var batteryIntent = createIntentForLongLifeTest(/* hasLongLife= */ true);
|
||||
|
||||
var batteryInfo =
|
||||
BatteryInfo.getBatteryInfo(
|
||||
mContext,
|
||||
batteryIntent,
|
||||
mBatteryUsageStats,
|
||||
/* estimate= */ MOCK_ESTIMATE,
|
||||
/* elapsedRealtimeUs= */ 0L,
|
||||
/* shortString= */ false,
|
||||
/* currentTimeMs= */ 0L);
|
||||
|
||||
assertThat(batteryInfo.isLongLife).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBatteryInfo_noLonglife_shouldNotLonglife() {
|
||||
var batteryIntent = createIntentForLongLifeTest(/* hasLongLife= */ false);
|
||||
|
||||
var batteryInfo =
|
||||
BatteryInfo.getBatteryInfo(
|
||||
mContext,
|
||||
batteryIntent,
|
||||
mBatteryUsageStats,
|
||||
/* estimate= */ MOCK_ESTIMATE,
|
||||
/* elapsedRealtimeUs= */ 0L,
|
||||
/* shortString= */ false,
|
||||
/* currentTimeMs= */ 0L);
|
||||
|
||||
assertThat(batteryInfo.isLongLife).isFalse();
|
||||
}
|
||||
|
||||
private enum ChargingSpeed {
|
||||
FAST,
|
||||
REGULAR,
|
||||
@@ -801,6 +835,15 @@ public class BatteryInfoTest {
|
||||
DOCKED
|
||||
}
|
||||
|
||||
private Intent createIntentForLongLifeTest(Boolean hasLongLife) {
|
||||
return new Intent(Intent.ACTION_BATTERY_CHANGED)
|
||||
.putExtra(
|
||||
BatteryManager.EXTRA_CHARGING_STATUS,
|
||||
hasLongLife
|
||||
? BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE
|
||||
: BatteryManager.CHARGING_POLICY_DEFAULT);
|
||||
}
|
||||
|
||||
private Intent createIntentForGetBatteryInfoTest(
|
||||
ChargingType chargingType, ChargingSpeed chargingSpeed, int batteryLevel) {
|
||||
return createBatteryIntent(
|
||||
|
||||
@@ -165,7 +165,7 @@ public class PowerUsageFeatureProviderImplTest {
|
||||
|
||||
@Test
|
||||
public void isBatteryDefend_defenderModeAndExtraDefendAreFalse_returnFalse() {
|
||||
mBatteryInfo.isBatteryDefender = false;
|
||||
mBatteryInfo.isLongLife = false;
|
||||
doReturn(false).when(mPowerFeatureProvider).isExtraDefend();
|
||||
|
||||
assertThat(mPowerFeatureProvider.isBatteryDefend(mBatteryInfo)).isFalse();
|
||||
@@ -173,7 +173,7 @@ public class PowerUsageFeatureProviderImplTest {
|
||||
|
||||
@Test
|
||||
public void isBatteryDefend_defenderModeIsFalse_returnFalse() {
|
||||
mBatteryInfo.isBatteryDefender = false;
|
||||
mBatteryInfo.isLongLife = false;
|
||||
doReturn(true).when(mPowerFeatureProvider).isExtraDefend();
|
||||
|
||||
assertThat(mPowerFeatureProvider.isBatteryDefend(mBatteryInfo)).isFalse();
|
||||
@@ -181,7 +181,7 @@ public class PowerUsageFeatureProviderImplTest {
|
||||
|
||||
@Test
|
||||
public void isBatteryDefend_defenderModeAndExtraDefendAreTrue_returnFalse() {
|
||||
mBatteryInfo.isBatteryDefender = true;
|
||||
mBatteryInfo.isLongLife = true;
|
||||
doReturn(true).when(mPowerFeatureProvider).isExtraDefend();
|
||||
|
||||
assertThat(mPowerFeatureProvider.isBatteryDefend(mBatteryInfo)).isFalse();
|
||||
@@ -189,7 +189,7 @@ public class PowerUsageFeatureProviderImplTest {
|
||||
|
||||
@Test
|
||||
public void isBatteryDefend_extraDefendIsFalse_returnTrue() {
|
||||
mBatteryInfo.isBatteryDefender = true;
|
||||
mBatteryInfo.isLongLife = true;
|
||||
doReturn(false).when(mPowerFeatureProvider).isExtraDefend();
|
||||
|
||||
assertThat(mPowerFeatureProvider.isBatteryDefend(mBatteryInfo)).isTrue();
|
||||
|
||||
@@ -18,15 +18,12 @@ package com.android.settings.fuelgauge.batterytip.detectors;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.fuelgauge.BatteryInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -41,28 +38,23 @@ public class BatteryDefenderDetectorTest {
|
||||
@Mock private BatteryInfo mBatteryInfo;
|
||||
private BatteryDefenderDetector mBatteryDefenderDetector;
|
||||
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final Context context = ApplicationProvider.getApplicationContext();
|
||||
mBatteryDefenderDetector = new BatteryDefenderDetector(mBatteryInfo, context);
|
||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detect_notBatteryDefend_tipInvisible() {
|
||||
when(mFakeFeatureFactory.powerUsageFeatureProvider.isBatteryDefend(mBatteryInfo))
|
||||
.thenReturn(false);
|
||||
mBatteryInfo.isBatteryDefender = false;
|
||||
|
||||
assertThat(mBatteryDefenderDetector.detect().isVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detect_isBatteryDefend_tipNew() {
|
||||
when(mFakeFeatureFactory.powerUsageFeatureProvider.isBatteryDefend(mBatteryInfo))
|
||||
.thenReturn(true);
|
||||
mBatteryInfo.isBatteryDefender = true;
|
||||
|
||||
assertThat(mBatteryDefenderDetector.detect().getState())
|
||||
.isEqualTo(BatteryTip.StateType.NEW);
|
||||
|
||||
@@ -51,6 +51,7 @@ import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
@@ -319,7 +320,8 @@ public class NetworkProviderSettingsTest {
|
||||
mNetworkProviderSettings.onCreate(Bundle.EMPTY);
|
||||
|
||||
verify(mDataUsagePreference).setVisible(true);
|
||||
verify(mDataUsagePreference).setTemplate(any(), eq(0) /*subId*/);
|
||||
verify(mDataUsagePreference)
|
||||
.setTemplate(any(), eq(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -124,8 +124,8 @@ public class SearchFeatureProviderImplTest {
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void verifyLaunchSearchResultPageCaller_nullCaller_shouldCrash() {
|
||||
mProvider.verifyLaunchSearchResultPageCaller(mActivity, null /* caller */);
|
||||
public void verifyLaunchSearchResultPageCaller_emptyCaller_shouldCrash() {
|
||||
mProvider.verifyLaunchSearchResultPageCaller(mActivity, "");
|
||||
}
|
||||
|
||||
@Test(expected = SecurityException.class)
|
||||
|
||||
@@ -21,14 +21,10 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.service.trust.TrustAgentService;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
@@ -38,34 +34,30 @@ import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.shadows.ShadowApplicationPackageManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
ShadowLockPatternUtils.class,
|
||||
ShadowRestrictedLockUtilsInternal.class,
|
||||
ShadowDevicePolicyManager.class,
|
||||
ShadowApplicationPackageManager.class,
|
||||
TrustAgentsPreferenceControllerTest.ShadowTrustAgentManager.class
|
||||
ShadowDevicePolicyManager.class, ShadowApplicationPackageManager.class
|
||||
})
|
||||
public class TrustAgentsPreferenceControllerTest {
|
||||
|
||||
private static final Intent TEST_INTENT =
|
||||
new Intent(TrustAgentService.SERVICE_INTERFACE);
|
||||
private static final ComponentName TRUST_AGENT_A = new ComponentName(
|
||||
"test.data.packageA", "clzAAA");
|
||||
private static final ComponentName TRUST_AGENT_B = new ComponentName(
|
||||
"test.data.packageB", "clzBBB");
|
||||
private static final ComponentName TRUST_AGENT_C = new ComponentName(
|
||||
"test.data.packageC", "clzCCC");
|
||||
private static final ComponentName TRUST_AGENT_D = new ComponentName(
|
||||
"test.data.packageD", "clzDDD");
|
||||
|
||||
private Context mContext;
|
||||
private ShadowApplicationPackageManager mPackageManager;
|
||||
@@ -84,11 +76,6 @@ public class TrustAgentsPreferenceControllerTest {
|
||||
mPreferenceScreen.setKey("pref_key");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowTrustAgentManager.clearPermissionGrantedList();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_byDefault_shouldBeShown() {
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
@@ -97,8 +84,7 @@ public class TrustAgentsPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void onStart_noTrustAgent_shouldNotAddPreference() {
|
||||
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||
mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
|
||||
installFakeAvailableAgents(/* grantPermission= */ false);
|
||||
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onStart();
|
||||
@@ -106,57 +92,34 @@ public class TrustAgentsPreferenceControllerTest {
|
||||
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Ignore("b/313612480")
|
||||
@Test
|
||||
public void
|
||||
onStart_hasAUninstalledTrustAgent_shouldRemoveOnePreferenceAndLeaveTwoPreferences() {
|
||||
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||
final ResolveInfo uninstalledTrustAgent = availableAgents.get(0);
|
||||
|
||||
for (ResolveInfo rInfo : availableAgents) {
|
||||
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
|
||||
}
|
||||
mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
|
||||
public void onStart_uninstalledTrustAgent_shouldRemoveOnePreferenceAndLeaveTwoPreferences() {
|
||||
installFakeAvailableAgents(/* grantPermission= */ true);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onStart();
|
||||
availableAgents.remove(uninstalledTrustAgent);
|
||||
uninstallAgent(TRUST_AGENT_A);
|
||||
|
||||
mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
|
||||
mController.onStart();
|
||||
|
||||
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Ignore("b/313612480")
|
||||
@Test
|
||||
public void onStart_hasANewTrustAgent_shouldAddOnePreferenceAndHaveFourPreferences() {
|
||||
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||
final ComponentName newComponentName = new ComponentName("test.data.packageD", "clzDDD");
|
||||
final ResolveInfo newTrustAgent = createFakeResolveInfo(newComponentName);
|
||||
for (ResolveInfo rInfo : availableAgents) {
|
||||
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
|
||||
}
|
||||
mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
|
||||
installFakeAvailableAgents(/* grantPermission= */ true);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onStart();
|
||||
availableAgents.add(newTrustAgent);
|
||||
ShadowTrustAgentManager.grantPermissionToResolveInfo(newTrustAgent);
|
||||
installFakeAvailableAgent(TRUST_AGENT_D, /* grantPermission= */ true);
|
||||
|
||||
mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
|
||||
mController.onStart();
|
||||
|
||||
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Ignore("b/313612480")
|
||||
@Test
|
||||
public void onStart_hasUnrestrictedTrustAgent_shouldAddThreeChangeablePreferences() {
|
||||
ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(0);
|
||||
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||
for (ResolveInfo rInfo : availableAgents) {
|
||||
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
|
||||
}
|
||||
mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
|
||||
installFakeAvailableAgents(/* grantPermission= */ true);
|
||||
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onStart();
|
||||
@@ -169,14 +132,9 @@ public class TrustAgentsPreferenceControllerTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("b/313612480")
|
||||
@Test
|
||||
public void onStart_hasRestrictedTructAgent_shouldAddThreeUnchangeablePreferences() {
|
||||
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
|
||||
for (ResolveInfo rInfo : availableAgents) {
|
||||
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
|
||||
}
|
||||
mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
|
||||
public void onStart_hasRestrictedTrustAgent_shouldAddThreeUnchangeablePreferences() {
|
||||
installFakeAvailableAgents(/* grantPermission= */ true);
|
||||
ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
|
||||
|
||||
@@ -191,51 +149,30 @@ public class TrustAgentsPreferenceControllerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private List<ResolveInfo> createFakeAvailableAgents() {
|
||||
final List<ComponentName> componentNames = new ArrayList<>();
|
||||
componentNames.add(new ComponentName("test.data.packageA", "clzAAA"));
|
||||
componentNames.add(new ComponentName("test.data.packageB", "clzBBB"));
|
||||
componentNames.add(new ComponentName("test.data.packageC", "clzCCC"));
|
||||
final List<ResolveInfo> result = new ArrayList<>();
|
||||
for (ComponentName cn : componentNames) {
|
||||
final ResolveInfo ri = createFakeResolveInfo(cn);
|
||||
result.add(ri);
|
||||
}
|
||||
return result;
|
||||
private void installFakeAvailableAgents(boolean grantPermission) {
|
||||
installFakeAvailableAgent(TRUST_AGENT_A, grantPermission);
|
||||
installFakeAvailableAgent(TRUST_AGENT_B, grantPermission);
|
||||
installFakeAvailableAgent(TRUST_AGENT_C, grantPermission);
|
||||
}
|
||||
|
||||
private ResolveInfo createFakeResolveInfo(ComponentName cn) {
|
||||
final ResolveInfo ri = new ResolveInfo();
|
||||
ri.serviceInfo = new ServiceInfo();
|
||||
ri.serviceInfo.packageName = cn.getPackageName();
|
||||
ri.serviceInfo.name = cn.getClassName();
|
||||
ri.serviceInfo.applicationInfo = new ApplicationInfo();
|
||||
ri.serviceInfo.applicationInfo.packageName = cn.getPackageName();
|
||||
ri.serviceInfo.applicationInfo.name = cn.getClassName();
|
||||
return ri;
|
||||
private void installFakeAvailableAgent(ComponentName name,
|
||||
boolean grantPermission) {
|
||||
mPackageManager.addServiceIfNotPresent(name);
|
||||
mPackageManager.addIntentFilterForService(name,
|
||||
new IntentFilter(TrustAgentService.SERVICE_INTERFACE));
|
||||
if (!grantPermission) {
|
||||
return;
|
||||
}
|
||||
PackageInfo pkgInfo = mPackageManager.getInternalMutablePackageInfo(
|
||||
name.getPackageName());
|
||||
pkgInfo.requestedPermissions =
|
||||
new String[]{android.Manifest.permission.PROVIDE_TRUST_AGENT};
|
||||
pkgInfo.requestedPermissionsFlags =
|
||||
new int[]{PackageInfo.REQUESTED_PERMISSION_GRANTED};
|
||||
}
|
||||
|
||||
@Implements(TrustAgentManager.class)
|
||||
public static class ShadowTrustAgentManager {
|
||||
private final static List<ResolveInfo> sPermissionGrantedList = new ArrayList<>();
|
||||
|
||||
@Implementation
|
||||
protected boolean shouldProvideTrust(ResolveInfo resolveInfo, PackageManager pm) {
|
||||
for (ResolveInfo info : sPermissionGrantedList) {
|
||||
if (info.serviceInfo.equals(resolveInfo.serviceInfo)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void grantPermissionToResolveInfo(ResolveInfo rInfo) {
|
||||
sPermissionGrantedList.add(rInfo);
|
||||
}
|
||||
|
||||
private static void clearPermissionGrantedList() {
|
||||
sPermissionGrantedList.clear();
|
||||
}
|
||||
private void uninstallAgent(ComponentName name) {
|
||||
mPackageManager.removeService(name);
|
||||
mPackageManager.removePackage(name.getPackageName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ android_test {
|
||||
"truth",
|
||||
"kotlinx_coroutines_test",
|
||||
"Settings-testutils2",
|
||||
"MediaDrmSettingsFlagsLib",
|
||||
"servicestests-utils",
|
||||
// Don't add SettingsLib libraries here - you can use them directly as they are in the
|
||||
// instrumented Settings app.
|
||||
|
||||
@@ -29,6 +29,8 @@ import android.util.Log;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.media_drm.Flags;
|
||||
import android.platform.test.annotations.DisableFlags;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
|
||||
import androidx.preference.SwitchPreference;
|
||||
@@ -65,10 +67,10 @@ public class ForceSwSecureCryptoFallbackPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_FORCE_L3_ENABLED)
|
||||
public void updateState_flagEnabled_checkPreference() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_FORCE_L3_ENABLED);
|
||||
mController.updateState(mPreference);
|
||||
assumeTrue(mPreference.isEnabled());
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
assertThat(WidevineProperties.forcel3_enabled().orElse(false)).isFalse();
|
||||
|
||||
@@ -85,33 +87,22 @@ public class ForceSwSecureCryptoFallbackPreferenceControllerTest {
|
||||
assertThat(WidevineProperties.forcel3_enabled().orElse(false)).isFalse();
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
|
||||
// Test flag rollback
|
||||
mController.setChecked(true);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
assertThat(WidevineProperties.forcel3_enabled().orElse(false)).isTrue();
|
||||
mSetFlagsRule.disableFlags(Flags.FLAG_FORCE_L3_ENABLED);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
assertThat(WidevineProperties.forcel3_enabled().orElse(false)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisableFlags(Flags.FLAG_FORCE_L3_ENABLED)
|
||||
public void updateState_flagDisabled_checkPreference() {
|
||||
mSetFlagsRule.disableFlags(Flags.FLAG_FORCE_L3_ENABLED);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_FORCE_L3_ENABLED)
|
||||
public void updateState_checkWidevine() throws Exception {
|
||||
try (MediaDrm drm = new MediaDrm(WIDEVINE_UUID)) {
|
||||
assumeTrue(drm.getPropertyString("securityLevel").equals("L1"));
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_FORCE_L3_ENABLED);
|
||||
mController.updateState(mPreference);
|
||||
assumeTrue(mPreference.isEnabled());
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
} catch (UnsupportedSchemeException ex) {
|
||||
assumeNoException(ex);
|
||||
}
|
||||
@@ -139,11 +130,11 @@ public class ForceSwSecureCryptoFallbackPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_FORCE_L3_ENABLED)
|
||||
public void updateState_checkWhenWidevineReady() throws Exception {
|
||||
try (MediaDrm drm = new MediaDrm(WIDEVINE_UUID)) {
|
||||
if (drm.getPropertyString("securityLevel").equals("L1")) {
|
||||
String version = drm.getPropertyString(MediaDrm.PROPERTY_VERSION);
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_FORCE_L3_ENABLED);
|
||||
mController.updateState(mPreference);
|
||||
if (Integer.parseInt(version.split("\\.", 2)[0]) >= 19) {
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
|
||||
@@ -131,8 +131,7 @@ public class MobileDataPreferenceControllerTest {
|
||||
|
||||
private MobileNetworkInfoEntity setupMobileNetworkInfoEntity(String subId,
|
||||
boolean isDatEnabled) {
|
||||
return new MobileNetworkInfoEntity(subId, false, false, isDatEnabled, false, false, false,
|
||||
false, false, false, false, false);
|
||||
return new MobileNetworkInfoEntity(subId, isDatEnabled, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user