1 /*
2  * Copyright (C) 2019 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.NetworkPolicy;
21 import android.net.NetworkPolicyManager;
22 import android.net.NetworkTemplate;
23 import android.os.Bundle;
24 import android.telephony.SubscriptionManager;
25 import android.telephony.TelephonyManager;
26 import android.util.Pair;
27 
28 import androidx.annotation.VisibleForTesting;
29 import androidx.annotation.XmlRes;
30 import androidx.loader.app.LoaderManager;
31 
32 import com.android.car.settings.R;
33 import com.android.car.settings.common.Logger;
34 import com.android.car.settings.common.SettingsFragment;
35 import com.android.settingslib.net.DataUsageController;
36 import com.android.settingslib.net.NetworkCycleChartData;
37 
38 import java.time.ZonedDateTime;
39 import java.util.Iterator;
40 import java.util.Map;
41 
42 /**
43  * Screen to display list of applications using the data.
44  */
45 public class AppDataUsageFragment extends SettingsFragment implements
46         DataUsageCyclePreferenceController.DataCyclePickedListener<NetworkCycleChartData> {
47 
48     private static final Logger LOG = new Logger(AppDataUsageFragment.class);
49 
50     private static final String ARG_NETWORK_SUB_ID = "network_sub_id";
51     /** Value to represent that the subscription id hasn't been computed yet. */
52     private static final int SUB_ID_NULL = Integer.MIN_VALUE;
53 
54     private AppsNetworkStatsManager mAppsNetworkStatsManager;
55     private DataUsageCycleManager mDataUsageCycleManager;
56     private NetworkTemplate mNetworkTemplate;
57     private DataUsageController mDataUsageController;
58 
59     private Bundle mBundle;
60     private LoaderManager mLoaderManager;
61     private AppDataUsageTotalPreferenceController mAppDataUsageTotalPreferenceController;
62 
63     /**
64      * Creates a new instance of the {@link AppDataUsageFragment}, which shows settings related to
65      * the given {@code subId}.
66      */
newInstance(int subId)67     public static AppDataUsageFragment newInstance(int subId) {
68         AppDataUsageFragment fragment = new AppDataUsageFragment();
69         Bundle args = new Bundle();
70         args.putInt(ARG_NETWORK_SUB_ID, subId);
71         fragment.setArguments(args);
72         return fragment;
73     }
74 
75     @Override
76     @XmlRes
getPreferenceScreenResId()77     protected int getPreferenceScreenResId() {
78         return R.xml.app_data_usage_fragment;
79     }
80 
81     @Override
onAttach(Context context)82     public void onAttach(Context context) {
83         super.onAttach(context);
84 
85         TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
86         int subId = getArguments() != null
87                 ? getArguments().getInt(ARG_NETWORK_SUB_ID, SUB_ID_NULL) : SUB_ID_NULL;
88         if (subId == SUB_ID_NULL) {
89             LOG.d("Cannot get the subscription id from arguments. Switching to default "
90                     + "subscription Id: " + subId);
91             SubscriptionManager subscriptionManager = context.getSystemService(
92                     SubscriptionManager.class);
93             subId = DataUsageUtils.getDefaultSubscriptionId(subscriptionManager);
94         }
95         mNetworkTemplate = DataUsageUtils.getMobileNetworkTemplate(telephonyManager, subId);
96         mDataUsageController = new DataUsageController(context);
97         mAppsNetworkStatsManager = new AppsNetworkStatsManager(getContext());
98         mAppsNetworkStatsManager.registerListener(
99                 use(AppDataUsagePreferenceController.class, R.string.pk_app_data_usage_detail));
100         mDataUsageCycleManager = new DataUsageCycleManager(getContext(), mNetworkTemplate);
101         mDataUsageCycleManager.registerListener(use(DataUsageCyclePreferenceController.class,
102                 R.string.pk_data_usage_usage_history));
103         use(DataUsageCyclePreferenceController.class,
104                 R.string.pk_data_usage_usage_history)
105                 .setDataCyclePickedListener(this)
106                 .setDataUsageInfo(mDataUsageController.getDataUsageInfo(mNetworkTemplate));
107 
108         long usage = mDataUsageController.getDataUsageInfo(mNetworkTemplate).usageLevel;
109         mAppDataUsageTotalPreferenceController =
110                 use(AppDataUsageTotalPreferenceController.class, R.string.pk_data_usage_all_apps);
111         mAppDataUsageTotalPreferenceController.setDataUsage(usage);
112 
113         use(AppDataUsagePreferenceController.class, R.string.pk_app_data_usage_detail)
114                 .setNetworkTemplate(mNetworkTemplate);
115     }
116 
117     @Override
onCreate(Bundle savedInstanceState)118     public void onCreate(Bundle savedInstanceState) {
119         super.onCreate(savedInstanceState);
120         mBundle = getBundleForNetworkStats();
121 
122         mLoaderManager = LoaderManager.getInstance(this);
123         mAppsNetworkStatsManager.startLoading(mLoaderManager, mBundle);
124         mDataUsageCycleManager.startLoading(mLoaderManager);
125     }
126 
getBundleForNetworkStats()127     private Bundle getBundleForNetworkStats() {
128         long start = mDataUsageController.getDataUsageInfo(mNetworkTemplate).cycleStart;
129         long end = mDataUsageController.getDataUsageInfo(mNetworkTemplate).cycleEnd;
130 
131         return SummaryForAllUidLoader.buildArgs(mNetworkTemplate, start, end);
132     }
133 
134     @VisibleForTesting(otherwise = VisibleForTesting.NONE)
getBundle()135     Bundle getBundle() {
136         return mBundle;
137     }
138 
139     @VisibleForTesting
getCycleIterator(NetworkPolicy policy)140     Iterator<Pair<ZonedDateTime, ZonedDateTime>> getCycleIterator(NetworkPolicy policy) {
141         return NetworkPolicyManager.cycleIterator(policy);
142     }
143 
144     @Override
onDataCyclePicked(String cycle, Map<CharSequence, NetworkCycleChartData> usages)145     public void onDataCyclePicked(String cycle, Map<CharSequence, NetworkCycleChartData> usages) {
146         mAppDataUsageTotalPreferenceController.setDataUsage(usages.get(cycle).getTotalUsage());
147 
148         mBundle = SummaryForAllUidLoader.buildArgs(
149                 mNetworkTemplate,
150                 usages.get(cycle).getStartTime(),
151                 usages.get(cycle).getEndTime());
152         mAppsNetworkStatsManager.startLoading(mLoaderManager, mBundle);
153     }
154 }
155