diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b4579771762..dccd1d03bcc 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -57,6 +57,7 @@ + diff --git a/res/drawable/ic_homepage_about.xml b/res/drawable/ic_homepage_about.xml index d47a740b573..07dbb34b0ea 100644 --- a/res/drawable/ic_homepage_about.xml +++ b/res/drawable/ic_homepage_about.xml @@ -18,13 +18,10 @@ - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - - \ No newline at end of file diff --git a/res/drawable/ic_homepage_location.xml b/res/drawable/ic_homepage_location.xml index 413801b0a56..c5d6e8970ff 100644 --- a/res/drawable/ic_homepage_location.xml +++ b/res/drawable/ic_homepage_location.xml @@ -18,13 +18,10 @@ - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - - diff --git a/res/menu/vpn.xml b/res/menu/vpn.xml index 7b35c702f43..a3b8090f8d9 100644 --- a/res/menu/vpn.xml +++ b/res/menu/vpn.xml @@ -18,6 +18,6 @@ diff --git a/res/values/strings.xml b/res/values/strings.xml index 039fb13e070..59374cf114a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -820,9 +820,9 @@ Display power button option that turns off Smart Lock, fingerprint unlocking, and notifications on the lock screen - SmartLock only extends unlock + Trust agents only extend unlock - If enabled, SmartLock will keep your device unlocked for longer, but can no longer unlock a locked device. + If enabled, trust agents will keep your device unlocked for longer, but can no longer unlock a locked device. Lock screen when trust is lost @@ -4771,13 +4771,13 @@ No hearing aids connected - Add hearing aid + Add hearing aids To pair your hearing aids, find and tap your device on the next screen. Make sure your hearing aids are in pairing mode. - %1$s currently active + %1$s active %1$d saved hearing aid @@ -5850,6 +5850,10 @@ Restrict SMS & call log access Only default phone and messaging apps have SMS & call log permissions + + Enable device identifier restrictions + + Enable the new access restrictions for device identifiers. @@ -10270,11 +10274,11 @@ - + Prevent ringing - + Press Power & Volume Up together to - + Shortcut to prevent ringing Vibrate diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index d7fcaec3169..d9b592c0ee6 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -114,6 +114,17 @@ android:key="quick_settings_tiles" android:title="@string/quick_settings_developer_tiles" android:fragment="com.android.settings.development.qstile.DevelopmentTileConfigFragment" /> + + + + + + + + settings:initialExpandedChildrenCount="2"> - - - - - diff --git a/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java b/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java index 1bfcd7d2b92..7d9fdcf75ad 100644 --- a/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java @@ -89,7 +89,7 @@ public class AppDataUsagePreferenceController extends AppInfoPreferenceControlle public Loader> onCreateLoader(int id, Bundle args) { final NetworkTemplate template = getTemplate(mContext); return NetworkCycleDataForUidLoader.builder(mContext) - .setUid(mParent.getAppEntry().info.uid) + .addUid(mParent.getAppEntry().info.uid) .setRetrieveDetail(false) .setNetworkTemplate(template) .setSubscriberId(template.getSubscriberId()) diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java index 69e86cdd0e3..6348b912185 100644 --- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java @@ -46,7 +46,7 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.dashboard.profileselector.ProfileSelectDialog; import com.android.settings.overlay.FeatureFactory; -import com.android.settings.widget.RoundedHomepageIcon; +import com.android.settings.widget.AdaptiveHomepageIcon; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.Tile; @@ -197,8 +197,8 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { Drawable iconDrawable = tileIcon.loadDrawable(preference.getContext()); if (forceRoundedIcon && !TextUtils.equals(mContext.getPackageName(), tile.getPackageName())) { - iconDrawable = new RoundedHomepageIcon(mContext, iconDrawable); - ((RoundedHomepageIcon) iconDrawable).setBackgroundColor(mContext, tile); + iconDrawable = new AdaptiveHomepageIcon(mContext, iconDrawable); + ((AdaptiveHomepageIcon) iconDrawable).setBackgroundColor(mContext, tile); } preference.setIcon(iconDrawable); } else if (tile.getMetaData() != null diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java index 329bf68fe6a..4f388436474 100644 --- a/src/com/android/settings/datausage/AppDataUsage.java +++ b/src/com/android/settings/datausage/AppDataUsage.java @@ -94,10 +94,12 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC private SpinnerPreference mCycle; private RestrictedSwitchPreference mUnrestrictedData; private DataSaverBackend mDataSaverBackend; + private Context mContext; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); + mContext = getContext(); mPackageManager = getPackageManager(); final Bundle args = getArguments(); @@ -105,9 +107,8 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC mTemplate = (args != null) ? (NetworkTemplate) args.getParcelable(ARG_NETWORK_TEMPLATE) : null; if (mTemplate == null) { - Context context = getContext(); - mTemplate = DataUsageUtils.getDefaultTemplate(context, - DataUsageUtils.getDefaultSubscriptionId(context)); + mTemplate = DataUsageUtils.getDefaultTemplate(mContext, + DataUsageUtils.getDefaultSubscriptionId(mContext)); } if (mAppItem == null) { int uid = (args != null) ? args.getInt(AppInfoBase.ARG_PACKAGE_UID, -1) @@ -131,7 +132,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC mBackgroundUsage = findPreference(KEY_BACKGROUND_USAGE); mCycle = (SpinnerPreference) findPreference(KEY_CYCLE); - mCycleAdapter = new CycleAdapter(getContext(), mCycle, mCycleListener); + mCycleAdapter = new CycleAdapter(mContext, mCycle, mCycleListener); if (mAppItem.key > 0) { if (mPackages.size() != 0) { @@ -155,7 +156,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC KEY_UNRESTRICTED_DATA); mUnrestrictedData.setOnPreferenceChangeListener(this); } - mDataSaverBackend = new DataSaverBackend(getContext()); + mDataSaverBackend = new DataSaverBackend(mContext); mAppSettings = findPreference(KEY_APP_SETTINGS); mAppSettingsIntent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE); @@ -256,7 +257,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC private void updatePrefs(boolean restrictBackground, boolean unrestrictData) { final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfMeteredDataRestricted( - getContext(), mPackageName, UserHandle.getUserId(mAppItem.key)); + mContext, mPackageName, UserHandle.getUserId(mAppItem.key)); if (mRestrictBackground != null) { mRestrictBackground.setChecked(!restrictBackground); mRestrictBackground.setDisabledByAdmin(admin); @@ -294,11 +295,10 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC foregroundBytes = data.getForegroudUsage(); } final long totalBytes = backgroundBytes + foregroundBytes; - final Context context = getContext(); - mTotalUsage.setSummary(DataUsageUtils.formatDataUsage(context, totalBytes)); - mForegroundUsage.setSummary(DataUsageUtils.formatDataUsage(context, foregroundBytes)); - mBackgroundUsage.setSummary(DataUsageUtils.formatDataUsage(context, backgroundBytes)); + mTotalUsage.setSummary(DataUsageUtils.formatDataUsage(mContext, totalBytes)); + mForegroundUsage.setSummary(DataUsageUtils.formatDataUsage(mContext, foregroundBytes)); + mBackgroundUsage.setSummary(DataUsageUtils.formatDataUsage(mContext, backgroundBytes)); } private boolean getAppRestrictBackground() { @@ -364,16 +364,24 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC } }; - private final LoaderManager.LoaderCallbacks> mUidDataCallbacks = + @VisibleForTesting + final LoaderManager.LoaderCallbacks> mUidDataCallbacks = new LoaderManager.LoaderCallbacks>() { @Override public Loader> onCreateLoader(int id, Bundle args) { - return NetworkCycleDataForUidLoader.builder(getContext()) - .setUid(mAppItem.key) - .setRetrieveDetail(true) + final NetworkCycleDataForUidLoader.Builder builder + = NetworkCycleDataForUidLoader.builder(mContext); + builder.setRetrieveDetail(true) .setNetworkTemplate(mTemplate) - .setSubscriberId(mTemplate.getSubscriberId()) - .build(); + .setSubscriberId(mTemplate.getSubscriberId()); + if (mAppItem.category == AppItem.CATEGORY_USER) { + for (int i = 0; i < mAppItem.uids.size(); i++) { + builder.addUid(mAppItem.uids.keyAt(i)); + } + } else { + builder.addUid(mAppItem.key); + } + return builder.build(); } @Override diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 5135fbf61fc..78520c6c20d 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -478,6 +478,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new FreeformWindowsPreferenceController(context)); controllers.add(new DesktopModePreferenceController(context)); controllers.add(new SmsAccessRestrictionPreferenceController(context)); + controllers.add(new DeviceIdentifierAccessRestrictionsPreferenceController(context)); controllers.add(new ShortcutManagerThrottlingPreferenceController(context)); controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context)); controllers.add(new DefaultLaunchPreferenceController(context, "running_apps")); @@ -497,6 +498,8 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra "android.theme.customization.font")); controllers.add(new OverlayCategoryPreferenceController(context, "android.theme.customization.adaptive_icon_shape")); + controllers.add(new TrustAgentsExtendUnlockPreferenceController(context)); + controllers.add(new TrustLostLocksScreenPreferenceController(context)); return controllers; } diff --git a/src/com/android/settings/development/DeviceIdentifierAccessRestrictionsPreferenceController.java b/src/com/android/settings/development/DeviceIdentifierAccessRestrictionsPreferenceController.java new file mode 100644 index 00000000000..1fdbe77641c --- /dev/null +++ b/src/com/android/settings/development/DeviceIdentifierAccessRestrictionsPreferenceController.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2019 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.development; + +import android.content.Context; +import android.provider.DeviceConfig; + +import androidx.preference.Preference; +import androidx.preference.SwitchPreference; + +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.development.DeveloperOptionsPreferenceController; + +public class DeviceIdentifierAccessRestrictionsPreferenceController + extends DeveloperOptionsPreferenceController + implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin { + + private static final String DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_KEY = + "device_identifier_access_restrictions"; + + public DeviceIdentifierAccessRestrictionsPreferenceController(Context context) { + super(context); + } + + @Override + public String getPreferenceKey() { + return DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_KEY; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + writeSetting((boolean) newValue); + return true; + } + + private void writeSetting(boolean isEnabled) { + DeviceConfig.setProperty(DeviceConfig.Privacy.NAMESPACE, + DeviceConfig.Privacy.PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED, + String.valueOf(!isEnabled), false); + } + + @Override + public void updateState(Preference preference) { + boolean isEnabled = !Boolean.parseBoolean( + DeviceConfig.getProperty(DeviceConfig.Privacy.NAMESPACE, + DeviceConfig.Privacy.PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED)); + ((SwitchPreference) mPreference).setChecked(isEnabled); + } + + @Override + protected void onDeveloperOptionsSwitchDisabled() { + super.onDeveloperOptionsSwitchDisabled(); + writeSetting(true); + ((SwitchPreference) mPreference).setChecked(true); + } +} diff --git a/src/com/android/settings/development/TrustAgentsExtendUnlockPreferenceController.java b/src/com/android/settings/development/TrustAgentsExtendUnlockPreferenceController.java new file mode 100644 index 00000000000..0834f9b96e2 --- /dev/null +++ b/src/com/android/settings/development/TrustAgentsExtendUnlockPreferenceController.java @@ -0,0 +1,58 @@ +/* + * 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.development; + +import android.content.Context; +import android.provider.Settings; + +import androidx.preference.Preference; +import androidx.preference.SwitchPreference; + +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.development.DeveloperOptionsPreferenceController; + +public class TrustAgentsExtendUnlockPreferenceController extends + DeveloperOptionsPreferenceController implements + Preference.OnPreferenceChangeListener, PreferenceControllerMixin { + + private static final String KEY_TRUST_AGENTS_EXTEND_UNLOCK = + "security_setting_trust_agents_extend_unlock"; + + public TrustAgentsExtendUnlockPreferenceController(Context context) { + super(context); + } + + @Override + public String getPreferenceKey() { + return KEY_TRUST_AGENTS_EXTEND_UNLOCK; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean isEnabled = (Boolean) newValue; + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK, isEnabled ? 1 : 0); + return true; + } + + @Override + public void updateState(Preference preference) { + int trustAgentsExtendUnlock = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK, 0); + ((SwitchPreference) mPreference).setChecked(trustAgentsExtendUnlock != 0); + } +} diff --git a/src/com/android/settings/development/TrustLostLocksScreenPreferenceController.java b/src/com/android/settings/development/TrustLostLocksScreenPreferenceController.java new file mode 100644 index 00000000000..3800fd6b881 --- /dev/null +++ b/src/com/android/settings/development/TrustLostLocksScreenPreferenceController.java @@ -0,0 +1,58 @@ +/* + * 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.development; + +import android.content.Context; +import android.provider.Settings; + +import androidx.preference.Preference; +import androidx.preference.SwitchPreference; + +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.development.DeveloperOptionsPreferenceController; + +public class TrustLostLocksScreenPreferenceController + extends DeveloperOptionsPreferenceController implements + Preference.OnPreferenceChangeListener, PreferenceControllerMixin { + + private static final String KEY_TRUST_LOST_LOCKS_SCREEN = + "security_setting_trust_lost_locks_screen"; + + public TrustLostLocksScreenPreferenceController(Context context) { + super(context); + } + + @Override + public String getPreferenceKey() { + return KEY_TRUST_LOST_LOCKS_SCREEN; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean isEnabled = (Boolean) newValue; + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST, isEnabled ? 1 : 0); + return true; + } + + @Override + public void updateState(Preference preference) { + int lockOnTrustLost = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST, 0); + ((SwitchPreference) mPreference).setChecked(lockOnTrustLost != 0); + } +} diff --git a/src/com/android/settings/homepage/AdaptiveIconShapeDrawable.java b/src/com/android/settings/homepage/AdaptiveIconShapeDrawable.java new file mode 100644 index 00000000000..62b768a6460 --- /dev/null +++ b/src/com/android/settings/homepage/AdaptiveIconShapeDrawable.java @@ -0,0 +1,43 @@ +package com.android.settings.homepage; + +import android.content.res.Resources; +import android.content.res.Resources.Theme; +import android.graphics.Path; +import android.graphics.drawable.AdaptiveIconDrawable; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.PathShape; +import android.util.AttributeSet; +import android.util.PathParser; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + +/** + * Draws a filled {@link ShapeDrawable} using the path from {@link AdaptiveIconDrawable}. + */ +public class AdaptiveIconShapeDrawable extends ShapeDrawable { + public AdaptiveIconShapeDrawable() { + super(); + } + + public AdaptiveIconShapeDrawable(Resources resources) { + super(); + init(resources); + } + + @Override + public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) + throws XmlPullParserException, IOException { + super.inflate(r, parser, attrs, theme); + init(r); + } + + private void init(Resources resources) { + final float pathSize = AdaptiveIconDrawable.MASK_SIZE; + final Path path = new Path(PathParser.createPathFromPathData( + resources.getString(com.android.internal.R.string.config_icon_mask))); + setShape(new PathShape(path, pathSize, pathSize)); + } +} diff --git a/src/com/android/settings/inputmethod/UserDictionarySettings.java b/src/com/android/settings/inputmethod/UserDictionarySettings.java index eccfb3c64fc..c8fb625edd1 100644 --- a/src/com/android/settings/inputmethod/UserDictionarySettings.java +++ b/src/com/android/settings/inputmethod/UserDictionarySettings.java @@ -154,7 +154,7 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { MenuItem actionItem = menu.add(0, OPTIONS_MENU_ADD, 0, R.string.user_dict_settings_add_menu_title) - .setIcon(R.drawable.ic_menu_add_white); + .setIcon(R.drawable.ic_menu_add); actionItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); } diff --git a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java index 3adc489b361..214dcd539ea 100644 --- a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java +++ b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java @@ -18,6 +18,7 @@ import static java.util.concurrent.TimeUnit.DAYS; import android.Manifest; import android.content.Context; import android.content.Intent; +import android.provider.DeviceConfig; import android.view.View; import androidx.annotation.VisibleForTesting; @@ -60,7 +61,9 @@ public class RecentLocationAccessPreferenceController extends AbstractPreference @Override public boolean isAvailable() { - return true; + return Boolean.parseBoolean( + DeviceConfig.getProperty(DeviceConfig.Privacy.NAMESPACE, + DeviceConfig.Privacy.PROPERTY_PERMISSIONS_HUB_ENABLED)); } @Override diff --git a/src/com/android/settings/network/ApnSettings.java b/src/com/android/settings/network/ApnSettings.java index 174257b027b..c397600654d 100755 --- a/src/com/android/settings/network/ApnSettings.java +++ b/src/com/android/settings/network/ApnSettings.java @@ -351,7 +351,7 @@ public class ApnSettings extends RestrictedSettingsFragment if (mAllowAddingApns) { menu.add(0, MENU_NEW, 0, getResources().getString(R.string.menu_new)) - .setIcon(R.drawable.ic_menu_add_white) + .setIcon(R.drawable.ic_menu_add) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); } menu.add(0, MENU_RESTORE, 0, diff --git a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java b/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java index e43140f0ef8..8b9b5955fb4 100644 --- a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java +++ b/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.permission.PermissionControllerManager; import android.permission.RuntimePermissionUsageInfo; +import android.provider.DeviceConfig; import android.util.Log; import android.view.View; @@ -38,6 +39,7 @@ import com.android.settings.core.BasePreferenceController; import com.android.settingslib.widget.BarChartInfo; import com.android.settingslib.widget.BarChartPreference; import com.android.settingslib.widget.BarViewInfo; +import com.android.settingslib.Utils; import java.util.ArrayList; import java.util.Comparator; @@ -62,7 +64,10 @@ public class PermissionBarChartPreferenceController extends BasePreferenceContro @Override public int getAvailabilityStatus() { - return AVAILABLE_UNSEARCHABLE; + return Boolean.parseBoolean( + DeviceConfig.getProperty(DeviceConfig.Privacy.NAMESPACE, + DeviceConfig.Privacy.PROPERTY_PERMISSIONS_HUB_ENABLED)) ? + AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE; } @Override @@ -143,6 +148,7 @@ public class PermissionBarChartPreferenceController extends BasePreferenceContro try { icon = mPackageManager.getPermissionGroupInfo(permissionGroup.toString(), 0) .loadIcon(mPackageManager); + icon.setTintList(Utils.getColorAttr(mContext, android.R.attr.textColorSecondary)); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Cannot find group icon for " + permissionGroup, e); } diff --git a/src/com/android/settings/security/trustagent/TrustAgentsExtendUnlockPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentsExtendUnlockPreferenceController.java deleted file mode 100644 index 036e07f6dc2..00000000000 --- a/src/com/android/settings/security/trustagent/TrustAgentsExtendUnlockPreferenceController.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.security.trustagent; - -import android.content.Context; -import android.provider.Settings; - -import com.android.settings.core.TogglePreferenceController; - -public class TrustAgentsExtendUnlockPreferenceController extends TogglePreferenceController { - - public TrustAgentsExtendUnlockPreferenceController(Context context, String key) { - super(context, key); - } - - @Override - public int getAvailabilityStatus() { - return AVAILABLE; - } - - @Override - public boolean isChecked() { - return Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK, 1) == 1; - } - - @Override - public boolean setChecked(boolean isChecked) { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK, isChecked ? 1 : 0); - return true; - } -} diff --git a/src/com/android/settings/security/trustagent/TrustLostLocksScreenPreferenceController.java b/src/com/android/settings/security/trustagent/TrustLostLocksScreenPreferenceController.java deleted file mode 100644 index e0c516891e3..00000000000 --- a/src/com/android/settings/security/trustagent/TrustLostLocksScreenPreferenceController.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.security.trustagent; - -import android.content.Context; -import android.provider.Settings; - -import com.android.settings.core.TogglePreferenceController; - -public class TrustLostLocksScreenPreferenceController extends TogglePreferenceController { - - public TrustLostLocksScreenPreferenceController(Context context, String key) { - super(context, key); - } - - @Override - public int getAvailabilityStatus() { - return AVAILABLE; - } - - @Override - public boolean isChecked() { - return Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST, 1) == 1; - } - - @Override - public boolean setChecked(boolean isChecked) { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST, isChecked ? 1 : 0); - return true; - } -} diff --git a/src/com/android/settings/slices/SlicesDatabaseAccessor.java b/src/com/android/settings/slices/SlicesDatabaseAccessor.java index ae77dd2a9b9..fcc42e47500 100644 --- a/src/com/android/settings/slices/SlicesDatabaseAccessor.java +++ b/src/com/android/settings/slices/SlicesDatabaseAccessor.java @@ -75,8 +75,9 @@ public class SlicesDatabaseAccessor { if (pathData == null) { throw new IllegalStateException("Invalid Slices uri: " + uri); } - Cursor cursor = getIndexedSliceData(pathData.second /* key */); - return buildSliceData(cursor, uri, pathData.first /* isIntentOnly */); + try (Cursor cursor = getIndexedSliceData(pathData.second /* key */)) { + return buildSliceData(cursor, uri, pathData.first /* isIntentOnly */); + } } /** @@ -85,8 +86,9 @@ public class SlicesDatabaseAccessor { * Used when handling the action of the {@link Slice}. */ public SliceData getSliceDataFromKey(String key) { - Cursor cursor = getIndexedSliceData(key); - return buildSliceData(cursor, null /* uri */, false /* isIntentOnly */); + try (Cursor cursor = getIndexedSliceData(key)) { + return buildSliceData(cursor, null /* uri */, false /* isIntentOnly */); + } } /** diff --git a/src/com/android/settings/widget/RoundedHomepageIcon.java b/src/com/android/settings/widget/AdaptiveHomepageIcon.java similarity index 90% rename from src/com/android/settings/widget/RoundedHomepageIcon.java rename to src/com/android/settings/widget/AdaptiveHomepageIcon.java index f7927e756ca..bec5d8da2c6 100644 --- a/src/com/android/settings/widget/RoundedHomepageIcon.java +++ b/src/com/android/settings/widget/AdaptiveHomepageIcon.java @@ -32,18 +32,19 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.settings.R; +import com.android.settings.homepage.AdaptiveIconShapeDrawable; import com.android.settingslib.drawer.Tile; -public class RoundedHomepageIcon extends LayerDrawable { +public class AdaptiveHomepageIcon extends LayerDrawable { - private static final String TAG = "RoundedHomepageIcon"; + private static final String TAG = "AdaptiveHomepageIcon"; @VisibleForTesting(otherwise = NONE) int mBackgroundColor = -1; - public RoundedHomepageIcon(Context context, Drawable foreground) { + public AdaptiveHomepageIcon(Context context, Drawable foreground) { super(new Drawable[]{ - context.getDrawable(R.drawable.ic_homepage_generic_background), + new AdaptiveIconShapeDrawable(context.getResources()), foreground }); final int insetPx = context.getResources() diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java index 37bb3cdfbc5..12559f4c637 100644 --- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java +++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java @@ -16,6 +16,8 @@ package com.android.settings.datausage; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -31,7 +33,9 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.pm.PackageManager; import android.net.NetworkPolicyManager; +import android.net.NetworkTemplate; import android.os.Bundle; +import android.text.format.DateUtils; import android.util.ArraySet; import android.view.View; @@ -47,6 +51,7 @@ import com.android.settingslib.AppItem; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.net.NetworkCycleDataForUid; +import com.android.settingslib.net.NetworkCycleDataForUidLoader; import org.junit.After; import org.junit.Before; @@ -188,7 +193,7 @@ public class AppDataUsageTest { ReflectionHelpers.setField(mFragment, "mBackgroundUsage", preference); ReflectionHelpers.setField(mFragment, "mForegroundUsage", preference); ReflectionHelpers.setField(mFragment, "mTotalUsage", preference); - doReturn(RuntimeEnvironment.application).when(mFragment).getContext(); + ReflectionHelpers.setField(mFragment, "mContext", RuntimeEnvironment.application); mFragment.bindData(0 /* position */); @@ -199,7 +204,7 @@ public class AppDataUsageTest { public void bindData_hasAppUsageData_shouldShowCycleSpinnerAndUpdateUsageSummary() { mFragment = spy(new AppDataUsage()); final Context context = RuntimeEnvironment.application; - doReturn(context).when(mFragment).getContext(); + ReflectionHelpers.setField(mFragment, "mContext", context); final long backgroundBytes = 1234L; final long foregroundBytes = 5678L; final List appUsage = new ArrayList<>(); @@ -223,4 +228,53 @@ public class AppDataUsageTest { verify(backgroundPref).setSummary(DataUsageUtils.formatDataUsage(context, backgroundBytes)); verify(foregroundPref).setSummary(DataUsageUtils.formatDataUsage(context, foregroundBytes)); } + + @Test + public void onCreateLoader_categoryApp_shouldQueryDataUsageUsingAppKey() { + mFragment = new AppDataUsage(); + final Context context = RuntimeEnvironment.application; + final int testUid = 123123; + final AppItem appItem = new AppItem(testUid); + appItem.category = AppItem.CATEGORY_APP; + ReflectionHelpers.setField(mFragment, "mContext", context); + ReflectionHelpers.setField(mFragment, "mAppItem", appItem); + ReflectionHelpers.setField(mFragment, "mTemplate", + NetworkTemplate.buildTemplateWifiWildcard()); + final long end = System.currentTimeMillis(); + final long start = end - (DateUtils.WEEK_IN_MILLIS * 4); + + final NetworkCycleDataForUidLoader loader = (NetworkCycleDataForUidLoader) + mFragment.mUidDataCallbacks.onCreateLoader(0, Bundle.EMPTY); + + final List uids = loader.getUids(); + assertThat(uids).hasSize(1); + assertThat(uids.get(0)).isEqualTo(testUid); + } + + @Test + public void onCreateLoader_categoryUser_shouldQueryDataUsageUsingAssociatedUids() { + mFragment = new AppDataUsage(); + final Context context = RuntimeEnvironment.application; + final int testUserId = 11; + final AppItem appItem = new AppItem(testUserId); + appItem.category = AppItem.CATEGORY_USER; + appItem.addUid(123); + appItem.addUid(456); + appItem.addUid(789); + ReflectionHelpers.setField(mFragment, "mContext", context); + ReflectionHelpers.setField(mFragment, "mAppItem", appItem); + ReflectionHelpers.setField(mFragment, "mTemplate", + NetworkTemplate.buildTemplateWifiWildcard()); + final long end = System.currentTimeMillis(); + final long start = end - (DateUtils.WEEK_IN_MILLIS * 4); + + final NetworkCycleDataForUidLoader loader = (NetworkCycleDataForUidLoader) + mFragment.mUidDataCallbacks.onCreateLoader(0, Bundle.EMPTY); + + final List uids = loader.getUids(); + assertThat(uids).hasSize(3); + assertThat(uids.get(0)).isEqualTo(123); + assertThat(uids.get(1)).isEqualTo(456); + assertThat(uids.get(2)).isEqualTo(789); + } } diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java index 8cba1defb35..2d3cb0cc6f6 100644 --- a/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.graphics.drawable.Drawable; +import android.provider.DeviceConfig; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; @@ -32,9 +33,11 @@ import android.widget.TextView; import androidx.preference.PreferenceScreen; import com.android.settings.R; +import com.android.settings.testutils.shadow.ShadowDeviceConfig; import com.android.settingslib.location.RecentLocationAccesses; import com.android.settingslib.widget.LayoutPreference; +import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -43,11 +46,13 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowDeviceConfig.class}) public class RecentLocationAccessPreferenceControllerTest { @Mock private LayoutPreference mLayoutPreference; @@ -76,6 +81,25 @@ public class RecentLocationAccessPreferenceControllerTest { mAppEntitiesHeaderView); } + @After + public void tearDown() { + ShadowDeviceConfig.reset(); + } + + @Test + public void isAvailable_permissionHubNotSet_shouldReturnFalse() { + // We have not yet set the property to show the Permissions Hub. + assertThat(mController.isAvailable()).isEqualTo(false); + } + + @Test + public void isAvailable_permissionHubEnabled_shouldReturnTrue() { + DeviceConfig.setProperty(DeviceConfig.Privacy.NAMESPACE, + DeviceConfig.Privacy.PROPERTY_PERMISSIONS_HUB_ENABLED, "true", true); + + assertThat(mController.isAvailable()).isEqualTo(true); + } + /** Verifies the title text, details text are correct, and the click listener is set. */ @Test @Ignore diff --git a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java index 119ac7db599..b9476304b72 100644 --- a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java @@ -17,6 +17,7 @@ package com.android.settings.privacy; import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE; +import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; import static com.google.common.truth.Truth.assertThat; @@ -28,13 +29,16 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.permission.RuntimePermissionUsageInfo; +import android.provider.DeviceConfig; import androidx.preference.PreferenceScreen; +import com.android.settings.testutils.shadow.ShadowDeviceConfig; import com.android.settingslib.widget.BarChartInfo; import com.android.settingslib.widget.BarChartPreference; import com.android.settingslib.widget.BarViewInfo; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,11 +46,13 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowDeviceConfig.class}) public class PermissionBarChartPreferenceControllerTest { @Mock @@ -65,8 +71,22 @@ public class PermissionBarChartPreferenceControllerTest { .thenReturn((BarChartPreference) mPreference); } + @After + public void tearDown() { + ShadowDeviceConfig.reset(); + } + @Test - public void getAvailabilityStatus_shouldReturnAvailableUnsearchable() { + public void getAvailabilityStatus_permissionHubNotSet_shouldReturnUnsupported() { + // We have not yet set the property to show the Permissions Hub. + assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); + } + + @Test + public void getAvailabilityStatus_permissionHubEnabled_shouldReturnAvailableUnsearchable() { + DeviceConfig.setProperty(DeviceConfig.Privacy.NAMESPACE, + DeviceConfig.Privacy.PROPERTY_PERMISSIONS_HUB_ENABLED, "true", true); + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE); } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceConfig.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceConfig.java index d46e7556793..dfd09887e54 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceConfig.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceConfig.java @@ -19,21 +19,32 @@ package com.android.settings.testutils.shadow; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; +import org.robolectric.annotation.Resetter; + +import java.util.HashMap; +import java.util.Map; @Implements(android.provider.DeviceConfig.class) public class ShadowDeviceConfig { - private static String configValue; + private static Map sPropertyMaps = new HashMap<>(); + + @Resetter + public static void reset() { + sPropertyMaps.clear(); + } @Implementation - protected static boolean setProperty( - String namespace, String name, String value, boolean makeDefault) { - configValue = value; + public static boolean setProperty( + String namespace, String name, String value, boolean makeDefault) { + sPropertyMaps.put(name, value); return true; } @Implementation - protected static String getProperty(String ns, String key) { return configValue; } + public static String getProperty(String namespace, String name) { + return sPropertyMaps.get(name); + } } diff --git a/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java b/tests/robotests/src/com/android/settings/widget/AdaptiveHomepageIconTest.java similarity index 83% rename from tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java rename to tests/robotests/src/com/android/settings/widget/AdaptiveHomepageIconTest.java index 21ba907e621..32690a3d6aa 100644 --- a/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java +++ b/tests/robotests/src/com/android/settings/widget/AdaptiveHomepageIconTest.java @@ -37,9 +37,9 @@ import android.graphics.drawable.ShapeDrawable; import android.os.Bundle; import com.android.settings.R; +import com.android.settings.homepage.AdaptiveIconShapeDrawable; import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.Tile; -import com.android.settingslib.testutils.DrawableTestHelper; import org.junit.Before; import org.junit.Test; @@ -48,7 +48,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) -public class RoundedHomepageIconTest { +public class AdaptiveHomepageIconTest { private Context mContext; private ActivityInfo mActivityInfo; @@ -64,18 +64,17 @@ public class RoundedHomepageIconTest { @Test public void createIcon_shouldSetBackgroundAndInset() { - final RoundedHomepageIcon icon = - new RoundedHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); + final AdaptiveHomepageIcon icon = + new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); assertThat(icon.getNumberOfLayers()).isEqualTo(2); - DrawableTestHelper.assertDrawableResId(icon.getDrawable(0), - R.drawable.ic_homepage_generic_background); + assertThat(icon.getDrawable(0)).isInstanceOf(AdaptiveIconShapeDrawable.class); } @Test public void setBackgroundColor_shouldUpdateColorFilter() { - final RoundedHomepageIcon icon = - spy(new RoundedHomepageIcon(mContext, new ColorDrawable(Color.BLACK))); + final AdaptiveHomepageIcon icon = + spy(new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK))); final ShapeDrawable background = mock(ShapeDrawable.class); when(icon.getDrawable(0)).thenReturn(background); @@ -90,8 +89,8 @@ public class RoundedHomepageIconTest { mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000); doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings)) .when(tile).getIcon(mContext); - final RoundedHomepageIcon icon = - new RoundedHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); + final AdaptiveHomepageIcon icon = + new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); icon.setBackgroundColor(mContext, tile); assertThat(icon.mBackgroundColor).isEqualTo(0xff0000); @@ -105,8 +104,8 @@ public class RoundedHomepageIconTest { doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings)) .when(tile).getIcon(mContext); - final RoundedHomepageIcon icon = - new RoundedHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); + final AdaptiveHomepageIcon icon = + new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); icon.setBackgroundColor(mContext, tile); assertThat(icon.mBackgroundColor)