Snap for 5045582 from 5cb7e3c0ab to qt-release
Change-Id: I1cf975972af715e185419980dbed01fb338e7589
This commit is contained in:
10
Android.mk
10
Android.mk
@@ -41,6 +41,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
androidx.lifecycle_lifecycle-extensions \
|
||||
guava \
|
||||
jsr305 \
|
||||
contextualcards \
|
||||
settings-logtags \
|
||||
|
||||
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
|
||||
@@ -57,7 +58,14 @@ include frameworks/base/packages/SettingsLib/search/common.mk
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
|
||||
# ==== prebuilt library ========================
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
|
||||
contextualcards:libs/contextualcards.aar
|
||||
include $(BUILD_MULTI_PREBUILT)
|
||||
|
||||
# Use the following include to make our test apk.
|
||||
ifeq (,$(ONE_SHOT_MAKEFILE))
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
endif
|
||||
endif
|
||||
@@ -3192,6 +3192,15 @@
|
||||
android:exported="true"
|
||||
android:permission="android.permission.WRITE_SETTINGS_HOMEPAGE_DATA" />
|
||||
|
||||
<provider
|
||||
android:name=".homepage.contextualcards.SettingsContextualCardProvider"
|
||||
android:authorities="com.android.settings.homepage.contextualcards"
|
||||
android:permission="android.permission.WRITE_SETTINGS_HOMEPAGE_DATA"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.action.SETTINGS_HOMEPAGE_DATA"/>
|
||||
</intent-filter>
|
||||
</provider>
|
||||
<!-- This is the longest AndroidManifest.xml ever. -->
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
BIN
libs/contextualcards.aar
Executable file
BIN
libs/contextualcards.aar
Executable file
Binary file not shown.
@@ -384,15 +384,15 @@
|
||||
<!-- Summary for bluetooth item in connection detail page. (phone)-->
|
||||
<string name="bluetooth_pref_summary" product="default">Allow your phone to communicate with nearby Bluetooth devices</string>
|
||||
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=40] -->
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=none] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload">Disable Bluetooth A2DP hardware offload</string>
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=20] -->
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=none] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload_dialog_title">Restart Device?</string>
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=60] -->
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=none] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload_dialog_message">You need to restart your device to change this setting.</string>
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=10] -->
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=none] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload_dialog_confirm">Restart</string>
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=10] -->
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=none] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload_dialog_cancel">Cancel</string>
|
||||
|
||||
<!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
|
||||
|
||||
@@ -67,6 +67,12 @@
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:controller="com.android.settings.applications.appinfo.AppDataUsagePreferenceController" />
|
||||
|
||||
<Preference
|
||||
android:key="data_settings_v2"
|
||||
android:title="@string/data_usage_app_summary_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:controller="com.android.settings.applications.appinfo.AppDataUsagePreferenceControllerV2" />
|
||||
|
||||
<Preference
|
||||
android:key="time_spent_in_app"
|
||||
android:title="@string/time_spent_in_app_pref_title"
|
||||
|
||||
@@ -47,7 +47,10 @@
|
||||
android:order="3"
|
||||
android:title="@string/status_number"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:selectable="false"/>
|
||||
android:selectable="false"
|
||||
settings:allowDynamicSummaryInSlice="true"
|
||||
settings:controller=
|
||||
"com.android.settings.deviceinfo.PhoneNumberPreferenceController" />
|
||||
|
||||
<Preference
|
||||
android:key="emergency_info"
|
||||
|
||||
@@ -205,7 +205,7 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
try {
|
||||
final ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(keyData));
|
||||
final PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
|
||||
final String algOid = pki.getAlgorithmId().getAlgorithm().getId();
|
||||
final String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
|
||||
final String algName = new AlgorithmId(new ObjectIdentifier(algOid)).getName();
|
||||
|
||||
return KeyChain.isBoundKeyAlgorithm(algName);
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.applications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.os.Build;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Based off from
|
||||
* packages/apps/PackageInstaller/src/com/android/packageinstaller/permission/AppPermissions.java
|
||||
* Except we only care about the number rather than the details.
|
||||
*/
|
||||
public final class AppPermissions {
|
||||
private static final String TAG = "AppPermissions";
|
||||
|
||||
private final ArrayMap<String, PermissionGroup> mGroups = new ArrayMap<>();
|
||||
private final Context mContext;
|
||||
private final PackageInfo mPackageInfo;
|
||||
|
||||
public AppPermissions(Context context, String packageName) {
|
||||
mContext = context;
|
||||
mPackageInfo = getPackageInfo(packageName);
|
||||
refresh();
|
||||
}
|
||||
|
||||
private PackageInfo getPackageInfo(String packageName) {
|
||||
try {
|
||||
return mContext.getPackageManager().getPackageInfo(packageName,
|
||||
PackageManager.GET_PERMISSIONS);
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e(TAG, "Unable to find " + packageName, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
if (mPackageInfo != null) {
|
||||
loadPermissionGroups();
|
||||
}
|
||||
}
|
||||
|
||||
public int getPermissionCount() {
|
||||
return mGroups.size();
|
||||
}
|
||||
|
||||
public int getGrantedPermissionsCount() {
|
||||
int ct = 0;
|
||||
for (int i = 0; i < mGroups.size(); i++) {
|
||||
if (mGroups.valueAt(i).areRuntimePermissionsGranted()) {
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
private void loadPermissionGroups() {
|
||||
mGroups.clear();
|
||||
if (mPackageInfo.requestedPermissions == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean appSupportsRuntimePermissions = appSupportsRuntime(
|
||||
mPackageInfo.applicationInfo);
|
||||
|
||||
for (int i = 0; i < mPackageInfo.requestedPermissions.length; i++) {
|
||||
String requestedPerm = mPackageInfo.requestedPermissions[i];
|
||||
|
||||
final PermissionInfo permInfo;
|
||||
try {
|
||||
permInfo = mContext.getPackageManager().getPermissionInfo(requestedPerm, 0);
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.w(TAG, "Unknown permission: " + requestedPerm);
|
||||
continue;
|
||||
}
|
||||
|
||||
String permName = permInfo.name;
|
||||
String groupName = permInfo.group != null ? permInfo.group : permName;
|
||||
|
||||
PermissionGroup group = mGroups.get(groupName);
|
||||
if (group == null) {
|
||||
group = new PermissionGroup();
|
||||
mGroups.put(groupName, group);
|
||||
}
|
||||
|
||||
final boolean runtime = appSupportsRuntimePermissions
|
||||
&& permInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
|
||||
final boolean granted = (mPackageInfo.requestedPermissionsFlags[i]
|
||||
& PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
|
||||
|
||||
Permission permission = new Permission(runtime, granted);
|
||||
group.addPermission(permission, permName);
|
||||
}
|
||||
// Only care about runtime perms for now.
|
||||
for (int i = mGroups.size() - 1; i >= 0; i--) {
|
||||
if (!mGroups.valueAt(i).mHasRuntimePermissions) {
|
||||
mGroups.removeAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean appSupportsRuntime(ApplicationInfo info) {
|
||||
return info.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1;
|
||||
}
|
||||
|
||||
private static final class PermissionGroup {
|
||||
private final ArrayMap<String, Permission> mPermissions = new ArrayMap<>();
|
||||
private boolean mHasRuntimePermissions;
|
||||
|
||||
public boolean hasRuntimePermissions() {
|
||||
return mHasRuntimePermissions;
|
||||
}
|
||||
|
||||
public boolean areRuntimePermissionsGranted() {
|
||||
final int permissionCount = mPermissions.size();
|
||||
for (int i = 0; i < permissionCount; i++) {
|
||||
Permission permission = mPermissions.valueAt(i);
|
||||
if (permission.runtime && !permission.granted) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<Permission> getPermissions() {
|
||||
return new ArrayList<>(mPermissions.values());
|
||||
}
|
||||
|
||||
void addPermission(Permission permission, String permName) {
|
||||
mPermissions.put(permName, permission);
|
||||
if (permission.runtime) {
|
||||
mHasRuntimePermissions = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Permission {
|
||||
private final boolean runtime;
|
||||
private boolean granted;
|
||||
|
||||
public Permission(boolean runtime, boolean granted) {
|
||||
this.runtime = runtime;
|
||||
this.granted = granted;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import androidx.preference.PreferenceScreen;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.datausage.AppStateDataUsageBridge;
|
||||
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
|
||||
import com.android.settings.datausage.DataSaverBackend;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
@@ -108,8 +109,8 @@ public class SpecialAppAccessPreferenceController extends BasePreferenceControll
|
||||
if (!ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(entry)) {
|
||||
continue;
|
||||
}
|
||||
if (entry.extraInfo != null && ((AppStateDataUsageBridge.DataUsageState)
|
||||
entry.extraInfo).isDataSaverWhitelisted) {
|
||||
if (entry.extraInfo instanceof DataUsageState
|
||||
&& ((DataUsageState) entry.extraInfo).isDataSaverWhitelisted) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
@@ -35,6 +36,7 @@ import androidx.preference.PreferenceScreen;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.datausage.AppDataUsage;
|
||||
import com.android.settings.datausage.DataUsageList;
|
||||
import com.android.settings.datausage.DataUsageUtils;
|
||||
@@ -45,6 +47,12 @@ import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.net.ChartData;
|
||||
import com.android.settingslib.net.ChartDataLoaderCompat;
|
||||
|
||||
/**
|
||||
* Deprecated in favor of {@link AppDataUsagePreferenceControllerV2}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public class AppDataUsagePreferenceController extends AppInfoPreferenceControllerBase
|
||||
implements LoaderManager.LoaderCallbacks<ChartData>, LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
@@ -57,6 +65,9 @@ public class AppDataUsagePreferenceController extends AppInfoPreferenceControlle
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.DATA_USAGE_V2)) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
return isBandwidthControlEnabled() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@@ -93,7 +104,9 @@ public class AppDataUsagePreferenceController extends AppInfoPreferenceControlle
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mParent.getLoaderManager().destroyLoader(mParent.LOADER_CHART_DATA);
|
||||
if (mStatsSession != null) {
|
||||
mParent.getLoaderManager().destroyLoader(mParent.LOADER_CHART_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.applications.appinfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.Loader;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.datausage.AppDataUsageV2;
|
||||
import com.android.settings.datausage.DataUsageUtils;
|
||||
import com.android.settingslib.AppItem;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.net.NetworkCycleDataForUid;
|
||||
import com.android.settingslib.net.NetworkCycleDataForUidLoader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AppDataUsagePreferenceControllerV2 extends AppInfoPreferenceControllerBase
|
||||
implements LoaderManager.LoaderCallbacks<List<NetworkCycleDataForUid>>, LifecycleObserver,
|
||||
OnResume, OnPause {
|
||||
|
||||
private List<NetworkCycleDataForUid> mAppUsageData;
|
||||
|
||||
public AppDataUsagePreferenceControllerV2(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (!FeatureFlagUtils.isEnabled(mContext, FeatureFlags.DATA_USAGE_V2)) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
return isBandwidthControlEnabled() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
preference.setSummary(getDataSummary());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
if (isAvailable()) {
|
||||
final int uid = mParent.getAppEntry().info.uid;
|
||||
final AppItem app = new AppItem(uid);
|
||||
app.addUid(uid);
|
||||
mParent.getLoaderManager().restartLoader(mParent.LOADER_CHART_DATA, null /* args */,
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (isAvailable()) {
|
||||
mParent.getLoaderManager().destroyLoader(mParent.LOADER_CHART_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<List<NetworkCycleDataForUid>> onCreateLoader(int id, Bundle args) {
|
||||
final NetworkTemplate template = getTemplate(mContext);
|
||||
return NetworkCycleDataForUidLoader.builder(mContext)
|
||||
.setUid(mParent.getAppEntry().info.uid)
|
||||
.setRetrieveDetail(false)
|
||||
.setNetworkTemplate(template)
|
||||
.setSubscriberId(template.getSubscriberId())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<List<NetworkCycleDataForUid>> loader,
|
||||
List<NetworkCycleDataForUid> data) {
|
||||
mAppUsageData = data;
|
||||
updateState(mPreference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<List<NetworkCycleDataForUid>> loader) {
|
||||
// Leave last result.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
|
||||
return AppDataUsageV2.class;
|
||||
}
|
||||
|
||||
private CharSequence getDataSummary() {
|
||||
if (mAppUsageData != null) {
|
||||
long totalBytes = 0;
|
||||
long startTime = System.currentTimeMillis();
|
||||
for (NetworkCycleDataForUid data : mAppUsageData) {
|
||||
totalBytes += data.getTotalUsage();
|
||||
final long cycleStart = data.getStartTime();
|
||||
if (cycleStart < startTime) {
|
||||
startTime = cycleStart;
|
||||
}
|
||||
}
|
||||
if (totalBytes == 0) {
|
||||
return mContext.getString(R.string.no_data_usage);
|
||||
}
|
||||
return mContext.getString(R.string.data_summary_format,
|
||||
Formatter.formatFileSize(mContext, totalBytes),
|
||||
DateUtils.formatDateTime(mContext, startTime,
|
||||
DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH));
|
||||
}
|
||||
return mContext.getString(R.string.computing_size);
|
||||
}
|
||||
|
||||
private static NetworkTemplate getTemplate(Context context) {
|
||||
if (DataUsageUtils.hasReadyMobileRadio(context)) {
|
||||
return NetworkTemplate.buildTemplateMobileWildcard();
|
||||
}
|
||||
if (DataUsageUtils.hasWifiRadio(context)) {
|
||||
return NetworkTemplate.buildTemplateWifiWildcard();
|
||||
}
|
||||
return NetworkTemplate.buildTemplateEthernet();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isBandwidthControlEnabled() {
|
||||
return Utils.isBandwidthControlEnabled();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@@ -48,6 +49,7 @@ import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.applications.manageapplications.ManageApplications;
|
||||
import com.android.settings.applications.specialaccess.pictureinpicture
|
||||
.PictureInPictureDetailPreferenceController;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
@@ -139,7 +141,11 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
final String packageName = getPackageName();
|
||||
use(TimeSpentInAppPreferenceController.class).setPackageName(packageName);
|
||||
|
||||
use(AppDataUsagePreferenceController.class).setParentFragment(this);
|
||||
if (FeatureFlagUtils.isEnabled(context, FeatureFlags.DATA_USAGE_V2)) {
|
||||
use(AppDataUsagePreferenceControllerV2.class).setParentFragment(this);
|
||||
} else {
|
||||
use(AppDataUsagePreferenceController.class).setParentFragment(this);
|
||||
}
|
||||
final AppInstallerInfoPreferenceController installer =
|
||||
use(AppInstallerInfoPreferenceController.class);
|
||||
installer.setPackageName(packageName);
|
||||
|
||||
@@ -80,21 +80,20 @@ public class ExternalSourcesDetails extends AppInfoWithHeader
|
||||
}
|
||||
|
||||
public static CharSequence getPreferenceSummary(Context context, AppEntry entry) {
|
||||
final UserHandle userHandle = UserHandle.getUserHandleForUid(entry.info.uid);
|
||||
final UserManager um = UserManager.get(context);
|
||||
final int userRestrictionSource = um.getUserRestrictionSource(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
|
||||
UserHandle.getUserHandleForUid(entry.info.uid));
|
||||
switch (userRestrictionSource) {
|
||||
case UserManager.RESTRICTION_SOURCE_DEVICE_OWNER:
|
||||
case UserManager.RESTRICTION_SOURCE_PROFILE_OWNER:
|
||||
return context.getString(R.string.disabled_by_admin);
|
||||
case UserManager.RESTRICTION_SOURCE_SYSTEM:
|
||||
return context.getString(R.string.disabled);
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userHandle)
|
||||
| um.getUserRestrictionSource(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
|
||||
userHandle);
|
||||
if ((userRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
|
||||
return context.getString(R.string.disabled_by_admin);
|
||||
} else if (userRestrictionSource != 0) {
|
||||
return context.getString(R.string.disabled);
|
||||
}
|
||||
|
||||
final InstallAppsState appsState = new AppStateInstallAppsBridge(context, null, null)
|
||||
.createInstallAppsStateFor(entry.info.packageName, entry.info.uid);
|
||||
|
||||
return context.getString(appsState.canInstallApps()
|
||||
? R.string.app_permission_summary_allowed
|
||||
: R.string.app_permission_summary_not_allowed);
|
||||
@@ -119,6 +118,10 @@ public class ExternalSourcesDetails extends AppInfoWithHeader
|
||||
return true;
|
||||
}
|
||||
mSwitchPref.checkRestrictionAndSetDisabled(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
|
||||
if (!mSwitchPref.isDisabledByAdmin()) {
|
||||
mSwitchPref.checkRestrictionAndSetDisabled(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
|
||||
}
|
||||
if (mSwitchPref.isDisabledByAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ package com.android.settings.biometrics.face;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
@@ -39,7 +39,7 @@ public class FaceSettingsAttentionPreferenceController extends TogglePreferenceC
|
||||
|
||||
public FaceSettingsAttentionPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mFaceManager = context.getSystemService(FaceManager.class);
|
||||
mFaceManager = Utils.getFaceManagerOrNull(context);
|
||||
}
|
||||
|
||||
public FaceSettingsAttentionPreferenceController(Context context) {
|
||||
|
||||
@@ -426,11 +426,11 @@ public class DataUsageListV2 extends DataUsageBaseFragment {
|
||||
|
||||
private void startAppDataUsage(AppItem item) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(AppDataUsage.ARG_APP_ITEM, item);
|
||||
args.putParcelable(AppDataUsage.ARG_NETWORK_TEMPLATE, mTemplate);
|
||||
args.putParcelable(AppDataUsageV2.ARG_APP_ITEM, item);
|
||||
args.putParcelable(AppDataUsageV2.ARG_NETWORK_TEMPLATE, mTemplate);
|
||||
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(AppDataUsage.class.getName())
|
||||
.setDestination(AppDataUsageV2.class.getName())
|
||||
.setTitleRes(R.string.app_data_usage)
|
||||
.setArguments(args)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
@@ -490,8 +490,6 @@ public class DataUsageListV2 extends DataUsageBaseFragment {
|
||||
@Override
|
||||
public Loader<List<NetworkCycleChartData>> onCreateLoader(int id, Bundle args) {
|
||||
return NetworkCycleChartDataLoader.builder(getContext())
|
||||
.setNetworkPolicy(services.mPolicyEditor.getPolicy(mTemplate))
|
||||
.setNetworkType(mNetworkType)
|
||||
.setNetworkTemplate(mTemplate)
|
||||
.setSubscriberId(mTelephonyManager.getSubscriberId(mSubId))
|
||||
.build();
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
package com.android.settings.datetime.timezone;
|
||||
|
||||
import android.content.Context;
|
||||
import android.icu.impl.OlsonTimeZone;
|
||||
import android.icu.text.DateFormat;
|
||||
import android.icu.text.DisplayContext;
|
||||
import android.icu.text.SimpleDateFormat;
|
||||
import android.icu.util.BasicTimeZone;
|
||||
import android.icu.util.Calendar;
|
||||
import android.icu.util.TimeZone;
|
||||
import android.icu.util.TimeZoneTransition;
|
||||
@@ -115,17 +115,17 @@ public class TimeZoneInfoPreferenceController extends BaseTimeZonePreferenceCont
|
||||
}
|
||||
|
||||
private TimeZoneTransition findNextDstTransition(TimeZone timeZone) {
|
||||
if (!(timeZone instanceof OlsonTimeZone)) {
|
||||
if (!(timeZone instanceof BasicTimeZone)) {
|
||||
return null;
|
||||
}
|
||||
final OlsonTimeZone olsonTimeZone = (OlsonTimeZone) timeZone;
|
||||
TimeZoneTransition transition = olsonTimeZone.getNextTransition(
|
||||
final BasicTimeZone basicTimeZone = (BasicTimeZone) timeZone;
|
||||
TimeZoneTransition transition = basicTimeZone.getNextTransition(
|
||||
mDate.getTime(), /* inclusive */ false);
|
||||
do {
|
||||
if (transition.getTo().getDSTSavings() != transition.getFrom().getDSTSavings()) {
|
||||
break;
|
||||
}
|
||||
transition = olsonTimeZone.getNextTransition(
|
||||
transition = basicTimeZone.getNextTransition(
|
||||
transition.getTime(), /*inclusive */ false);
|
||||
} while (transition != null);
|
||||
return transition;
|
||||
|
||||
@@ -23,6 +23,8 @@ import android.util.FeatureFlagUtils;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
@@ -29,15 +29,13 @@ import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.DeviceInfoUtils;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PhoneNumberPreferenceController extends AbstractPreferenceController implements
|
||||
PreferenceControllerMixin {
|
||||
public class PhoneNumberPreferenceController extends BasePreferenceController {
|
||||
|
||||
private final static String KEY_PHONE_NUMBER = "phone_number";
|
||||
|
||||
@@ -45,21 +43,20 @@ public class PhoneNumberPreferenceController extends AbstractPreferenceControlle
|
||||
private final SubscriptionManager mSubscriptionManager;
|
||||
private final List<Preference> mPreferenceList = new ArrayList<>();
|
||||
|
||||
public PhoneNumberPreferenceController(Context context) {
|
||||
super(context);
|
||||
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
mSubscriptionManager = (SubscriptionManager) context.getSystemService(
|
||||
Context.TELEPHONY_SUBSCRIPTION_SERVICE);
|
||||
public PhoneNumberPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
|
||||
mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_PHONE_NUMBER;
|
||||
public int getAvailabilityStatus() {
|
||||
return mTelephonyManager.isVoiceCapable() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mTelephonyManager.isVoiceCapable();
|
||||
public CharSequence getSummary() {
|
||||
return getFirstPhoneNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,10 +86,26 @@ public class PhoneNumberPreferenceController extends AbstractPreferenceControlle
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSliceable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private CharSequence getFirstPhoneNumber() {
|
||||
final List<SubscriptionInfo> subscriptionInfoList =
|
||||
mSubscriptionManager.getActiveSubscriptionInfoList();
|
||||
if (subscriptionInfoList == null) {
|
||||
return mContext.getText(R.string.device_info_default);
|
||||
}
|
||||
|
||||
// For now, We only return first result for slice view.
|
||||
return getFormattedPhoneNumber(subscriptionInfoList.get(0));
|
||||
}
|
||||
|
||||
private CharSequence getPhoneNumber(int simSlot) {
|
||||
final SubscriptionInfo subscriptionInfo = getSubscriptionInfo(simSlot);
|
||||
if (subscriptionInfo == null) {
|
||||
return mContext.getString(R.string.device_info_default);
|
||||
return mContext.getText(R.string.device_info_default);
|
||||
}
|
||||
|
||||
return getFormattedPhoneNumber(subscriptionInfo);
|
||||
|
||||
@@ -41,7 +41,6 @@ import com.android.settings.deviceinfo.FccEquipmentIdPreferenceController;
|
||||
import com.android.settings.deviceinfo.FeedbackPreferenceController;
|
||||
import com.android.settings.deviceinfo.IpAddressPreferenceController;
|
||||
import com.android.settings.deviceinfo.ManualPreferenceController;
|
||||
import com.android.settings.deviceinfo.PhoneNumberPreferenceController;
|
||||
import com.android.settings.deviceinfo.RegulatoryInfoPreferenceController;
|
||||
import com.android.settings.deviceinfo.SafetyInfoPreferenceController;
|
||||
import com.android.settings.deviceinfo.UptimePreferenceController;
|
||||
@@ -110,7 +109,6 @@ public class MyDeviceInfoFragment extends DashboardFragment
|
||||
Lifecycle lifecycle) {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new EmergencyInfoPreferenceController(context));
|
||||
controllers.add(new PhoneNumberPreferenceController(context));
|
||||
controllers.add(new BrandedAccountPreferenceController(context));
|
||||
DeviceNamePreferenceController deviceNamePreferenceController =
|
||||
new DeviceNamePreferenceController(context);
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.homepage.contextualcards;
|
||||
|
||||
import static android.provider.SettingsSlicesContract.KEY_WIFI;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.settings.homepage.deviceinfo.DataUsageSlice;
|
||||
import com.android.settings.wifi.WifiSlice;
|
||||
|
||||
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCard;
|
||||
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Provides dynamic card for SettingsIntelligence. */
|
||||
public class SettingsContextualCardProvider extends ContextualCardProvider {
|
||||
|
||||
public static final String CARD_AUTHORITY = "com.android.settings.homepage.contextualcards";
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<ContextualCard> getContextualCards() {
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
final ContextualCard wifiCard =
|
||||
new ContextualCard.Builder()
|
||||
.setSliceUri(WifiSlice.WIFI_URI.toString())
|
||||
.setName(KEY_WIFI)
|
||||
.build();
|
||||
final ContextualCard dataUsageCard =
|
||||
new ContextualCard.Builder()
|
||||
.setSliceUri(DataUsageSlice.DATA_USAGE_CARD_URI.toString())
|
||||
.setName(DataUsageSlice.PATH_DATA_USAGE_CARD)
|
||||
.build();
|
||||
|
||||
cards.add(wifiCard);
|
||||
cards.add(dataUsageCard);
|
||||
return cards;
|
||||
}
|
||||
}
|
||||
@@ -231,9 +231,13 @@ public class ApnEditor extends SettingsPreferenceFragment
|
||||
|
||||
final Intent intent = getIntent();
|
||||
final String action = intent.getAction();
|
||||
if (TextUtils.isEmpty(action)) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
mSubId = intent.getIntExtra(ApnSettings.SUB_ID,
|
||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
|
||||
mReadOnlyApn = false;
|
||||
mReadOnlyApnTypes = null;
|
||||
mReadOnlyApnFields = null;
|
||||
|
||||
@@ -65,6 +65,7 @@ public class BlockPreferenceController extends NotificationPreferenceController
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
LayoutPreference pref = (LayoutPreference) preference;
|
||||
pref.setSelectable(false);
|
||||
SwitchBar bar = pref.findViewById(R.id.switch_bar);
|
||||
if (bar != null) {
|
||||
bar.setSwitchBarText(R.string.notification_switch_label,
|
||||
|
||||
@@ -19,15 +19,16 @@ package com.android.settings.notification;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.text.BidiFormatter;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
public class ZenDeleteRuleDialog extends InstrumentedDialogFragment {
|
||||
protected static final String TAG = "ZenDeleteRuleDialog";
|
||||
private static final String EXTRA_ZEN_RULE_NAME = "zen_rule_name";
|
||||
@@ -43,8 +44,9 @@ public class ZenDeleteRuleDialog extends InstrumentedDialogFragment {
|
||||
|
||||
public static void show(Fragment parent, String ruleName, String id, PositiveClickListener
|
||||
listener) {
|
||||
final BidiFormatter bidi = BidiFormatter.getInstance();
|
||||
final Bundle args = new Bundle();
|
||||
args.putString(EXTRA_ZEN_RULE_NAME, ruleName);
|
||||
args.putString(EXTRA_ZEN_RULE_NAME, bidi.unicodeWrap(ruleName));
|
||||
args.putString(EXTRA_ZEN_RULE_ID, id);
|
||||
mPositiveClickListener = listener;
|
||||
|
||||
|
||||
@@ -94,4 +94,22 @@ public class SpecialAppAccessPreferenceControllerTest {
|
||||
.isEqualTo(mContext.getResources().getQuantityString(
|
||||
R.plurals.special_access_summary, 1, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_wrongExtraInfo_shouldNotIncludeInSummary() {
|
||||
final ArrayList<ApplicationsState.AppEntry> apps = new ArrayList<>();
|
||||
final ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class);
|
||||
entry.hasLauncherEntry = true;
|
||||
entry.info = new ApplicationInfo();
|
||||
entry.extraInfo = new AppStateNotificationBridge.NotificationsSentState();
|
||||
apps.add(entry);
|
||||
when(mSession.getAllApps()).thenReturn(apps);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mController.onExtraInfoUpdated();
|
||||
|
||||
assertThat(mPreference.getSummary())
|
||||
.isEqualTo(mContext.getResources().getQuantityString(
|
||||
R.plurals.special_access_summary, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ public class AppDataUsagePreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void onPause_shouldDestroyDataLoader() {
|
||||
ReflectionHelpers.setField(mController, "mStatsSession", mock(INetworkStatsSession.class));
|
||||
doReturn(mLoaderManager).when(mFragment).getLoaderManager();
|
||||
|
||||
mController.onPause();
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.applications.appinfo;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.datausage.AppDataUsageV2;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;import android.net.INetworkStatsSession;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class AppDataUsagePreferenceControllerV2Test {
|
||||
|
||||
@Mock
|
||||
private LoaderManager mLoaderManager;
|
||||
@Mock
|
||||
private AppInfoDashboardFragment mFragment;
|
||||
|
||||
private Context mContext;
|
||||
private AppDataUsagePreferenceControllerV2 mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application.getApplicationContext());
|
||||
mController = spy(new AppDataUsagePreferenceControllerV2(mContext, "test_key"));
|
||||
mController.setParentFragment(mFragment);
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DATA_USAGE_V2, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_bandwidthControlEnabled_shouldReturnAvailable() {
|
||||
doReturn(true).when(mController).isBandwidthControlEnabled();
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_bandwidthControlDisabled_shouldReturnDisabled() {
|
||||
doReturn(false).when(mController).isBandwidthControlEnabled();
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_notAvailable_shouldNotRestartDataLoader() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DATA_USAGE_V2, false);
|
||||
doReturn(mLoaderManager).when(mFragment).getLoaderManager();
|
||||
|
||||
mController.onResume();
|
||||
|
||||
verify(mLoaderManager, never()).restartLoader(
|
||||
AppInfoDashboardFragment.LOADER_CHART_DATA, Bundle.EMPTY, mController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_isAvailable_shouldRestartDataLoader() {
|
||||
final ConnectivityManager connectivityManager = mock(ConnectivityManager.class);
|
||||
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||
.thenReturn(connectivityManager);
|
||||
when(connectivityManager.isNetworkSupported(anyInt())).thenReturn(true);
|
||||
doReturn(mLoaderManager).when(mFragment).getLoaderManager();
|
||||
doReturn(BasePreferenceController.AVAILABLE).when(mController).getAvailabilityStatus();
|
||||
final AppEntry appEntry = mock(AppEntry.class);
|
||||
appEntry.info = new ApplicationInfo();
|
||||
when(mFragment.getAppEntry()).thenReturn(appEntry);
|
||||
|
||||
mController.onResume();
|
||||
|
||||
verify(mLoaderManager).restartLoader(eq(AppInfoDashboardFragment.LOADER_CHART_DATA),
|
||||
nullable(Bundle.class), eq(mController));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause_shouldDestroyDataLoader() {
|
||||
doReturn(BasePreferenceController.AVAILABLE).when(mController).getAvailabilityStatus();
|
||||
doReturn(mLoaderManager).when(mFragment).getLoaderManager();
|
||||
|
||||
mController.onPause();
|
||||
|
||||
verify(mLoaderManager).destroyLoader(AppInfoDashboardFragment.LOADER_CHART_DATA);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDetailFragmentClass_shouldReturnAppDataUsage() {
|
||||
assertThat(mController.getDetailFragmentClass()).isEqualTo(AppDataUsageV2.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_shouldUpdatePreferenceSummary() {
|
||||
final Preference preference = mock(Preference.class);
|
||||
|
||||
mController.updateState(preference);
|
||||
|
||||
verify(preference).setSummary(any());
|
||||
}
|
||||
}
|
||||
@@ -17,29 +17,36 @@
|
||||
package com.android.settings.applications.appinfo;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
|
||||
import com.android.settings.applications.AppStateInstallAppsBridge;
|
||||
import com.android.settings.applications.AppStateInstallAppsBridge.InstallAppsState;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.RestrictedPreferenceHelper;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowUserManager.class})
|
||||
public class ExternalSourcesDetailsTest {
|
||||
|
||||
@Mock
|
||||
@@ -47,6 +54,8 @@ public class ExternalSourcesDetailsTest {
|
||||
@Mock
|
||||
private RestrictedSwitchPreference mSwitchPref;
|
||||
@Mock
|
||||
private RestrictedPreferenceHelper mHelper;
|
||||
@Mock
|
||||
private PackageInfo mPackageInfo;
|
||||
|
||||
private ExternalSourcesDetails mFragment;
|
||||
@@ -90,5 +99,128 @@ public class ExternalSourcesDetailsTest {
|
||||
mFragment.refreshUi();
|
||||
|
||||
assertThat(mFragment.refreshUi()).isTrue();
|
||||
assertThat(mSwitchPref.isDisabledByAdmin()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshUi_userRestrictionsUnknownSources_disablesSwitchPreference() {
|
||||
// Mocks set up
|
||||
final ExternalSourcesDetails fragment = new ExternalSourcesDetails();
|
||||
final ContextWrapper context = RuntimeEnvironment.application;
|
||||
final UserManager userManager = (UserManager) context.getSystemService(
|
||||
Context.USER_SERVICE);
|
||||
final ShadowUserManager shadowUserManager = Shadow.extract(userManager);
|
||||
|
||||
ReflectionHelpers.setField(fragment, "mSwitchPref", mSwitchPref);
|
||||
ReflectionHelpers.setField(fragment, "mPackageInfo", mPackageInfo);
|
||||
mPackageInfo.applicationInfo = new ApplicationInfo();
|
||||
ReflectionHelpers.setField(fragment, "mUserManager", userManager);
|
||||
ReflectionHelpers.setField(mSwitchPref, "mHelper", mHelper);
|
||||
|
||||
final AppStateInstallAppsBridge appBridge = mock(AppStateInstallAppsBridge.class);
|
||||
ReflectionHelpers.setField(fragment, "mAppBridge", appBridge);
|
||||
when(appBridge.createInstallAppsStateFor(nullable(String.class), anyInt()))
|
||||
.thenReturn(mock(InstallAppsState.class));
|
||||
|
||||
// Test restriction set up
|
||||
shadowUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true);
|
||||
doAnswer((answer) -> {
|
||||
when(mSwitchPref.isDisabledByAdmin()).thenReturn(true);
|
||||
return null;
|
||||
}).when(mSwitchPref).checkRestrictionAndSetDisabled(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
|
||||
|
||||
// Code execution
|
||||
assertThat(fragment.refreshUi()).isTrue();
|
||||
|
||||
// Assertions
|
||||
assertThat(shadowUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
|
||||
UserHandle.of(UserHandle.myUserId()))).isTrue();
|
||||
assertThat(mSwitchPref.isDisabledByAdmin()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshUi_userRestrictionsUnknownSourcesGlobally_disablesSwitchPreference() {
|
||||
// Mocks set up
|
||||
final ExternalSourcesDetails fragment = new ExternalSourcesDetails();
|
||||
final ContextWrapper context = RuntimeEnvironment.application;
|
||||
final UserManager userManager = (UserManager) context.getSystemService(
|
||||
Context.USER_SERVICE);
|
||||
final ShadowUserManager shadowUserManager = Shadow.extract(userManager);
|
||||
|
||||
ReflectionHelpers.setField(fragment, "mSwitchPref", mSwitchPref);
|
||||
ReflectionHelpers.setField(fragment, "mPackageInfo", mPackageInfo);
|
||||
mPackageInfo.applicationInfo = new ApplicationInfo();
|
||||
ReflectionHelpers.setField(fragment, "mUserManager", userManager);
|
||||
ReflectionHelpers.setField(mSwitchPref, "mHelper", mHelper);
|
||||
|
||||
final AppStateInstallAppsBridge appBridge = mock(AppStateInstallAppsBridge.class);
|
||||
ReflectionHelpers.setField(fragment, "mAppBridge", appBridge);
|
||||
when(appBridge.createInstallAppsStateFor(nullable(String.class), anyInt()))
|
||||
.thenReturn(mock(InstallAppsState.class));
|
||||
|
||||
// Test restriction set up
|
||||
shadowUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, true);
|
||||
doAnswer((answer) -> {
|
||||
when(mSwitchPref.isDisabledByAdmin()).thenReturn(true);
|
||||
return null;
|
||||
}).when(mSwitchPref).checkRestrictionAndSetDisabled(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
|
||||
|
||||
// Code execution
|
||||
assertThat(fragment.refreshUi()).isTrue();
|
||||
|
||||
// Assertions
|
||||
assertThat(shadowUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
|
||||
UserHandle.of(UserHandle.myUserId()))).isTrue();
|
||||
assertThat(mSwitchPref.isDisabledByAdmin()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshUi_bothUnknownSourcesUserRestrictions_disableSwitchPreference() {
|
||||
// Mocks set up
|
||||
final ExternalSourcesDetails fragment = new ExternalSourcesDetails();
|
||||
final ContextWrapper context = RuntimeEnvironment.application;
|
||||
final UserManager userManager = (UserManager) context.getSystemService(
|
||||
Context.USER_SERVICE);
|
||||
final ShadowUserManager shadowUserManager = Shadow.extract(userManager);
|
||||
|
||||
ReflectionHelpers.setField(fragment, "mSwitchPref", mSwitchPref);
|
||||
ReflectionHelpers.setField(fragment, "mPackageInfo", mPackageInfo);
|
||||
mPackageInfo.applicationInfo = new ApplicationInfo();
|
||||
ReflectionHelpers.setField(fragment, "mUserManager", userManager);
|
||||
ReflectionHelpers.setField(mSwitchPref, "mHelper", mHelper);
|
||||
|
||||
final AppStateInstallAppsBridge appBridge = mock(AppStateInstallAppsBridge.class);
|
||||
ReflectionHelpers.setField(fragment, "mAppBridge", appBridge);
|
||||
when(appBridge.createInstallAppsStateFor(nullable(String.class), anyInt()))
|
||||
.thenReturn(mock(InstallAppsState.class));
|
||||
|
||||
// Test restriction set up
|
||||
shadowUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, true);
|
||||
shadowUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true);
|
||||
doAnswer((answer) -> {
|
||||
when(mSwitchPref.isDisabledByAdmin()).thenReturn(true);
|
||||
return null;
|
||||
}).when(mSwitchPref).checkRestrictionAndSetDisabled(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
|
||||
|
||||
// Code execution
|
||||
assertThat(fragment.refreshUi()).isTrue();
|
||||
|
||||
// Assertions
|
||||
assertThat(shadowUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
|
||||
UserHandle.of(UserHandle.myUserId()))).isTrue();
|
||||
assertThat(shadowUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
|
||||
UserHandle.of(UserHandle.myUserId()))).isTrue();
|
||||
assertThat(mSwitchPref.isDisabledByAdmin()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
|
||||
package com.android.settings.deviceinfo;
|
||||
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
@@ -27,12 +26,14 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -41,7 +42,6 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class PhoneNumberPreferenceControllerTest {
|
||||
@@ -55,6 +55,8 @@ public class PhoneNumberPreferenceControllerTest {
|
||||
@Mock
|
||||
private SubscriptionInfo mSubscriptionInfo;
|
||||
@Mock
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
private Context mContext;
|
||||
@@ -63,9 +65,10 @@ public class PhoneNumberPreferenceControllerTest {
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = spy(new PhoneNumberPreferenceController(mContext));
|
||||
ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
|
||||
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||
mController = spy(new PhoneNumberPreferenceController(mContext, "phone_number"));
|
||||
final String prefKey = mController.getPreferenceKey();
|
||||
when(mScreen.findPreference(prefKey)).thenReturn(mPreference);
|
||||
when(mScreen.getContext()).thenReturn(mContext);
|
||||
@@ -75,17 +78,19 @@ public class PhoneNumberPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_shouldBeTrueIfCallCapable() {
|
||||
public void getAvailabilityStatus_isVoiceCapable_shouldBeAVAILABLE() {
|
||||
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
|
||||
|
||||
assertTrue(mController.isAvailable());
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_shouldBeFalseIfNotCallCapable() {
|
||||
public void getAvailabilityStatus_isNotVoiceCapable_shouldBeUNSUPPORTED_ON_DEVICE() {
|
||||
when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
|
||||
|
||||
assertFalse(mController.isAvailable());
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,4 +131,19 @@ public class PhoneNumberPreferenceControllerTest {
|
||||
mContext.getString(R.string.status_number_sim_slot, 2 /* sim slot */));
|
||||
verify(mSecondPreference).setSummary(phoneNumber);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_cannotGetActiveSubscriptionInfo_shouldShowUnknown() {
|
||||
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null);
|
||||
|
||||
CharSequence primaryNumber = mController.getSummary();
|
||||
|
||||
assertThat(primaryNumber).isNotNull();
|
||||
assertThat(primaryNumber).isEqualTo(mContext.getString(R.string.device_info_default));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSliceable_shouldBeTrue() {
|
||||
assertThat(mController.isSliceable()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.homepage.contextualcards;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCard;
|
||||
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class SettingsContextualCardProviderTest {
|
||||
|
||||
private Context mContext;
|
||||
private ContentResolver mResolver;
|
||||
private Uri mUri;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mResolver = mContext.getContentResolver();
|
||||
mUri = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsContextualCardProvider.CARD_AUTHORITY)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentProviderCall_returnCorrectSize() {
|
||||
final Bundle returnValue =
|
||||
mResolver.call(mUri, ContextualCardProvider.METHOD_GET_CARD_LIST, "", null);
|
||||
final ArrayList<ContextualCard> cards =
|
||||
returnValue.getParcelableArrayList(ContextualCardProvider.BUNDLE_CARD_LIST);
|
||||
assertThat(cards.size()).isEqualTo(2);
|
||||
}
|
||||
}
|
||||
@@ -19,11 +19,13 @@ package com.android.settings.network;
|
||||
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.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
@@ -450,6 +452,15 @@ public class ApnEditorTest {
|
||||
assertThat(ApnEditor.formatInteger("not an int")).isEqualTo("not an int");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_noAction_shouldFinishAndNoCrash() {
|
||||
doNothing().when(mApnEditorUT).addPreferencesFromResource(anyInt());
|
||||
|
||||
mApnEditorUT.onCreate(null);
|
||||
|
||||
verify(mApnEditorUT).finish();
|
||||
}
|
||||
|
||||
private void initCursor() {
|
||||
doReturn(2).when(mCursor).getColumnCount();
|
||||
doReturn(Integer.valueOf(2)).when(mCursor).getInt(CURSOR_INTEGER_INDEX);
|
||||
|
||||
Reference in New Issue
Block a user