Separate OTA data usage from SYSTEM_UID.

Prior to this CL, Process.OTA_UPDATE_UID was included with SYSTEM_UID
for the purposes of per-app data usage in the DataUsageList. With this
change, it is now separated into its own category.

This change also deletes the duplicate ic_system_update* icons and
moves the one implementation into SettingsLib.

Fixes: 70640191
Test: manually verified locally that there is an item in the list
with the proper title. Required setting up a custom OTA for my
test device.

Change-Id: Iecc45648f68a12c9f8e2370577ab017863e7fcb2
This commit is contained in:
Andrew Sapperstein
2018-12-14 13:25:48 -08:00
committed by Doris Ling
parent 7d257171dc
commit 5efb70ac18
7 changed files with 98 additions and 74 deletions

View File

@@ -1,25 +0,0 @@
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM16,12.5l-4,4l-4,-4l1.41,-1.41L11,12.67V8.5V8h2v0.5v4.17l1.59,-1.59L16,12.5z"/>
</vector>

View File

@@ -1,25 +0,0 @@
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM16,12.5l-4,4l-4,-4l1.41,-1.41L11,12.67V8.5V8h2v0.5v4.17l1.59,-1.59L16,12.5z"/>
</vector>

View File

@@ -66,7 +66,7 @@
<com.android.settings.deviceinfo.StorageItemPreference <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_system" android:key="pref_system"
android:title="@string/storage_detail_system" android:title="@string/storage_detail_system"
android:icon="@drawable/ic_system_update_vd_theme_24" android:icon="@drawable/ic_system_update"
android:order="100" /> android:order="100" />
<PreferenceCategory <PreferenceCategory
android:key="pref_secondary_users" android:key="pref_secondary_users"

View File

