NetworkPolicyManager.java revision 14711eb5b6a45b587222ae71c57a381beb7b1a7e
1/*
2 * Copyright (C) 2011 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
17package android.net;
18
19import static android.text.format.Time.MONTH_DAY;
20
21import android.content.Context;
22import android.content.Intent;
23import android.os.RemoteException;
24import android.text.format.Time;
25
26import java.io.PrintWriter;
27
28/**
29 * Manager for creating and modifying network policy rules.
30 *
31 * {@hide}
32 */
33public class NetworkPolicyManager {
34
35    /** No specific network policy, use system default. */
36    public static final int POLICY_NONE = 0x0;
37    /** Reject network usage on paid networks when application in background. */
38    public static final int POLICY_REJECT_PAID_BACKGROUND = 0x1;
39
40    /** All network traffic should be allowed. */
41    public static final int RULE_ALLOW_ALL = 0x0;
42    /** Reject traffic on paid networks. */
43    public static final int RULE_REJECT_PAID = 0x1;
44
45    /**
46     * {@link Intent} action launched when user selects {@link NetworkPolicy}
47     * warning notification.
48     */
49    public static final String ACTION_DATA_USAGE_WARNING =
50            "android.intent.action.DATA_USAGE_WARNING";
51
52    /**
53     * {@link Intent} action launched when user selects {@link NetworkPolicy}
54     * limit notification.
55     */
56    public static final String ACTION_DATA_USAGE_LIMIT =
57            "android.intent.action.DATA_USAGE_LIMIT";
58
59    /**
60     * {@link Intent} extra included in {@link #ACTION_DATA_USAGE_WARNING} and
61     * {@link #ACTION_DATA_USAGE_LIMIT} to indicate which
62     * {@link NetworkPolicy#networkTemplate} it applies to.
63     */
64    public static final String EXTRA_NETWORK_TEMPLATE =
65            "android.intent.extra.NETWORK_TEMPLATE";
66
67    private INetworkPolicyManager mService;
68
69    public NetworkPolicyManager(INetworkPolicyManager service) {
70        if (service == null) {
71            throw new IllegalArgumentException("missing INetworkPolicyManager");
72        }
73        mService = service;
74    }
75
76    public static NetworkPolicyManager getSystemService(Context context) {
77        return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
78    }
79
80    /** {@hide} */
81    public void setNetworkPolicies(NetworkPolicy[] policies) {
82        try {
83            mService.setNetworkPolicies(policies);
84        } catch (RemoteException e) {
85        }
86    }
87
88    /** {@hide} */
89    public NetworkPolicy[] getNetworkPolicies() {
90        try {
91            return mService.getNetworkPolicies();
92        } catch (RemoteException e) {
93            return null;
94        }
95    }
96
97    /**
98     * Set policy flags for specific UID.
99     *
100     * @param policy {@link #POLICY_NONE} or combination of flags like
101     *            {@link #POLICY_REJECT_PAID_BACKGROUND}.
102     */
103    public void setUidPolicy(int uid, int policy) {
104        try {
105            mService.setUidPolicy(uid, policy);
106        } catch (RemoteException e) {
107        }
108    }
109
110    public int getUidPolicy(int uid) {
111        try {
112            return mService.getUidPolicy(uid);
113        } catch (RemoteException e) {
114            return POLICY_NONE;
115        }
116    }
117
118    /**
119     * Compute the last cycle boundary for the given {@link NetworkPolicy}. For
120     * example, if cycle day is 20th, and today is June 15th, it will return May
121     * 20th. When cycle day doesn't exist in current month, it snaps to the 1st
122     * of following month.
123     *
124     * @hide
125     */
126    public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
127        final Time now = new Time(Time.TIMEZONE_UTC);
128        now.set(currentTime);
129
130        // first, find cycle boundary for current month
131        final Time cycle = new Time(now);
132        cycle.hour = cycle.minute = cycle.second = 0;
133        snapToCycleDay(cycle, policy.cycleDay);
134
135        if (Time.compare(cycle, now) >= 0) {
136            // cycle boundary is beyond now, use last cycle boundary; start by
137            // pushing ourselves squarely into last month.
138            final Time lastMonth = new Time(now);
139            lastMonth.hour = lastMonth.minute = lastMonth.second = 0;
140            lastMonth.monthDay = 1;
141            lastMonth.month -= 1;
142            lastMonth.normalize(true);
143
144            cycle.set(lastMonth);
145            snapToCycleDay(cycle, policy.cycleDay);
146        }
147
148        return cycle.toMillis(true);
149    }
150
151    /** {@hide} */
152    public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
153        final Time now = new Time(Time.TIMEZONE_UTC);
154        now.set(currentTime);
155
156        // first, find cycle boundary for current month
157        final Time cycle = new Time(now);
158        cycle.hour = cycle.minute = cycle.second = 0;
159        snapToCycleDay(cycle, policy.cycleDay);
160
161        if (Time.compare(cycle, now) <= 0) {
162            // cycle boundary is before now, use next cycle boundary; start by
163            // pushing ourselves squarely into next month.
164            final Time nextMonth = new Time(now);
165            nextMonth.hour = nextMonth.minute = nextMonth.second = 0;
166            nextMonth.monthDay = 1;
167            nextMonth.month += 1;
168            nextMonth.normalize(true);
169
170            cycle.set(nextMonth);
171            snapToCycleDay(cycle, policy.cycleDay);
172        }
173
174        return cycle.toMillis(true);
175    }
176
177    /**
178     * Snap to the cycle day for the current month given; when cycle day doesn't
179     * exist, it snaps to 1st of following month.
180     *
181     * @hide
182     */
183    public static void snapToCycleDay(Time time, int cycleDay) {
184        if (cycleDay > time.getActualMaximum(MONTH_DAY)) {
185            // cycle day isn't valid this month; snap to 1st of next month
186            time.month += 1;
187            time.monthDay = 1;
188        } else {
189            time.monthDay = cycleDay;
190        }
191        time.normalize(true);
192    }
193
194    /**
195     * Check if given UID can have a {@link #setUidPolicy(int, int)} defined,
196     * usually to protect critical system services.
197     */
198    public static boolean isUidValidForPolicy(Context context, int uid) {
199        return (uid >= android.os.Process.FIRST_APPLICATION_UID
200                && uid <= android.os.Process.LAST_APPLICATION_UID);
201    }
202
203    /** {@hide} */
204    public static void dumpPolicy(PrintWriter fout, int policy) {
205        fout.write("[");
206        if ((policy & POLICY_REJECT_PAID_BACKGROUND) != 0) {
207            fout.write("REJECT_PAID_BACKGROUND");
208        }
209        fout.write("]");
210    }
211
212    /** {@hide} */
213    public static void dumpRules(PrintWriter fout, int rules) {
214        fout.write("[");
215        if ((rules & RULE_REJECT_PAID) != 0) {
216            fout.write("REJECT_PAID");
217        }
218        fout.write("]");
219    }
220
221}
222