Snap for 8822995 from 51d087cd67 to tm-qpr1-release
Change-Id: Ib39d3da91aa450fe4bc161641393fdb98d0455d6
This commit is contained in:
@@ -617,4 +617,7 @@
|
||||
|
||||
<!-- Whether to put the apps with system UID into system component bucket or not -->
|
||||
<bool name="config_battery_combine_system_components">false</bool>
|
||||
|
||||
<!-- Whether to enable the advanced vpn feature. The default is not to. -->
|
||||
<bool name="config_advanced_vpn_enabled">false</bool>
|
||||
</resources>
|
||||
|
||||
@@ -6646,6 +6646,8 @@
|
||||
<string name="battery_not_usage_24hr">No usage for past 24 hr</string>
|
||||
<!-- Description for no usage time but have battery usage [CHAR LIMIT=120] -->
|
||||
<string name="battery_usage_without_time"></string>
|
||||
<!-- Description for other users aggregated battery usage data [CHAR LIMIT=120] -->
|
||||
<string name="battery_usage_other_users">Other users</string>
|
||||
|
||||
<!-- Graph subtext displayed to user when enhanced battery estimate is being used [CHAR LIMIT=120] -->
|
||||
<string name="advanced_battery_graph_subtext">Battery left estimate is based on your device usage</string>
|
||||
|
||||
@@ -16,4 +16,9 @@
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:title="@string/vpn_title">
|
||||
<PreferenceCategory
|
||||
android:key="advanced_vpn_group"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="vpn_group"/>
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.content.res.Resources;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Display;
|
||||
|
||||
@@ -56,6 +57,7 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment {
|
||||
private Resources mResources;
|
||||
private static final int FHD_INDEX = 0;
|
||||
private static final int QHD_INDEX = 1;
|
||||
private static final String RESOLUTION_METRIC_SETTING_KEY = "user_selected_resolution";
|
||||
private Display mDefaultDisplay;
|
||||
private String[] mScreenResolutionOptions;
|
||||
private Set<Point> mResolutions;
|
||||
@@ -157,6 +159,17 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment {
|
||||
@VisibleForTesting
|
||||
public void setDisplayMode(final int width) {
|
||||
mDisplayObserver.startObserve();
|
||||
|
||||
/** For store settings globally. */
|
||||
/** TODO(b/238061217): Moving to an atom with the same string */
|
||||
Settings.System.putString(
|
||||
getContext().getContentResolver(),
|
||||
RESOLUTION_METRIC_SETTING_KEY,
|
||||
getPreferMode(width).getPhysicalWidth()
|
||||
+ "x"
|
||||
+ getPreferMode(width).getPhysicalHeight());
|
||||
|
||||
/** Apply the resolution change. */
|
||||
mDefaultDisplay.setUserPreferredDisplayMode(getPreferMode(width));
|
||||
}
|
||||
|
||||
@@ -186,7 +199,7 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment {
|
||||
protected boolean setDefaultKey(final String key) {
|
||||
int width = getWidthForResoluitonKey(key);
|
||||
if (width < 0) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
setDisplayMode(width);
|
||||
@@ -200,9 +213,8 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment {
|
||||
String selectedKey = selected.getKey();
|
||||
int selectedWidth = getWidthForResoluitonKey(selectedKey);
|
||||
if (!mDisplayObserver.setPendingResolutionChange(selectedWidth)) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
super.onRadioButtonClicked(selected);
|
||||
}
|
||||
|
||||
@@ -318,7 +330,7 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment {
|
||||
}
|
||||
|
||||
if (!isDensityChanged() || !isResolutionChangeApplied()) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
restoreDensity();
|
||||
@@ -353,10 +365,10 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment {
|
||||
int currentWidth = getCurrentWidth();
|
||||
|
||||
if (selectedWidth == currentWidth) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
if (mPreviousWidth.get() != -1 && !isResolutionChangeApplied()) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
mPreviousWidth.set(currentWidth);
|
||||
@@ -366,7 +378,7 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment {
|
||||
|
||||
private boolean isResolutionChangeApplied() {
|
||||
if (mPreviousWidth.get() == getCurrentWidth()) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -69,6 +69,8 @@ public class BatteryUtils {
|
||||
public static final int UID_REMOVED_APPS = -4;
|
||||
/** Special UID value for data usage by tethering. */
|
||||
public static final int UID_TETHERING = -5;
|
||||
/** Special UID for aggregated other users. */
|
||||
public static final long UID_OTHER_USERS = Long.MIN_VALUE;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({StatusType.SCREEN_USAGE,
|
||||
|
||||
@@ -149,6 +149,11 @@ public interface PowerUsageFeatureProvider {
|
||||
*/
|
||||
Map<Long, Map<String, BatteryHistEntry>> getBatteryHistory(Context context);
|
||||
|
||||
/**
|
||||
* Returns battery history data since last full charge with corresponding timestamp key.
|
||||
*/
|
||||
Map<Long, Map<String, BatteryHistEntry>> getBatteryHistorySinceLastFullCharge(Context context);
|
||||
|
||||
/**
|
||||
* Returns {@link Uri} to monitor battery history data is update.
|
||||
*/
|
||||
|
||||
@@ -165,6 +165,12 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, Map<String, BatteryHistEntry>> getBatteryHistorySinceLastFullCharge(
|
||||
Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getBatteryHistoryUri() {
|
||||
return null;
|
||||
|
||||
@@ -113,6 +113,9 @@ public class BatteryDiffEntry {
|
||||
|
||||
/** Gets the app label name for this entry. */
|
||||
public String getAppLabel() {
|
||||
if (isOtherUsers()) {
|
||||
return mContext.getString(R.string.battery_usage_other_users);
|
||||
}
|
||||
loadLabelAndIcon();
|
||||
// Returns default applicationn label if we cannot find it.
|
||||
return mAppLabel == null || mAppLabel.length() == 0
|
||||
@@ -122,6 +125,9 @@ public class BatteryDiffEntry {
|
||||
|
||||
/** Gets the app icon {@link Drawable} for this entry. */
|
||||
public Drawable getAppIcon() {
|
||||
if (isOtherUsers()) {
|
||||
return mContext.getDrawable(R.drawable.ic_power_system);
|
||||
}
|
||||
loadLabelAndIcon();
|
||||
return mAppIcon != null && mAppIcon.getConstantState() != null
|
||||
? mAppIcon.getConstantState().newDrawable()
|
||||
@@ -156,6 +162,9 @@ public class BatteryDiffEntry {
|
||||
|
||||
/** Whether the current BatteryDiffEntry is system component or not. */
|
||||
public boolean isSystemEntry() {
|
||||
if (isOtherUsers()) {
|
||||
return true;
|
||||
}
|
||||
switch (mBatteryHistEntry.mConsumerType) {
|
||||
case ConvertUtils.CONSUMER_TYPE_USER_BATTERY:
|
||||
case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY:
|
||||
@@ -175,6 +184,11 @@ public class BatteryDiffEntry {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isOtherUsers() {
|
||||
return mBatteryHistEntry.mConsumerType == ConvertUtils.CONSUMER_TYPE_UID_BATTERY
|
||||
&& mBatteryHistEntry.mUid == BatteryUtils.UID_OTHER_USERS;
|
||||
}
|
||||
|
||||
void loadLabelAndIcon() {
|
||||
if (mIsLoaded) {
|
||||
return;
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.LocaleList;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArraySet;
|
||||
@@ -28,6 +29,8 @@ import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -265,17 +268,55 @@ public final class ConvertUtils {
|
||||
}
|
||||
}
|
||||
insert24HoursData(BatteryChartView.SELECTED_INDEX_ALL, resultMap);
|
||||
resolveMultiUsersData(context, resultMap);
|
||||
if (purgeLowPercentageAndFakeData) {
|
||||
purgeLowPercentageAndFakeData(context, resultMap);
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static void resolveMultiUsersData(
|
||||
final Context context,
|
||||
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
||||
final int currentUserId = context.getUserId();
|
||||
final UserHandle userHandle =
|
||||
Utils.getManagedProfile(context.getSystemService(UserManager.class));
|
||||
final int workProfileUserId =
|
||||
userHandle != null ? userHandle.getIdentifier() : Integer.MIN_VALUE;
|
||||
// Loops for all BatteryDiffEntry in the different slots.
|
||||
for (List<BatteryDiffEntry> entryList : indexedUsageMap.values()) {
|
||||
double consumePowerFromOtherUsers = 0f;
|
||||
double consumePercentageFromOtherUsers = 0f;
|
||||
final Iterator<BatteryDiffEntry> iterator = entryList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final BatteryDiffEntry entry = iterator.next();
|
||||
final BatteryHistEntry batteryHistEntry = entry.mBatteryHistEntry;
|
||||
if (batteryHistEntry.mConsumerType != CONSUMER_TYPE_UID_BATTERY) {
|
||||
continue;
|
||||
}
|
||||
// Whether the BatteryHistEntry represents the current user data?
|
||||
if (batteryHistEntry.mUserId == currentUserId
|
||||
|| batteryHistEntry.mUserId == workProfileUserId) {
|
||||
continue;
|
||||
}
|
||||
// Removes and aggregates non-current users data from the list.
|
||||
iterator.remove();
|
||||
consumePowerFromOtherUsers += entry.mConsumePower;
|
||||
consumePercentageFromOtherUsers += entry.getPercentOfTotal();
|
||||
}
|
||||
if (consumePercentageFromOtherUsers != 0) {
|
||||
entryList.add(createOtherUsersEntry(context, consumePowerFromOtherUsers,
|
||||
consumePercentageFromOtherUsers));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void insert24HoursData(
|
||||
final int desiredIndex,
|
||||
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
||||
final Map<String, BatteryDiffEntry> resultMap = new HashMap<>();
|
||||
double totalConsumePower = 0.0;
|
||||
double totalConsumePower = 0f;
|
||||
// Loops for all BatteryDiffEntry and aggregate them together.
|
||||
for (List<BatteryDiffEntry> entryList : indexedUsageMap.values()) {
|
||||
for (BatteryDiffEntry entry : entryList) {
|
||||
@@ -361,4 +402,22 @@ public final class ConvertUtils {
|
||||
return locales != null && !locales.isEmpty() ? locales.get(0)
|
||||
: Locale.getDefault();
|
||||
}
|
||||
|
||||
private static BatteryDiffEntry createOtherUsersEntry(
|
||||
Context context, double consumePower, double consumePercentage) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(BatteryHistEntry.KEY_UID, BatteryUtils.UID_OTHER_USERS);
|
||||
values.put(BatteryHistEntry.KEY_USER_ID, BatteryUtils.UID_OTHER_USERS);
|
||||
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE, CONSUMER_TYPE_UID_BATTERY);
|
||||
// We will show the percentage for the "other users" item only, the aggregated
|
||||
// running time information is useless for users to identify individual apps.
|
||||
final BatteryDiffEntry batteryDiffEntry = new BatteryDiffEntry(
|
||||
context,
|
||||
/*foregroundUsageTimeInMs=*/ 0,
|
||||
/*backgroundUsageTimeInMs=*/ 0,
|
||||
consumePower,
|
||||
new BatteryHistEntry(values));
|
||||
batteryDiffEntry.setTotalConsumePower(100 * consumePower / consumePercentage);
|
||||
return batteryDiffEntry;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.android.settings.security.SecurityFeatureProvider;
|
||||
import com.android.settings.security.SecuritySettingsFeatureProvider;
|
||||
import com.android.settings.slices.SlicesFeatureProvider;
|
||||
import com.android.settings.users.UserFeatureProvider;
|
||||
import com.android.settings.vpn2.AdvancedVpnFeatureProvider;
|
||||
import com.android.settings.wifi.WifiTrackerLibProvider;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
|
||||
@@ -177,6 +178,11 @@ public abstract class FeatureFactory {
|
||||
*/
|
||||
public abstract AccessibilityMetricsFeatureProvider getAccessibilityMetricsFeatureProvider();
|
||||
|
||||
/**
|
||||
* Retrieves implementation for advanced vpn feature.
|
||||
*/
|
||||
public abstract AdvancedVpnFeatureProvider getAdvancedVpnFeatureProvider();
|
||||
|
||||
public static final class FactoryNotFoundException extends RuntimeException {
|
||||
public FactoryNotFoundException(Throwable throwable) {
|
||||
super("Unable to create factory. Did you misconfigure Proguard?", throwable);
|
||||
|
||||
@@ -71,6 +71,8 @@ import com.android.settings.slices.SlicesFeatureProvider;
|
||||
import com.android.settings.slices.SlicesFeatureProviderImpl;
|
||||
import com.android.settings.users.UserFeatureProvider;
|
||||
import com.android.settings.users.UserFeatureProviderImpl;
|
||||
import com.android.settings.vpn2.AdvancedVpnFeatureProvider;
|
||||
import com.android.settings.vpn2.AdvancedVpnFeatureProviderImpl;
|
||||
import com.android.settings.wifi.WifiTrackerLibProvider;
|
||||
import com.android.settings.wifi.WifiTrackerLibProviderImpl;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
@@ -106,6 +108,7 @@ public class FeatureFactoryImpl extends FeatureFactory {
|
||||
private SecuritySettingsFeatureProvider mSecuritySettingsFeatureProvider;
|
||||
private AccessibilitySearchFeatureProvider mAccessibilitySearchFeatureProvider;
|
||||
private AccessibilityMetricsFeatureProvider mAccessibilityMetricsFeatureProvider;
|
||||
private AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider;
|
||||
|
||||
@Override
|
||||
public SupportFeatureProvider getSupportFeatureProvider(Context context) {
|
||||
@@ -334,4 +337,12 @@ public class FeatureFactoryImpl extends FeatureFactory {
|
||||
}
|
||||
return mAccessibilityMetricsFeatureProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedVpnFeatureProvider getAdvancedVpnFeatureProvider() {
|
||||
if (mAdvancedVpnFeatureProvider == null) {
|
||||
mAdvancedVpnFeatureProvider = new AdvancedVpnFeatureProviderImpl();
|
||||
}
|
||||
return mAdvancedVpnFeatureProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.vpn2;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Feature Provider used in vpn usage
|
||||
*/
|
||||
public interface AdvancedVpnFeatureProvider {
|
||||
|
||||
/**
|
||||
* Returns package name of advanced vpn.
|
||||
*/
|
||||
String getAdvancedVpnPackageName();
|
||||
|
||||
/**
|
||||
* Returns {@code true} advanced vpn is supported.
|
||||
*/
|
||||
boolean isAdvancedVpnSupported(Context context);
|
||||
|
||||
/**
|
||||
* Returns the title of advanced vpn preference group.
|
||||
*/
|
||||
String getAdvancedVpnPreferenceGroupTitle(Context context);
|
||||
|
||||
/**
|
||||
* Returns the title of vpn preference group.
|
||||
*/
|
||||
String getVpnPreferenceGroupTitle(Context context);
|
||||
|
||||
/**
|
||||
* Returns {@code true} advanced vpn is removable.
|
||||
*/
|
||||
boolean isAdvancedVpnRemovable();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.vpn2;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Feature provider implementation for advanced vpn.
|
||||
*/
|
||||
public class AdvancedVpnFeatureProviderImpl implements AdvancedVpnFeatureProvider {
|
||||
@Override
|
||||
public String getAdvancedVpnPackageName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdvancedVpnSupported(Context context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdvancedVpnPreferenceGroupTitle(Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVpnPreferenceGroupTitle(Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdvancedVpnRemovable() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
@@ -71,6 +72,7 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
||||
private PackageManager mPackageManager;
|
||||
private DevicePolicyManager mDevicePolicyManager;
|
||||
private VpnManager mVpnManager;
|
||||
private AdvancedVpnFeatureProvider mFeatureProvider;
|
||||
|
||||
// VPN app info
|
||||
private final int mUserId = UserHandle.myUserId();
|
||||
@@ -122,6 +124,7 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
||||
mPackageManager = getContext().getPackageManager();
|
||||
mDevicePolicyManager = getContext().getSystemService(DevicePolicyManager.class);
|
||||
mVpnManager = getContext().getSystemService(VpnManager.class);
|
||||
mFeatureProvider = FeatureFactory.getFactory(getContext()).getAdvancedVpnFeatureProvider();
|
||||
|
||||
mPreferenceAlwaysOn = (RestrictedSwitchPreference) findPreference(KEY_ALWAYS_ON_VPN);
|
||||
mPreferenceLockdown = (RestrictedSwitchPreference) findPreference(KEY_LOCKDOWN_VPN);
|
||||
@@ -283,7 +286,16 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRestrictedViews() {
|
||||
@VisibleForTesting
|
||||
void updateRestrictedViews() {
|
||||
if (mFeatureProvider.isAdvancedVpnSupported(getContext())
|
||||
&& !mFeatureProvider.isAdvancedVpnRemovable()
|
||||
&& TextUtils.equals(mPackageName, mFeatureProvider.getAdvancedVpnPackageName())) {
|
||||
mPreferenceForget.setVisible(false);
|
||||
} else {
|
||||
mPreferenceForget.setVisible(true);
|
||||
}
|
||||
|
||||
if (isAdded()) {
|
||||
mPreferenceAlwaysOn.checkRestrictionAndSetDisabled(UserManager.DISALLOW_CONFIG_VPN,
|
||||
mUserId);
|
||||
@@ -314,6 +326,14 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void init(String packageName, AdvancedVpnFeatureProvider featureProvider,
|
||||
RestrictedPreference preference) {
|
||||
mPackageName = packageName;
|
||||
mFeatureProvider = featureProvider;
|
||||
mPreferenceForget = preference;
|
||||
}
|
||||
|
||||
private String getAlwaysOnVpnPackage() {
|
||||
return mVpnManager.getAlwaysOnVpnPackageForUser(mUserId);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.security.Credentials;
|
||||
import android.security.LegacyVpnProfileStore;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
@@ -52,6 +53,7 @@ import android.view.MenuItem;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.net.LegacyVpnInfo;
|
||||
@@ -59,6 +61,7 @@ import com.android.internal.net.VpnConfig;
|
||||
import com.android.internal.net.VpnProfile;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.RestrictedSettingsFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.GearPreference;
|
||||
import com.android.settings.widget.GearPreference.OnGearClickListener;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
@@ -79,9 +82,12 @@ import java.util.Set;
|
||||
public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
Handler.Callback, Preference.OnPreferenceClickListener {
|
||||
private static final String LOG_TAG = "VpnSettings";
|
||||
private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
|
||||
|
||||
private static final int RESCAN_MESSAGE = 0;
|
||||
private static final int RESCAN_INTERVAL_MS = 1000;
|
||||
private static final String ADVANCED_VPN_GROUP_KEY = "advanced_vpn_group";
|
||||
private static final String VPN_GROUP_KEY = "vpn_group";
|
||||
|
||||
private static final NetworkRequest VPN_REQUEST = new NetworkRequest.Builder()
|
||||
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
|
||||
@@ -102,6 +108,9 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
private LegacyVpnInfo mConnectedLegacyVpn;
|
||||
|
||||
private boolean mUnavailable;
|
||||
private AdvancedVpnFeatureProvider mFeatureProvider;
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
private boolean mIsAdvancedVpnSupported;
|
||||
|
||||
public VpnSettings() {
|
||||
super(UserManager.DISALLOW_CONFIG_VPN);
|
||||
@@ -119,11 +128,14 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
|
||||
mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
mVpnManager = (VpnManager) getSystemService(Context.VPN_MANAGEMENT_SERVICE);
|
||||
mFeatureProvider = FeatureFactory.getFactory(getContext()).getAdvancedVpnFeatureProvider();
|
||||
mIsAdvancedVpnSupported = mFeatureProvider.isAdvancedVpnSupported(getContext());
|
||||
|
||||
mUnavailable = isUiRestricted();
|
||||
setHasOptionsMenu(!mUnavailable);
|
||||
|
||||
addPreferencesFromResource(R.xml.vpn_settings2);
|
||||
mPreferenceScreen = getPreferenceScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -229,7 +241,8 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
|
||||
// Run heavy RPCs before switching to UI thread
|
||||
final List<VpnProfile> vpnProfiles = loadVpnProfiles();
|
||||
final List<AppVpnInfo> vpnApps = getVpnApps(context, /* includeProfiles */ true);
|
||||
final List<AppVpnInfo> vpnApps = getVpnApps(context, /* includeProfiles */ true,
|
||||
mFeatureProvider);
|
||||
|
||||
final Map<String, LegacyVpnInfo> connectedLegacyVpns = getConnectedLegacyVpns();
|
||||
final Set<AppVpnInfo> connectedAppVpns = getConnectedAppVpns();
|
||||
@@ -265,7 +278,7 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
|
||||
private final VpnSettings mSettings;
|
||||
|
||||
public UpdatePreferences(VpnSettings settings) {
|
||||
UpdatePreferences(VpnSettings settings) {
|
||||
mSettings = settings;
|
||||
}
|
||||
|
||||
@@ -332,7 +345,14 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
}
|
||||
|
||||
// Trim out deleted VPN preferences
|
||||
mSettings.setShownPreferences(updates);
|
||||
if (DEBUG) {
|
||||
Log.d(LOG_TAG, "isAdvancedVpnSupported() : " + mSettings.mIsAdvancedVpnSupported);
|
||||
}
|
||||
if (mSettings.mIsAdvancedVpnSupported) {
|
||||
mSettings.setShownAdvancedPreferences(updates);
|
||||
} else {
|
||||
mSettings.setShownPreferences(updates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,12 +363,61 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
|
||||
@VisibleForTesting @UiThread
|
||||
public void setShownPreferences(final Collection<Preference> updates) {
|
||||
retainAllPreference(updates);
|
||||
|
||||
final PreferenceGroup vpnGroup = getPreferenceScreen();
|
||||
updatePreferenceGroup(vpnGroup, updates);
|
||||
|
||||
// Show all new preferences on the screen
|
||||
for (Preference pref : updates) {
|
||||
vpnGroup.addPreference(pref);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting @UiThread
|
||||
void setShownAdvancedPreferences(final Collection<Preference> updates) {
|
||||
retainAllPreference(updates);
|
||||
|
||||
PreferenceGroup advancedVpnGroup = mPreferenceScreen.findPreference(ADVANCED_VPN_GROUP_KEY);
|
||||
PreferenceGroup vpnGroup = mPreferenceScreen.findPreference(VPN_GROUP_KEY);
|
||||
advancedVpnGroup.setTitle(
|
||||
mFeatureProvider.getAdvancedVpnPreferenceGroupTitle(getContext()));
|
||||
vpnGroup.setTitle(mFeatureProvider.getVpnPreferenceGroupTitle(getContext()));
|
||||
updatePreferenceGroup(advancedVpnGroup, updates);
|
||||
updatePreferenceGroup(vpnGroup, updates);
|
||||
|
||||
// Show all new preferences on the screen
|
||||
for (Preference pref : updates) {
|
||||
String packageName = "";
|
||||
if (pref instanceof LegacyVpnPreference) {
|
||||
LegacyVpnPreference legacyPref = (LegacyVpnPreference) pref;
|
||||
packageName = legacyPref.getPackageName();
|
||||
} else if (pref instanceof AppPreference) {
|
||||
AppPreference appPref = (AppPreference) pref;
|
||||
packageName = appPref.getPackageName();
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(LOG_TAG, "setShownAdvancedPreferences() package name : " + packageName);
|
||||
}
|
||||
if (TextUtils.equals(packageName, mFeatureProvider.getAdvancedVpnPackageName())) {
|
||||
advancedVpnGroup.addPreference(pref);
|
||||
} else {
|
||||
vpnGroup.addPreference(pref);
|
||||
}
|
||||
}
|
||||
|
||||
advancedVpnGroup.setVisible(advancedVpnGroup.getPreferenceCount() > 0);
|
||||
vpnGroup.setVisible(vpnGroup.getPreferenceCount() > 0);
|
||||
}
|
||||
|
||||
private void retainAllPreference(Collection<Preference> updates) {
|
||||
mLegacyVpnPreferences.values().retainAll(updates);
|
||||
mAppPreferences.values().retainAll(updates);
|
||||
}
|
||||
|
||||
private void updatePreferenceGroup(PreferenceGroup vpnGroup, Collection<Preference> updates) {
|
||||
// Change {@param updates} in-place to only contain new preferences that were not already
|
||||
// added to the preference screen.
|
||||
final PreferenceGroup vpnGroup = getPreferenceScreen();
|
||||
for (int i = vpnGroup.getPreferenceCount() - 1; i >= 0; i--) {
|
||||
Preference p = vpnGroup.getPreference(i);
|
||||
if (updates.contains(p)) {
|
||||
@@ -357,11 +426,6 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
vpnGroup.removePreference(p);
|
||||
}
|
||||
}
|
||||
|
||||
// Show any new preferences on the screen
|
||||
for (Preference pref : updates) {
|
||||
vpnGroup.addPreference(pref);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -508,7 +572,15 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
return result;
|
||||
}
|
||||
|
||||
static List<AppVpnInfo> getVpnApps(Context context, boolean includeProfiles) {
|
||||
static List<AppVpnInfo> getVpnApps(Context context, boolean includeProfiles,
|
||||
AdvancedVpnFeatureProvider featureProvider) {
|
||||
return getVpnApps(context, includeProfiles, featureProvider,
|
||||
context.getSystemService(AppOpsManager.class));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static List<AppVpnInfo> getVpnApps(Context context, boolean includeProfiles,
|
||||
AdvancedVpnFeatureProvider featureProvider, AppOpsManager aom) {
|
||||
List<AppVpnInfo> result = Lists.newArrayList();
|
||||
|
||||
final Set<Integer> profileIds;
|
||||
@@ -521,8 +593,6 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
profileIds = Collections.singleton(UserHandle.myUserId());
|
||||
}
|
||||
|
||||
// Fetch VPN-enabled apps from AppOps.
|
||||
AppOpsManager aom = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
|
||||
List<AppOpsManager.PackageOps> apps =
|
||||
aom.getPackagesForOps(new int[] {OP_ACTIVATE_VPN, OP_ACTIVATE_PLATFORM_VPN});
|
||||
if (apps != null) {
|
||||
@@ -540,7 +610,7 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
allowed = true;
|
||||
}
|
||||
}
|
||||
if (allowed) {
|
||||
if (allowed || isAdvancedVpn(featureProvider, pkg.getPackageName(), context)) {
|
||||
result.add(new AppVpnInfo(userId, pkg.getPackageName()));
|
||||
}
|
||||
}
|
||||
@@ -550,6 +620,12 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isAdvancedVpn(AdvancedVpnFeatureProvider featureProvider,
|
||||
String packageName, Context context) {
|
||||
return featureProvider.isAdvancedVpnSupported(context)
|
||||
&& TextUtils.equals(packageName, featureProvider.getAdvancedVpnPackageName());
|
||||
}
|
||||
|
||||
private static List<VpnProfile> loadVpnProfiles() {
|
||||
final ArrayList<VpnProfile> result = Lists.newArrayList();
|
||||
|
||||
@@ -562,4 +638,10 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void init(PreferenceScreen preferenceScreen, AdvancedVpnFeatureProvider featureProvider) {
|
||||
mPreferenceScreen = preferenceScreen;
|
||||
mFeatureProvider = featureProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -343,9 +344,17 @@ public final class BatteryBackupHelperTest {
|
||||
|
||||
private void verifyBackupData(String expectedResult) throws Exception {
|
||||
final byte[] expectedBytes = expectedResult.getBytes();
|
||||
final ArgumentCaptor<byte[]> captor = ArgumentCaptor.forClass(byte[].class);
|
||||
final Set<String> expectedResultSet =
|
||||
Set.of(expectedResult.split(BatteryBackupHelper.DELIMITER));
|
||||
|
||||
verify(mBackupDataOutput).writeEntityHeader(
|
||||
BatteryBackupHelper.KEY_OPTIMIZATION_LIST, expectedBytes.length);
|
||||
verify(mBackupDataOutput).writeEntityData(expectedBytes, expectedBytes.length);
|
||||
verify(mBackupDataOutput).writeEntityData(captor.capture(), eq(expectedBytes.length));
|
||||
final String actualResult = new String(captor.getValue());
|
||||
final Set<String> actualResultSet =
|
||||
Set.of(actualResult.split(BatteryBackupHelper.DELIMITER));
|
||||
assertThat(actualResultSet).isEqualTo(expectedResultSet);
|
||||
}
|
||||
|
||||
private void createTestingData(
|
||||
|
||||
@@ -138,7 +138,7 @@ public final class BatteryDiffEntryTest {
|
||||
// Generates fake testing data.
|
||||
final ContentValues values = getContentValuesWithType(
|
||||
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
|
||||
values.put("drainType",
|
||||
values.put(BatteryHistEntry.KEY_DRAIN_TYPE,
|
||||
Integer.valueOf(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY));
|
||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||
|
||||
@@ -164,7 +164,7 @@ public final class BatteryDiffEntryTest {
|
||||
// Generates fake testing data.
|
||||
final ContentValues values = getContentValuesWithType(
|
||||
ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
|
||||
values.put("userId", Integer.valueOf(1001));
|
||||
values.put(BatteryHistEntry.KEY_USER_ID, Integer.valueOf(1001));
|
||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||
|
||||
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
||||
@@ -189,8 +189,8 @@ public final class BatteryDiffEntryTest {
|
||||
final String fakePackageName = "com.fake.google.com";
|
||||
final ContentValues values = getContentValuesWithType(
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||
values.put("uid", /*invalid uid*/ 10001);
|
||||
values.put("packageName", fakePackageName);
|
||||
values.put(BatteryHistEntry.KEY_UID, /*invalid uid*/ 10001);
|
||||
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, fakePackageName);
|
||||
doReturn(mMockAppInfo).when(mMockPackageManager)
|
||||
.getApplicationInfo(fakePackageName, 0);
|
||||
doReturn(expectedAppLabel).when(mMockPackageManager)
|
||||
@@ -233,7 +233,7 @@ public final class BatteryDiffEntryTest {
|
||||
final String expectedAppLabel = "fake app label";
|
||||
final ContentValues values = getContentValuesWithType(
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||
values.put("appLabel", expectedAppLabel);
|
||||
values.put(BatteryHistEntry.KEY_APP_LABEL, expectedAppLabel);
|
||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||
|
||||
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
||||
@@ -391,8 +391,8 @@ public final class BatteryDiffEntryTest {
|
||||
final String fakePackageName = "com.fake.google.com";
|
||||
final ContentValues values = getContentValuesWithType(
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||
values.put("uid", /*invalid uid*/ 10001);
|
||||
values.put("packageName", fakePackageName);
|
||||
values.put(BatteryHistEntry.KEY_UID, /*invalid uid*/ 10001);
|
||||
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, fakePackageName);
|
||||
final BatteryDiffEntry entry =
|
||||
createBatteryDiffEntry(10, new BatteryHistEntry(values));
|
||||
|
||||
@@ -424,7 +424,7 @@ public final class BatteryDiffEntryTest {
|
||||
final String expectedPackageName = "com.fake.google.com";
|
||||
final ContentValues values = getContentValuesWithType(
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||
values.put("packageName", expectedPackageName);
|
||||
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, expectedPackageName);
|
||||
final BatteryDiffEntry entry =
|
||||
createBatteryDiffEntry(10, new BatteryHistEntry(values));
|
||||
|
||||
@@ -437,7 +437,7 @@ public final class BatteryDiffEntryTest {
|
||||
final ContentValues values = getContentValuesWithType(
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||
values.put(
|
||||
"packageName",
|
||||
BatteryHistEntry.KEY_PACKAGE_NAME,
|
||||
expectedPackageName + ":privileged_process0");
|
||||
final BatteryDiffEntry entry =
|
||||
createBatteryDiffEntry(10, new BatteryHistEntry(values));
|
||||
@@ -445,11 +445,24 @@ public final class BatteryDiffEntryTest {
|
||||
assertThat(entry.getPackageName()).isEqualTo(expectedPackageName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAppLabel_withOtherUsersUid_returnExpectedLabel() {
|
||||
final ContentValues values = getContentValuesWithType(
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||
values.put(BatteryHistEntry.KEY_UID, BatteryUtils.UID_OTHER_USERS);
|
||||
|
||||
final BatteryDiffEntry batteryDiffEntry = createBatteryDiffEntry(
|
||||
/*consumePower=*/ 0, new BatteryHistEntry(values));
|
||||
|
||||
assertThat(batteryDiffEntry.getAppLabel())
|
||||
.isEqualTo(mContext.getString(R.string.battery_usage_other_users));
|
||||
}
|
||||
|
||||
private BatteryDiffEntry createBatteryDiffEntry(
|
||||
int consumerType, long uid, boolean isHidden) {
|
||||
final ContentValues values = getContentValuesWithType(consumerType);
|
||||
values.put("isHidden", isHidden);
|
||||
values.put("uid", uid);
|
||||
values.put(BatteryHistEntry.KEY_IS_HIDDEN, isHidden);
|
||||
values.put(BatteryHistEntry.KEY_UID, uid);
|
||||
return new BatteryDiffEntry(
|
||||
mContext,
|
||||
/*foregroundUsageTimeInMs=*/ 0,
|
||||
@@ -472,15 +485,15 @@ public final class BatteryDiffEntryTest {
|
||||
|
||||
private static ContentValues getContentValuesWithType(int consumerType) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put("consumerType", Integer.valueOf(consumerType));
|
||||
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE, Integer.valueOf(consumerType));
|
||||
return values;
|
||||
}
|
||||
|
||||
private BatteryDiffEntry createBatteryDiffEntry(Drawable drawable) throws Exception {
|
||||
final ContentValues values = getContentValuesWithType(
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||
values.put("uid", 1001);
|
||||
values.put("packageName", "com.a.b.c");
|
||||
values.put(BatteryHistEntry.KEY_UID, 1001);
|
||||
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, "com.a.b.c");
|
||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||
doReturn(drawable).when(mMockPackageManager).getDefaultActivityIcon();
|
||||
doReturn(null).when(mMockPackageManager).getApplicationInfo("com.a.b.c", 0);
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.os.BatteryUsageStats;
|
||||
import android.os.LocaleList;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
|
||||
@@ -39,6 +40,7 @@ import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -371,6 +373,71 @@ public final class ConvertUtilsTest {
|
||||
assertThat(ConvertUtils.getLocale(mContext)).isEqualTo(Locale.getDefault());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveMultiUsersData_replaceOtherUsersItemWithExpectedEntry() {
|
||||
final int currentUserId = mContext.getUserId();
|
||||
final Map<Integer, List<BatteryDiffEntry>> entryMap = new HashMap<>();
|
||||
// Without other users time slot.
|
||||
entryMap.put(0, Arrays.asList(
|
||||
createBatteryDiffEntry(
|
||||
currentUserId,
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
|
||||
/*consumePercentage=*/ 50)));
|
||||
// With other users time slot.
|
||||
final List<BatteryDiffEntry> withOtherUsersList = new ArrayList<>();
|
||||
entryMap.put(1, withOtherUsersList);
|
||||
withOtherUsersList.add(
|
||||
createBatteryDiffEntry(
|
||||
currentUserId + 1,
|
||||
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY,
|
||||
/*consumePercentage=*/ 20));
|
||||
withOtherUsersList.add(
|
||||
createBatteryDiffEntry(
|
||||
currentUserId + 2,
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
|
||||
/*consumePercentage=*/ 30));
|
||||
withOtherUsersList.add(
|
||||
createBatteryDiffEntry(
|
||||
currentUserId + 3,
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
|
||||
/*consumePercentage=*/ 40));
|
||||
|
||||
ConvertUtils.resolveMultiUsersData(mContext, entryMap);
|
||||
|
||||
assertThat(entryMap.get(0).get(0).getPercentOfTotal()).isEqualTo(50);
|
||||
// Asserts with other users items.
|
||||
final List<BatteryDiffEntry> entryList = entryMap.get(1);
|
||||
assertThat(entryList).hasSize(2);
|
||||
assertBatteryDiffEntry(
|
||||
entryList.get(0),
|
||||
currentUserId + 1,
|
||||
/*uid=*/ 0,
|
||||
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY,
|
||||
/*consumePercentage=*/ 20);
|
||||
assertBatteryDiffEntry(
|
||||
entryList.get(1),
|
||||
BatteryUtils.UID_OTHER_USERS,
|
||||
BatteryUtils.UID_OTHER_USERS,
|
||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
|
||||
/*consumePercentage=*/ 70);
|
||||
}
|
||||
|
||||
private BatteryDiffEntry createBatteryDiffEntry(
|
||||
long userId, int counsumerType, double consumePercentage) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(BatteryHistEntry.KEY_USER_ID, userId);
|
||||
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE, counsumerType);
|
||||
final BatteryDiffEntry batteryDiffEntry =
|
||||
new BatteryDiffEntry(
|
||||
mContext,
|
||||
/*foregroundUsageTimeInMs=*/ 0,
|
||||
/*backgroundUsageTimeInMs=*/ 0,
|
||||
/*consumePower=*/ consumePercentage,
|
||||
new BatteryHistEntry(values));
|
||||
batteryDiffEntry.setTotalConsumePower(100f);
|
||||
return batteryDiffEntry;
|
||||
}
|
||||
|
||||
private static BatteryHistEntry createBatteryHistEntry(
|
||||
String packageName, String appLabel, double consumePower,
|
||||
long uid, long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) {
|
||||
@@ -389,6 +456,15 @@ public final class ConvertUtilsTest {
|
||||
return new BatteryHistEntry(values);
|
||||
}
|
||||
|
||||
private static void assertBatteryDiffEntry(
|
||||
BatteryDiffEntry entry, long userId, long uid, int counsumerType,
|
||||
double consumePercentage) {
|
||||
assertThat(entry.mBatteryHistEntry.mUid).isEqualTo(uid);
|
||||
assertThat(entry.mBatteryHistEntry.mUserId).isEqualTo(userId);
|
||||
assertThat(entry.mBatteryHistEntry.mConsumerType).isEqualTo(counsumerType);
|
||||
assertThat(entry.getPercentOfTotal()).isEqualTo(consumePercentage);
|
||||
}
|
||||
|
||||
private static void assertBatteryDiffEntry(
|
||||
BatteryDiffEntry entry, int percentOfTotal,
|
||||
long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) {
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.android.settings.security.SecurityFeatureProvider;
|
||||
import com.android.settings.security.SecuritySettingsFeatureProvider;
|
||||
import com.android.settings.slices.SlicesFeatureProvider;
|
||||
import com.android.settings.users.UserFeatureProvider;
|
||||
import com.android.settings.vpn2.AdvancedVpnFeatureProvider;
|
||||
import com.android.settings.wifi.WifiTrackerLibProvider;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
|
||||
@@ -87,6 +88,7 @@ public class FakeFeatureFactory extends FeatureFactory {
|
||||
public SecuritySettingsFeatureProvider securitySettingsFeatureProvider;
|
||||
public AccessibilitySearchFeatureProvider mAccessibilitySearchFeatureProvider;
|
||||
public AccessibilityMetricsFeatureProvider mAccessibilityMetricsFeatureProvider;
|
||||
public AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider;
|
||||
|
||||
/**
|
||||
* Call this in {@code @Before} method of the test class to use fake factory.
|
||||
@@ -136,6 +138,7 @@ public class FakeFeatureFactory extends FeatureFactory {
|
||||
securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
|
||||
mAccessibilitySearchFeatureProvider = mock(AccessibilitySearchFeatureProvider.class);
|
||||
mAccessibilityMetricsFeatureProvider = mock(AccessibilityMetricsFeatureProvider.class);
|
||||
mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -272,4 +275,9 @@ public class FakeFeatureFactory extends FeatureFactory {
|
||||
public AccessibilityMetricsFeatureProvider getAccessibilityMetricsFeatureProvider() {
|
||||
return mAccessibilityMetricsFeatureProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedVpnFeatureProvider getAdvancedVpnFeatureProvider() {
|
||||
return mAdvancedVpnFeatureProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,15 +27,12 @@ import android.view.Display;
|
||||
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ScreenResolutionFragmentTest {
|
||||
|
||||
private Context mContext;
|
||||
@@ -56,6 +53,7 @@ public class ScreenResolutionFragmentTest {
|
||||
public void getDefaultKey_FHD() {
|
||||
Display.Mode mode = new Display.Mode(0, FHD_WIDTH, 0, 0);
|
||||
doReturn(mode).when(mFragment).getDisplayMode();
|
||||
doReturn(mContext).when(mFragment).getContext();
|
||||
|
||||
mFragment.onAttach(mContext);
|
||||
assertThat(mFragment.getDefaultKey()).isEqualTo(mFragment.getKeyForResolution(FHD_WIDTH));
|
||||
@@ -66,6 +64,7 @@ public class ScreenResolutionFragmentTest {
|
||||
public void getDefaultKey_QHD() {
|
||||
Display.Mode mode = new Display.Mode(0, QHD_WIDTH, 0, 0);
|
||||
doReturn(mode).when(mFragment).getDisplayMode();
|
||||
doReturn(mContext).when(mFragment).getContext();
|
||||
|
||||
mFragment.onAttach(mContext);
|
||||
assertThat(mFragment.getDefaultKey()).isEqualTo(mFragment.getKeyForResolution(QHD_WIDTH));
|
||||
@@ -74,6 +73,7 @@ public class ScreenResolutionFragmentTest {
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void setDefaultKey_FHD() {
|
||||
doReturn(mContext).when(mFragment).getContext();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
mFragment.setDefaultKey(mFragment.getKeyForResolution(FHD_WIDTH));
|
||||
@@ -84,6 +84,7 @@ public class ScreenResolutionFragmentTest {
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void setDefaultKey_QHD() {
|
||||
doReturn(mContext).when(mFragment).getContext();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
mFragment.setDefaultKey(mFragment.getKeyForResolution(QHD_WIDTH));
|
||||
@@ -94,6 +95,7 @@ public class ScreenResolutionFragmentTest {
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void bindPreferenceExtra_setSummary() {
|
||||
doReturn(mContext).when(mFragment).getContext();
|
||||
mFragment.onAttach(mContext);
|
||||
SelectorWithWidgetPreference preference = new SelectorWithWidgetPreference(mContext);
|
||||
ScreenResolutionFragment.ScreenResolutionCandidateInfo candidates =
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.android.settings.security.SecurityFeatureProvider;
|
||||
import com.android.settings.security.SecuritySettingsFeatureProvider;
|
||||
import com.android.settings.slices.SlicesFeatureProvider;
|
||||
import com.android.settings.users.UserFeatureProvider;
|
||||
import com.android.settings.vpn2.AdvancedVpnFeatureProvider;
|
||||
import com.android.settings.wifi.WifiTrackerLibProvider;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
|
||||
@@ -82,6 +83,7 @@ public class FakeFeatureFactory extends FeatureFactory {
|
||||
public SecuritySettingsFeatureProvider securitySettingsFeatureProvider;
|
||||
public AccessibilitySearchFeatureProvider mAccessibilitySearchFeatureProvider;
|
||||
public AccessibilityMetricsFeatureProvider mAccessibilityMetricsFeatureProvider;
|
||||
public AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider;
|
||||
|
||||
/**
|
||||
* Call this in {@code @Before} method of the test class to use fake factory.
|
||||
@@ -122,6 +124,7 @@ public class FakeFeatureFactory extends FeatureFactory {
|
||||
securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
|
||||
mAccessibilitySearchFeatureProvider = mock(AccessibilitySearchFeatureProvider.class);
|
||||
mAccessibilityMetricsFeatureProvider = mock(AccessibilityMetricsFeatureProvider.class);
|
||||
mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -258,4 +261,9 @@ public class FakeFeatureFactory extends FeatureFactory {
|
||||
public AccessibilityMetricsFeatureProvider getAccessibilityMetricsFeatureProvider() {
|
||||
return mAccessibilityMetricsFeatureProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedVpnFeatureProvider getAdvancedVpnFeatureProvider() {
|
||||
return mAdvancedVpnFeatureProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.vpn2;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AppManagementFragmentTest {
|
||||
private static final String FAKE_PACKAGE_NAME = "com.fake.package.name";
|
||||
private static final String ADVANCED_VPN_GROUP_PACKAGE_NAME = "com.advanced.package.name";
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
|
||||
private AppManagementFragment mFragment;
|
||||
private Context mContext;
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
private RestrictedPreference mPreferenceForget;
|
||||
|
||||
@Before
|
||||
@UiThreadTest
|
||||
public void setUp() {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
|
||||
mFragment = spy(new AppManagementFragment());
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mPreferenceForget = new RestrictedPreference(mContext);
|
||||
|
||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mFragment.init(ADVANCED_VPN_GROUP_PACKAGE_NAME,
|
||||
mFakeFeatureFactory.getAdvancedVpnFeatureProvider(), mPreferenceForget);
|
||||
when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.getAdvancedVpnPackageName())
|
||||
.thenReturn(ADVANCED_VPN_GROUP_PACKAGE_NAME);
|
||||
when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isAdvancedVpnSupported(any()))
|
||||
.thenReturn(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateRestrictedViews_isAdvancedVpn_hidesForgetPreference() {
|
||||
when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isAdvancedVpnRemovable())
|
||||
.thenReturn(false);
|
||||
mFragment.updateRestrictedViews();
|
||||
assertThat(mPreferenceForget.isVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateRestrictedViews_isNotAdvancedVpn_showsForgetPreference() {
|
||||
when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isAdvancedVpnRemovable())
|
||||
.thenReturn(false);
|
||||
mFragment.init(FAKE_PACKAGE_NAME,
|
||||
mFakeFeatureFactory.getAdvancedVpnFeatureProvider(), mPreferenceForget);
|
||||
mFragment.updateRestrictedViews();
|
||||
assertThat(mPreferenceForget.isVisible()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateRestrictedViews_isAdvancedVpnRemovable_showsForgetPreference() {
|
||||
when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isAdvancedVpnRemovable())
|
||||
.thenReturn(true);
|
||||
mFragment.init(FAKE_PACKAGE_NAME,
|
||||
mFakeFeatureFactory.getAdvancedVpnFeatureProvider(), mPreferenceForget);
|
||||
mFragment.updateRestrictedViews();
|
||||
assertThat(mPreferenceForget.isVisible()).isTrue();
|
||||
}
|
||||
}
|
||||
185
tests/unit/src/com/android/settings/vpn2/VpnSettingsTest.java
Normal file
185
tests/unit/src/com/android/settings/vpn2/VpnSettingsTest.java
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.vpn2;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Looper;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class VpnSettingsTest {
|
||||
private static final String ADVANCED_VPN_GROUP_KEY = "advanced_vpn_group";
|
||||
private static final String VPN_GROUP_KEY = "vpn_group";
|
||||
private static final String ADVANCED_VPN_GROUP_TITLE = "advanced_vpn_group_title";
|
||||
private static final String VPN_GROUP_TITLE = "vpn_group_title";
|
||||
private static final String FAKE_PACKAGE_NAME = "com.fake.package.name";
|
||||
private static final String ADVANCED_VPN_GROUP_PACKAGE_NAME = "com.advanced.package.name";
|
||||
private static final int USER_ID_1 = UserHandle.USER_NULL;
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
private AppOpsManager mAppOpsManager;
|
||||
|
||||
private VpnSettings mVpnSettings;
|
||||
private Context mContext;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
private PreferenceGroup mAdvancedVpnGroup;
|
||||
private PreferenceGroup mVpnGroup;
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
|
||||
@Before
|
||||
@UiThreadTest
|
||||
public void setUp() throws PackageManager.NameNotFoundException {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
|
||||
mVpnSettings = spy(new VpnSettings());
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mAdvancedVpnGroup = spy(new PreferenceCategory(mContext));
|
||||
mVpnGroup = spy(new PreferenceCategory(mContext));
|
||||
mAdvancedVpnGroup.setKey(ADVANCED_VPN_GROUP_KEY);
|
||||
mVpnGroup.setKey(VPN_GROUP_KEY);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
|
||||
mPreferenceScreen.addPreference(mAdvancedVpnGroup);
|
||||
mPreferenceScreen.addPreference(mVpnGroup);
|
||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mVpnSettings.init(mPreferenceScreen, mFakeFeatureFactory.getAdvancedVpnFeatureProvider());
|
||||
|
||||
when(mVpnSettings.getContext()).thenReturn(mContext);
|
||||
when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider
|
||||
.getAdvancedVpnPreferenceGroupTitle(mContext)).thenReturn(ADVANCED_VPN_GROUP_TITLE);
|
||||
when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.getVpnPreferenceGroupTitle(mContext))
|
||||
.thenReturn(VPN_GROUP_TITLE);
|
||||
when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.getAdvancedVpnPackageName())
|
||||
.thenReturn(ADVANCED_VPN_GROUP_PACKAGE_NAME);
|
||||
when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isAdvancedVpnSupported(any()))
|
||||
.thenReturn(true);
|
||||
doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
|
||||
doReturn(mContext).when(mContext).createPackageContextAsUser(any(), anyInt(), any());
|
||||
doReturn(mPreferenceManager).when(mVpnGroup).getPreferenceManager();
|
||||
doReturn(mPreferenceManager).when(mAdvancedVpnGroup).getPreferenceManager();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setShownAdvancedPreferences_hasGeneralVpn_returnsVpnCountAs1() {
|
||||
Set<Preference> updates = new ArraySet<>();
|
||||
AppPreference pref =
|
||||
spy(new AppPreference(mContext, USER_ID_1, FAKE_PACKAGE_NAME));
|
||||
updates.add(pref);
|
||||
|
||||
mVpnSettings.setShownAdvancedPreferences(updates);
|
||||
|
||||
assertThat(mVpnGroup.getPreferenceCount()).isEqualTo(1);
|
||||
assertThat(mVpnGroup.isVisible()).isTrue();
|
||||
assertThat(mAdvancedVpnGroup.isVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setShownAdvancedPreferences_hasAdvancedVpn_returnsAdvancedVpnCountAs1() {
|
||||
Set<Preference> updates = new ArraySet<>();
|
||||
AppPreference pref =
|
||||
spy(new AppPreference(mContext, USER_ID_1, ADVANCED_VPN_GROUP_PACKAGE_NAME));
|
||||
updates.add(pref);
|
||||
|
||||
mVpnSettings.setShownAdvancedPreferences(updates);
|
||||
|
||||
assertThat(mAdvancedVpnGroup.getPreferenceCount()).isEqualTo(1);
|
||||
assertThat(mAdvancedVpnGroup.isVisible()).isTrue();
|
||||
assertThat(mVpnGroup.isVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setShownAdvancedPreferences_noVpn_returnsEmpty() {
|
||||
Set<Preference> updates = new ArraySet<>();
|
||||
|
||||
mVpnSettings.setShownAdvancedPreferences(updates);
|
||||
|
||||
assertThat(mAdvancedVpnGroup.getPreferenceCount()).isEqualTo(0);
|
||||
assertThat(mVpnGroup.getPreferenceCount()).isEqualTo(0);
|
||||
assertThat(mAdvancedVpnGroup.isVisible()).isFalse();
|
||||
assertThat(mVpnGroup.isVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getVpnApps_isAdvancedVpn_returnsOne() {
|
||||
int uid = 1111;
|
||||
List<AppOpsManager.OpEntry> opEntries = new ArrayList<>();
|
||||
List<AppOpsManager.PackageOps> apps = new ArrayList<>();
|
||||
AppOpsManager.PackageOps packageOps =
|
||||
new AppOpsManager.PackageOps(ADVANCED_VPN_GROUP_PACKAGE_NAME, uid, opEntries);
|
||||
apps.add(packageOps);
|
||||
when(mAppOpsManager.getPackagesForOps((int[]) any())).thenReturn(apps);
|
||||
|
||||
assertThat(VpnSettings.getVpnApps(mContext, /* includeProfiles= */ false,
|
||||
mFakeFeatureFactory.getAdvancedVpnFeatureProvider(),
|
||||
mAppOpsManager).size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getVpnApps_isNotAdvancedVpn_returnsEmpty() {
|
||||
int uid = 1111;
|
||||
List<AppOpsManager.OpEntry> opEntries = new ArrayList<>();
|
||||
List<AppOpsManager.PackageOps> apps = new ArrayList<>();
|
||||
AppOpsManager.PackageOps packageOps =
|
||||
new AppOpsManager.PackageOps(FAKE_PACKAGE_NAME, uid, opEntries);
|
||||
apps.add(packageOps);
|
||||
when(mAppOpsManager.getPackagesForOps((int[]) any())).thenReturn(apps);
|
||||
|
||||
assertThat(VpnSettings.getVpnApps(mContext, /* includeProfiles= */ false,
|
||||
mFakeFeatureFactory.getAdvancedVpnFeatureProvider(),
|
||||
mAppOpsManager)).isEmpty();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user