15d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey/*
25d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * Copyright (C) 2012 The Android Open Source Project
35d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey *
45d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
55d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * you may not use this file except in compliance with the License.
65d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * You may obtain a copy of the License at
75d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey *
85d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
95d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey *
105d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * Unless required by applicable law or agreed to in writing, software
115d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
125d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * See the License for the specific language governing permissions and
145d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * limitations under the License.
155d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey */
165d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
175d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkeypackage android.support.v4.net;
185d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
1936dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikasimport static android.net.ConnectivityManager.TYPE_BLUETOOTH;
2036dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikasimport static android.net.ConnectivityManager.TYPE_ETHERNET;
218e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.net.ConnectivityManager.TYPE_MOBILE;
228e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
238e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
248e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
258e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
268e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.net.ConnectivityManager.TYPE_WIFI;
278e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.net.ConnectivityManager.TYPE_WIMAX;
288e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
298e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
30d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkeyimport android.content.Intent;
315d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkeyimport android.net.ConnectivityManager;
325d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkeyimport android.net.NetworkInfo;
335d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkeyimport android.os.Build;
34ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viveretteimport android.support.annotation.IntDef;
3536dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikasimport android.support.annotation.RequiresApi;
36c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo;
37ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette
38ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viveretteimport java.lang.annotation.Retention;
39ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viveretteimport java.lang.annotation.RetentionPolicy;
405d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
415d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey/**
425d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * Helper for accessing features in {@link ConnectivityManager} introduced after
435d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey * API level 16 in a backwards compatible fashion.
445d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey */
45c5847d13e40f5d52459f5c0dab32dc08f1a9a683Chris Banespublic final class ConnectivityManagerCompat {
465d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
475d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey    interface ConnectivityManagerCompatImpl {
485d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        boolean isActiveNetworkMetered(ConnectivityManager cm);
49ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette
50ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        @RestrictBackgroundStatus
51ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        int getRestrictBackgroundStatus(ConnectivityManager cm);
52ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    }
53ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette
54ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    /** @hide */
558e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas    @RestrictTo(LIBRARY_GROUP)
56ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    @Retention(RetentionPolicy.SOURCE)
5736dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas    @IntDef(value = {
58ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette            RESTRICT_BACKGROUND_STATUS_DISABLED,
59ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette            RESTRICT_BACKGROUND_STATUS_WHITELISTED,
60ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette            RESTRICT_BACKGROUND_STATUS_ENABLED,
61ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    })
62ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    public @interface RestrictBackgroundStatus {
635d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey    }
645d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
65ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    /**
66ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * Device is not restricting metered network activity while application is running on
67ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * background.
68ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     */
69ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1;
70ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette
71ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    /**
72ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * Device is restricting metered network activity while application is running on background,
73ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * but application is allowed to bypass it.
74ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * <p>
75ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * In this state, application should take action to mitigate metered network access.
76ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * For example, a music streaming application should switch to a low-bandwidth bitrate.
77ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     */
78ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2;
79ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette
80ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    /**
81ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * Device is restricting metered network activity while application is running on background.
82ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * <p>
83ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * In this state, application should not try to use the network while running on background,
84ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * because it would be denied.
85ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     */
86ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3;
87ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette
8836dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas    static class ConnectivityManagerCompatBaseImpl implements ConnectivityManagerCompatImpl {
8936dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas        @SuppressWarnings("deprecation")
905d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        @Override
915d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        public boolean isActiveNetworkMetered(ConnectivityManager cm) {
925d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey            final NetworkInfo info = cm.getActiveNetworkInfo();
935d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey            if (info == null) {
945d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey                // err on side of caution
955d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey                return true;
965d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey            }
975d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
985d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey            final int type = info.getType();
995d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey            switch (type) {
1005d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey                case TYPE_MOBILE:
101f185f104c4786740765e549d535f9ba1052f96ccKirill Grouchnikov                case TYPE_MOBILE_DUN:
102f185f104c4786740765e549d535f9ba1052f96ccKirill Grouchnikov                case TYPE_MOBILE_HIPRI:
103f185f104c4786740765e549d535f9ba1052f96ccKirill Grouchnikov                case TYPE_MOBILE_MMS:
104f185f104c4786740765e549d535f9ba1052f96ccKirill Grouchnikov                case TYPE_MOBILE_SUPL:
105f185f104c4786740765e549d535f9ba1052f96ccKirill Grouchnikov                case TYPE_WIMAX:
1065d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey                    return true;
1075d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey                case TYPE_WIFI:
10836dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas                case TYPE_BLUETOOTH:
10936dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas                case TYPE_ETHERNET:
1105d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey                    return false;
1115d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey                default:
1125d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey                    // err on side of caution
1135d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey                    return true;
1145d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey            }
1155d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        }
116ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette
117ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        @Override
118ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        public int getRestrictBackgroundStatus(ConnectivityManager cm) {
119ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette            return RESTRICT_BACKGROUND_STATUS_ENABLED;
120ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        }
1215d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey    }
1225d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
12336dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas    @RequiresApi(16)
12436dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas    static class ConnectivityManagerCompatApi16Impl extends ConnectivityManagerCompatBaseImpl {
1255d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        @Override
1265d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        public boolean isActiveNetworkMetered(ConnectivityManager cm) {
12736dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas            return cm.isActiveNetworkMetered();
1285d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        }
1295d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey    }
1305d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
13136dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas    @RequiresApi(24)
13236dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas    static class ConnectivityManagerCompatApi24Impl extends ConnectivityManagerCompatApi16Impl {
133ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        @Override
134ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        public int getRestrictBackgroundStatus(ConnectivityManager cm) {
135ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette            //noinspection ResourceType
13636dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas            return cm.getRestrictBackgroundStatus();
137ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        }
138ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    }
139ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette
1405d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey    private static final ConnectivityManagerCompatImpl IMPL;
1415d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
1425d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey    static {
143ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        if (Build.VERSION.SDK_INT >= 24) {
14436dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas            IMPL = new ConnectivityManagerCompatApi24Impl();
145ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        } else if (Build.VERSION.SDK_INT >= 16) {
14636dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas            IMPL = new ConnectivityManagerCompatApi16Impl();
1475d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        } else {
14836dcd511c2d065eef1e4310be7fe5e586e1bacc4Aurimas Liutikas            IMPL = new ConnectivityManagerCompatBaseImpl();
1495d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        }
1505d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey    }
1515d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey
1525d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey    /**
1535d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey     * Returns if the currently active data network is metered. A network is
1545d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey     * classified as metered when the user is sensitive to heavy data usage on
155c725e0cfeb10019175b9a7e1eba80081848f7484Alan Viverette     * that connection due to monetary costs, data limitations or
156c725e0cfeb10019175b9a7e1eba80081848f7484Alan Viverette     * battery/performance issues. You should check this before doing large
157c725e0cfeb10019175b9a7e1eba80081848f7484Alan Viverette     * data transfers, and warn the user or delay the operation until another
158c725e0cfeb10019175b9a7e1eba80081848f7484Alan Viverette     * network is available.
159c725e0cfeb10019175b9a7e1eba80081848f7484Alan Viverette     * <p>This method requires the caller to hold the permission
160c725e0cfeb10019175b9a7e1eba80081848f7484Alan Viverette     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
161c725e0cfeb10019175b9a7e1eba80081848f7484Alan Viverette     *
162c725e0cfeb10019175b9a7e1eba80081848f7484Alan Viverette     * @return {@code true} if large transfers should be avoided, otherwise
163c725e0cfeb10019175b9a7e1eba80081848f7484Alan Viverette     *        {@code false}.
1645d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey     */
165d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey    public static boolean isActiveNetworkMetered(ConnectivityManager cm) {
1665d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey        return IMPL.isActiveNetworkMetered(cm);
1675d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey    }
168d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey
169d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey    /**
170d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey     * Return the {@link NetworkInfo} that caused the given
171d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey     * {@link ConnectivityManager#CONNECTIVITY_ACTION} broadcast. This obtains
172d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey     * the current state from {@link ConnectivityManager} instead of using the
173d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey     * potentially-stale value from
174ae9236048961df9576210e7db8424d7c93a1a8adJeff Sharkey     * {@link ConnectivityManager#EXTRA_NETWORK_INFO}. May be {@code null}.
175d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey     */
176d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey    public static NetworkInfo getNetworkInfoFromBroadcast(ConnectivityManager cm, Intent intent) {
177d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey        final NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
178ae9236048961df9576210e7db8424d7c93a1a8adJeff Sharkey        if (info != null) {
179ae9236048961df9576210e7db8424d7c93a1a8adJeff Sharkey            return cm.getNetworkInfo(info.getType());
180ae9236048961df9576210e7db8424d7c93a1a8adJeff Sharkey        } else {
181ae9236048961df9576210e7db8424d7c93a1a8adJeff Sharkey            return null;
182ae9236048961df9576210e7db8424d7c93a1a8adJeff Sharkey        }
183d5e609a825a32049f519b7bd23a1caad8aaee088Jeff Sharkey    }
184c5847d13e40f5d52459f5c0dab32dc08f1a9a683Chris Banes
185ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    /**
186ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * Determines if the calling application is subject to metered network restrictions while
187ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * running on background.
188ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     *
189ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     * @return {@link #RESTRICT_BACKGROUND_STATUS_DISABLED},
190ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     *         {@link #RESTRICT_BACKGROUND_STATUS_ENABLED},
191ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     *         or {@link #RESTRICT_BACKGROUND_STATUS_WHITELISTED}
192ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette     */
193ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    @RestrictBackgroundStatus
194ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    public static int getRestrictBackgroundStatus(ConnectivityManager cm) {
195ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette        return IMPL.getRestrictBackgroundStatus(cm);
196ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette    }
197ca7861c8ce16f632aa0026910b0f6dc5db0ad812Alan Viverette
198c5847d13e40f5d52459f5c0dab32dc08f1a9a683Chris Banes    private ConnectivityManagerCompat() {}
1995d79c2b6211936177817f2492816c1dba76dac3eJeff Sharkey}
200