1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.settings.datausage; 18 19 import android.content.Context; 20 import android.net.NetworkPolicyManager; 21 import android.net.NetworkTemplate; 22 import android.os.Bundle; 23 import android.telephony.SubscriptionManager; 24 import android.telephony.TelephonyManager; 25 26 import androidx.annotation.XmlRes; 27 import androidx.loader.app.LoaderManager; 28 29 import com.android.car.settings.R; 30 import com.android.car.settings.common.Logger; 31 import com.android.car.settings.common.SettingsFragment; 32 import com.android.car.settings.common.UpdateSummaryPreferenceController; 33 import com.android.settingslib.AppItem; 34 import com.android.settingslib.net.DataUsageController; 35 import com.android.settingslib.net.NetworkCycleDataForUid; 36 import com.android.settingslib.net.UidDetail; 37 import com.android.settingslib.net.UidDetailProvider; 38 39 import java.util.Map; 40 41 /** 42 * Screen to display detailed data usage information for a specific app. 43 */ 44 public class AppSpecificDataUsageFragment extends SettingsFragment implements 45 AppSpecificDataUsageCyclePreferenceController.DataCyclePickedListener 46 <NetworkCycleDataForUid> { 47 private static final Logger LOG = new Logger(AppSpecificDataUsageFragment.class); 48 49 private static final String EXTRA_PACKAGE_NAME = "extra_app_item_key"; 50 51 private AppSpecificDataUsageManager mAppSpecificDataUsageManager; 52 53 /** Creates an instance of this fragment, passing packageName as an argument. */ getInstance(AppItem appItem, NetworkTemplate networkTemplate)54 public static AppSpecificDataUsageFragment getInstance(AppItem appItem, 55 NetworkTemplate networkTemplate) { 56 AppSpecificDataUsageFragment 57 appSpecificDataUsageFragment = new AppSpecificDataUsageFragment(); 58 Bundle bundle = new Bundle(); 59 bundle.putObject(EXTRA_PACKAGE_NAME, appItem); 60 bundle.putParcelable(NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE, networkTemplate); 61 appSpecificDataUsageFragment.setArguments(bundle); 62 return appSpecificDataUsageFragment; 63 } 64 65 @Override 66 @XmlRes getPreferenceScreenResId()67 protected int getPreferenceScreenResId() { 68 return R.xml.app_specific_data_usage_fragment; 69 } 70 71 @Override onAttach(Context context)72 public void onAttach(Context context) { 73 super.onAttach(context); 74 AppItem appItem = (AppItem) getArguments().get(EXTRA_PACKAGE_NAME); 75 76 NetworkTemplate networkTemplate = getArguments().getParcelable( 77 NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE); 78 if (networkTemplate == null) { 79 TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class); 80 SubscriptionManager subscriptionManager = 81 context.getSystemService(SubscriptionManager.class); 82 networkTemplate = DataUsageUtils.getMobileNetworkTemplate(telephonyManager, 83 DataUsageUtils.getDefaultSubscriptionId(subscriptionManager)); 84 } 85 86 mAppSpecificDataUsageManager = new AppSpecificDataUsageManager(context, networkTemplate, 87 appItem.key); 88 mAppSpecificDataUsageManager.registerListener( 89 use(AppSpecificDataUsageCyclePreferenceController.class, 90 R.string.pk_app_specific_usage_cycle)); 91 92 UidDetailProvider uidDetailProvider = new UidDetailProvider(context); 93 UidDetail uidDetail = uidDetailProvider.getUidDetail(appItem.key, true /* blocking */); 94 use(AppSpecificDataUsageHeaderPreferenceController.class, 95 R.string.pk_app_specific_usage_title) 96 .setTitle(uidDetail.label.toString()) 97 .setIcon(uidDetail.icon); 98 99 DataUsageController dataUsageController = new DataUsageController(context); 100 use(AppSpecificDataUsageCyclePreferenceController.class, 101 R.string.pk_app_specific_usage_cycle) 102 .setDataCyclePickedListener(this) 103 .setDataUsageInfo(dataUsageController.getDataUsageInfo(networkTemplate)); 104 } 105 106 @Override onCreate(Bundle savedInstanceState)107 public void onCreate(Bundle savedInstanceState) { 108 super.onCreate(savedInstanceState); 109 110 LoaderManager loaderManager = LoaderManager.getInstance(this); 111 mAppSpecificDataUsageManager.startLoading(loaderManager); 112 } 113 114 @Override onDataCyclePicked(String cycle, Map<CharSequence, NetworkCycleDataForUid> usages)115 public void onDataCyclePicked(String cycle, Map<CharSequence, NetworkCycleDataForUid> usages) { 116 // TODO: (b/203824535) Default to generic "Calculating..." string after string freeze when 117 // not yet loaded. 118 NetworkCycleDataForUid cycleData = usages.get(cycle); 119 use(UpdateSummaryPreferenceController.class, 120 R.string.pk_app_specific_usage_total) 121 .setSummary(DataUsageUtils.bytesToIecUnits(getContext(), cycleData.getTotalUsage()) 122 .toString()); 123 use(UpdateSummaryPreferenceController.class, 124 R.string.pk_app_specific_usage_foreground) 125 .setSummary(DataUsageUtils.bytesToIecUnits(getContext(), 126 cycleData.getForegroudUsage()).toString()); 127 use(UpdateSummaryPreferenceController.class, 128 R.string.pk_app_specific_usage_background) 129 .setSummary(DataUsageUtils.bytesToIecUnits(getContext(), 130 cycleData.getBackgroudUsage()).toString()); 131 } 132 } 133