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.NetworkTemplate;
21 import android.telephony.SubscriptionInfo;
22 import android.telephony.SubscriptionManager;
23 import android.telephony.SubscriptionPlan;
24 import android.telephony.TelephonyManager;
25 import android.text.BidiFormatter;
26 import android.text.format.Formatter;
27 
28 import androidx.annotation.Nullable;
29 import androidx.annotation.VisibleForTesting;
30 
31 import com.android.internal.util.CollectionUtils;
32 
33 import java.util.List;
34 
35 /** Provides helpful utilities related to data usage. */
36 public final class DataUsageUtils {
37 
38     @VisibleForTesting
39     static final long PETA = 1000000000000000L;
40 
DataUsageUtils()41     private DataUsageUtils() {
42     }
43 
44     /**
45      * Returns the mobile network template given the subscription id.
46      */
getMobileNetworkTemplate(TelephonyManager telephonyManager, int subscriptionId)47     public static NetworkTemplate getMobileNetworkTemplate(TelephonyManager telephonyManager,
48             int subscriptionId) {
49         NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
50                 telephonyManager.getSubscriberId(subscriptionId));
51         return NetworkTemplate.normalize(mobileAll, telephonyManager.getMergedSubscriberIds());
52     }
53 
54     /**
55      * Returns the default subscription if available else returns
56      * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
57      */
getDefaultSubscriptionId(SubscriptionManager subscriptionManager)58     public static int getDefaultSubscriptionId(SubscriptionManager subscriptionManager) {
59         if (subscriptionManager == null) {
60             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
61         }
62         SubscriptionInfo subscriptionInfo = subscriptionManager.getDefaultDataSubscriptionInfo();
63         if (subscriptionInfo == null) {
64             List<SubscriptionInfo> list = subscriptionManager.getAllSubscriptionInfoList();
65             if (list.size() == 0) {
66                 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
67             }
68             subscriptionInfo = list.get(0);
69         }
70         return subscriptionInfo.getSubscriptionId();
71     }
72 
73     /**
74      * Format byte value to readable string using IEC units.
75      */
bytesToIecUnits(Context context, long byteValue)76     public static CharSequence bytesToIecUnits(Context context, long byteValue) {
77         Formatter.BytesResult res = Formatter.formatBytes(context.getResources(), byteValue,
78                 Formatter.FLAG_IEC_UNITS);
79         return BidiFormatter.getInstance().unicodeWrap(context.getString(
80                 com.android.internal.R.string.fileSizeSuffix, res.value, res.units));
81     }
82 
83     /**
84      * Returns the primary subscription plan. Returns {@code null} if {@link SubscriptionPlan}
85      * doesn't exist for a given subscriptionId or if the first {@link SubscriptionPlan} has
86      * invalid properties.
87      */
88     @Nullable
getPrimaryPlan(SubscriptionManager subManager, int subscriptionId)89     public static SubscriptionPlan getPrimaryPlan(SubscriptionManager subManager,
90             int subscriptionId) {
91         List<SubscriptionPlan> plans = subManager.getSubscriptionPlans(subscriptionId);
92         if (CollectionUtils.isEmpty(plans)) {
93             return null;
94         }
95         // First plan in the list is the primary plan
96         SubscriptionPlan plan = plans.get(0);
97         return plan.getDataLimitBytes() > 0
98                 && saneSize(plan.getDataUsageBytes())
99                 && plan.getCycleRule() != null ? plan : null;
100     }
101 
saneSize(long value)102     private static boolean saneSize(long value) {
103         return value >= 0L && value < PETA;
104     }
105 }
106