@@ -84,8 +84,10 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
private PreferenceCategory mAppList; private PreferenceCategory mAppList;
private Drawable mIcon; private Drawable mIcon;
private CharSequence mLabel; @VisibleForTesting
private String mPackageName; CharSequence mLabel;
@VisibleForTesting
String mPackageName;
private CycleAdapter mCycleAdapter; private CycleAdapter mCycleAdapter;
private List<NetworkCycleDataForUid> mUsageData; private List<NetworkCycleDataForUid> mUsageData;
@@ -133,29 +135,32 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
mForegroundUsage = findPreference(KEY_FOREGROUND_USAGE); mForegroundUsage = findPreference(KEY_FOREGROUND_USAGE);
mBackgroundUsage = findPreference(KEY_BACKGROUND_USAGE); mBackgroundUsage = findPreference(KEY_BACKGROUND_USAGE);
mCycle = (SpinnerPreference) findPreference(KEY_CYCLE); mCycle = findPreference(KEY_CYCLE);
mCycleAdapter = new CycleAdapter(mContext, mCycle, mCycleListener); mCycleAdapter = new CycleAdapter(mContext, mCycle, mCycleListener);
final UidDetailProvider uidDetailProvider = getUidDetailProvider();
if (mAppItem.key > 0) { if (mAppItem.key > 0) {
if (mPackages.size() != 0) {
try {
ApplicationInfo info = mPackageManager.getApplicationInfoAsUser(
mPackages.valueAt(0), 0, UserHandle.getUserId(mAppItem.key));
mIcon = IconDrawableFactory.newInstance(getActivity()).getBadgedIcon(info);
mLabel = info.loadLabel(mPackageManager);
mPackageName = info.packageName;
} catch (PackageManager.NameNotFoundException e) {
}
}
if (!UserHandle.isApp(mAppItem.key)) { if (!UserHandle.isApp(mAppItem.key)) {
final UidDetail uidDetail = uidDetailProvider.getUidDetail(mAppItem.key, true);
mIcon = uidDetail.icon;
mLabel = uidDetail.label;
removePreference(KEY_UNRESTRICTED_DATA); removePreference(KEY_UNRESTRICTED_DATA);
removePreference(KEY_RESTRICT_BACKGROUND); removePreference(KEY_RESTRICT_BACKGROUND);
} else { } else {
mRestrictBackground = (RestrictedSwitchPreference) findPreference( if (mPackages.size() != 0) {
KEY_RESTRICT_BACKGROUND); try {
final ApplicationInfo info = mPackageManager.getApplicationInfoAsUser(
mPackages.valueAt(0), 0, UserHandle.getUserId(mAppItem.key));
mIcon = IconDrawableFactory.newInstance(getActivity()).getBadgedIcon(info);
mLabel = info.loadLabel(mPackageManager);
mPackageName = info.packageName;
} catch (PackageManager.NameNotFoundException e) {
}
}
mRestrictBackground = findPreference(KEY_RESTRICT_BACKGROUND);
mRestrictBackground.setOnPreferenceChangeListener(this); mRestrictBackground.setOnPreferenceChangeListener(this);
mUnrestrictedData = (RestrictedSwitchPreference) findPreference( mUnrestrictedData = findPreference(KEY_UNRESTRICTED_DATA);
KEY_UNRESTRICTED_DATA);
mUnrestrictedData.setOnPreferenceChangeListener(this); mUnrestrictedData.setOnPreferenceChangeListener(this);
} }
mDataSaverBackend = new DataSaverBackend(mContext); mDataSaverBackend = new DataSaverBackend(mContext);
@@ -164,7 +169,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
mAppSettingsIntent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE); mAppSettingsIntent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE);
mAppSettingsIntent.addCategory(Intent.CATEGORY_DEFAULT); mAppSettingsIntent.addCategory(Intent.CATEGORY_DEFAULT);
PackageManager pm = getPackageManager(); final PackageManager pm = getPackageManager();
boolean matchFound = false; boolean matchFound = false;
for (String packageName : mPackages) { for (String packageName : mPackages) {
mAppSettingsIntent.setPackage(packageName); mAppSettingsIntent.setPackage(packageName);
@@ -179,7 +184,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
} }
if (mPackages.size() > 1) { if (mPackages.size() > 1) {
mAppList = (PreferenceCategory) findPreference(KEY_APP_LIST); mAppList = findPreference(KEY_APP_LIST);
LoaderManager.getInstance(this).restartLoader(LOADER_APP_PREF, Bundle.EMPTY, LoaderManager.getInstance(this).restartLoader(LOADER_APP_PREF, Bundle.EMPTY,
mAppPrefCallbacks); mAppPrefCallbacks);
} else { } else {
@@ -187,7 +192,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
} }
} else { } else {
final Context context = getActivity(); final Context context = getActivity();
UidDetail uidDetail = new UidDetailProvider(context).getUidDetail(mAppItem.key, true); final UidDetail uidDetail = uidDetailProvider.getUidDetail(mAppItem.key, true);
mIcon = uidDetail.icon; mIcon = uidDetail.icon;
mLabel = uidDetail.label; mLabel = uidDetail.label;
mPackageName = context.getPackageName(); mPackageName = context.getPackageName();
@@ -257,6 +262,11 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
updatePrefs(getAppRestrictBackground(), getUnrestrictData()); updatePrefs(getAppRestrictBackground(), getUnrestrictData());
} }
@VisibleForTesting
UidDetailProvider getUidDetailProvider() {
return new UidDetailProvider(mContext);
}
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) { private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfMeteredDataRestricted( final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfMeteredDataRestricted(
mContext, mPackageName, UserHandle.getUserId(mAppItem.key)); mContext, mPackageName, UserHandle.getUserId(mAppItem.key));
@@ -276,7 +286,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
} }
private void addUid(int uid) { private void addUid(int uid) {
String[] packages = getPackageManager().getPackagesForUid(uid); String[] packages = mPackageManager.getPackagesForUid(uid);
if (packages != null) { if (packages != null) {
for (int i = 0; i < packages.length; i++) { for (int i = 0; i < packages.length; i++) {
mPackages.add(packages[i]); mPackages.add(packages[i]);

View File

@@ -33,6 +33,7 @@ import android.net.ConnectivityManager;
import android.net.NetworkPolicy; import android.net.NetworkPolicy;
import android.net.NetworkTemplate; import android.net.NetworkTemplate;
import android.os.Bundle; import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
@@ -362,7 +363,8 @@ public class DataUsageList extends DataUsageBaseFragment {
category = AppItem.CATEGORY_USER; category = AppItem.CATEGORY_USER;
} }
} }
} else if (uid == UID_REMOVED || uid == UID_TETHERING) { } else if (uid == UID_REMOVED || uid == UID_TETHERING
|| uid == Process.OTA_UPDATE_UID) {
collapseKey = uid; collapseKey = uid;
category = AppItem.CATEGORY_APP; category = AppItem.CATEGORY_APP;
} else { } else {

View File

@@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
@@ -31,10 +32,13 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.NetworkPolicyManager; import android.net.NetworkPolicyManager;
import android.net.NetworkTemplate; import android.net.NetworkTemplate;
import android.os.Bundle; import android.os.Bundle;
import android.os.Process;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.ArraySet; import android.util.ArraySet;
@@ -56,6 +60,8 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.net.NetworkCycleDataForUid; import com.android.settingslib.net.NetworkCycleDataForUid;
import com.android.settingslib.net.NetworkCycleDataForUidLoader; import com.android.settingslib.net.NetworkCycleDataForUidLoader;
import com.android.settingslib.net.UidDetail;
import com.android.settingslib.net.UidDetailProvider;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -95,6 +101,62 @@ public class AppDataUsageTest {
ShadowEntityHeaderController.reset(); ShadowEntityHeaderController.reset();
} }
@Test
public void onCreate_appUid_shouldGetAppLabelFromAppInfo() throws NameNotFoundException {
mFragment = spy(new AppDataUsage());
final FragmentActivity activity = spy(Robolectric.setupActivity(FragmentActivity.class));
doReturn(mPackageManager).when(activity).getPackageManager();
doReturn(activity).when(mFragment).getActivity();
doReturn(RuntimeEnvironment.application).when(mFragment).getContext();
ReflectionHelpers.setField(mFragment, "mDashboardFeatureProvider",
FakeFeatureFactory.setupForTest().dashboardFeatureProvider);
final String packageName = "testPackage";
final int uid = (Process.FIRST_APPLICATION_UID + Process.LAST_APPLICATION_UID) / 2;
doReturn(new String[] {packageName}).when(mPackageManager).getPackagesForUid(uid);
final String label = "testLabel";
final AppItem appItem = new AppItem(uid);
appItem.uids.put(uid, true);
final ApplicationInfo info = spy(new ApplicationInfo());
doReturn(label).when(info).loadLabel(mPackageManager);
when(mPackageManager.getApplicationInfoAsUser(
eq(packageName), anyInt() /* flags */, anyInt() /* userId */)).thenReturn(info);
final Bundle args = new Bundle();
args.putParcelable(AppDataUsage.ARG_APP_ITEM, appItem);
args.putInt(AppInfoBase.ARG_PACKAGE_UID, uid);
mFragment.setArguments(args);
mFragment.onCreate(Bundle.EMPTY);
assertThat(mFragment.mLabel).isEqualTo(label);
}
@Test
public void onCreate_notAppUid_shouldGetAppLabelFromUidDetailProvider() {
mFragment = spy(new AppDataUsage());
ReflectionHelpers.setField(mFragment, "mDashboardFeatureProvider",
FakeFeatureFactory.setupForTest().dashboardFeatureProvider);
doReturn(Robolectric.setupActivity(FragmentActivity.class)).when(mFragment).getActivity();
doReturn(RuntimeEnvironment.application).when(mFragment).getContext();
final UidDetailProvider uidDetailProvider = mock(UidDetailProvider.class);
doReturn(uidDetailProvider).when(mFragment).getUidDetailProvider();
final String label = "testLabel";
final int uid = Process.SYSTEM_UID;
final UidDetail uidDetail = new UidDetail();
uidDetail.label = label;
when(uidDetailProvider.getUidDetail(eq(uid), anyBoolean() /* blocking */)).
thenReturn(uidDetail);
final AppItem appItem = new AppItem(uid);
appItem.uids.put(uid, true);
final Bundle args = new Bundle();
args.putParcelable(AppDataUsage.ARG_APP_ITEM, appItem);
args.putInt(AppInfoBase.ARG_PACKAGE_UID, uid);
mFragment.setArguments(args);
mFragment.onCreate(Bundle.EMPTY);
assertThat(mFragment.mLabel).isEqualTo(label);
}
@Test @Test
public void bindAppHeader_allWorkApps_shouldNotShowAppInfoLink() { public void bindAppHeader_allWorkApps_shouldNotShowAppInfoLink() {
ShadowEntityHeaderController.setUseMock(mHeaderController); ShadowEntityHeaderController.setUseMock(mHeaderController);

View File

@@ -341,7 +341,7 @@ public class StorageItemPreferenceControllerTest {
final StorageItemPreference apps = spy(new StorageItemPreference(mContext)); final StorageItemPreference apps = spy(new StorageItemPreference(mContext));
apps.setIcon(R.drawable.ic_storage_apps); apps.setIcon(R.drawable.ic_storage_apps);
final StorageItemPreference system = spy(new StorageItemPreference(mContext)); final StorageItemPreference system = spy(new StorageItemPreference(mContext));
system.setIcon(R.drawable.ic_system_update_vd_theme_24); system.setIcon(R.drawable.ic_system_update);
final StorageItemPreference files = spy(new StorageItemPreference(mContext)); final StorageItemPreference files = spy(new StorageItemPreference(mContext));
files.setIcon(R.drawable.ic_folder_vd_theme_24); files.setIcon(R.drawable.ic_folder_vd_theme_24);
final PreferenceScreen screen = mock(PreferenceScreen.class); final PreferenceScreen screen = mock(PreferenceScreen.class);