NetworkPolicyManager.java revision 1a303953589fdddf21d88b8fa660136f5b060d0d
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    public void registerListener(INetworkPolicyListener listener) {
119        try {
120            mService.registerListener(listener);
121        } catch (RemoteException e) {
122        }
123    }
124
125    public void unregisterListener(INetworkPolicyListener listener) {
126        try {
127            mService.unregisterListener(listener);
128        } catch (RemoteException e) {
129        }
130    }
131
132    /**
133     * Compute the last cycle boundary for the given {@link NetworkPolicy}. For
134     * example, if cycle day is 20th, and today is June 15th, it will return May
135     * 20th. When cycle day doesn't exist in current month, it snaps to the 1st
136     * of following month.
137     *
138     * @hide
139     */
140    public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
141        final Time now = new Time(Time.TIMEZONE_UTC);
142        now.set(currentTime);
143
144        // first, find cycle boundary for current month
145        final Time cycle = new Time(now);
146        cycle.hour = cycle.minute = cycle.second = 0;
147        snapToCycleDay(cycle, policy.cycleDay);
148
149        if (Time.compare(cycle, now) >= 0) {
150            // cycle boundary is beyond now, use last cycle boundary; start by
151            // pushing ourselves squarely into last month.
152            final Time lastMonth = new Time(now);
153            lastMonth.hour = lastMonth.minute = lastMonth.second = 0;
154            lastMonth.monthDay = 1;
155            lastMonth.month -= 1;
156            lastMonth.normalize(true);
157
158            cycle.set(lastMonth);
159            snapToCycleDay(cycle, policy.cycleDay);
160        }
161
162        return cycle.toMillis(true);
163    }
164
165    /** {@hide} */
166    public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
167        final Time now = new Time(Time.TIMEZONE_UTC);
168        now.set(currentTime);
169
170        // first, find cycle boundary for current month
171        final Time cycle = new Time(now);
172        cycle.hour = cycle.minute = cycle.second = 0;
173        snapToCycleDay(cycle, policy.cycleDay);
174
175        if (Time.compare(cycle, now) <= 0) {
176            // cycle boundary is before now, use next cycle boundary; start by
177            // pushing ourselves squarely into next month.
178            final Time nextMonth = new Time(now);
179            nextMonth.hour = nextMonth.minute = nextMonth.second = 0;
180            nextMonth.monthDay = 1;
181            nextMonth.month += 1;
182            nextMonth.normalize(true);
183
184            cycle.set(nextMonth);
185            snapToCycleDay(cycle, policy.cycleDay);
186        }
187
188        return cycle.toMillis(true);
189    }
190
191    /**
192     * Snap to the cycle day for the current month given; when cycle day doesn't
193     * exist, it snaps to 1st of following month.
194     *
195     * @hide
196     */
197    public static void snapToCycleDay(Time time, int cycleDay) {
198        if (cycleDay > time.getActualMaximum(MONTH_DAY)) {
199            // cycle day isn't valid this month; snap to 1st of next month
200            time.month += 1;
201            time.monthDay = 1;
202        } else {
203            time.monthDay = cycleDay;
204        }
205        time.normalize(true);
206    }
207
208    /**
209     * Check if given UID can have a {@link #setUidPolicy(int, int)} defined,
210     * usually to protect critical system services.
211     */
212    public static boolean isUidValidForPolicy(Context context, int uid) {
213        return (uid >= android.os.Process.FIRST_APPLICATION_UID
214                && uid <= android.os.Process.LAST_APPLICATION_UID);
215    }
216
217    /** {@hide} */
218    public static void dumpPolicy(PrintWriter fout, int policy) {
219        fout.write("[");
220        if ((policy & POLICY_REJECT_PAID_BACKGROUND) != 0) {
221            fout.write("REJECT_PAID_BACKGROUND");
222        }
223        fout.write("]");
224    }
225
226    /** {@hide} */
227    public static void dumpRules(PrintWriter fout, int rules) {
228        fout.write("[");
229        if ((rules & RULE_REJECT_PAID) != 0) {
230            fout.write("REJECT_PAID");
231        }
232        fout.write("]");
233    }
234
235}
236