blob: a7ffee924bbff0b939ab1dfc99a0a392cd2199aa [file] [log] [blame]
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001/*
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
Jeff Sharkey4414cea2011-06-24 17:05:24 -070019import static android.content.pm.PackageManager.GET_SIGNATURES;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -070020import static android.net.NetworkPolicy.CYCLE_NONE;
Jeff Sharkeycd2ca402011-06-10 15:14:07 -070021import static android.text.format.Time.MONTH_DAY;
22
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070023import android.content.Context;
Jeff Sharkey14711eb2011-06-15 10:29:17 -070024import android.content.Intent;
Jeff Sharkey4414cea2011-06-24 17:05:24 -070025import android.content.pm.PackageManager;
26import android.content.pm.PackageManager.NameNotFoundException;
27import android.content.pm.Signature;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070028import android.os.RemoteException;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -070029import android.os.UserHandle;
Jeff Sharkeycd2ca402011-06-10 15:14:07 -070030import android.text.format.Time;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070031
Jeff Sharkey4414cea2011-06-24 17:05:24 -070032import com.google.android.collect.Sets;
33
Jeff Sharkey1b861272011-05-22 00:34:52 -070034import java.io.PrintWriter;
Jeff Sharkey4414cea2011-06-24 17:05:24 -070035import java.util.HashSet;
Jeff Sharkey1b861272011-05-22 00:34:52 -070036
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070037/**
38 * Manager for creating and modifying network policy rules.
39 *
40 * {@hide}
41 */
42public class NetworkPolicyManager {
43
44 /** No specific network policy, use system default. */
45 public static final int POLICY_NONE = 0x0;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -070046 /** Reject network usage on metered networks when application in background. */
47 public static final int POLICY_REJECT_METERED_BACKGROUND = 0x1;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070048 /** Allow network use (metered or not) in the background in battery save mode. */
49 public static final int POLICY_ALLOW_BACKGROUND_BATTERY_SAVE = 0x2;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -070050
51 /** All network traffic should be allowed. */
52 public static final int RULE_ALLOW_ALL = 0x0;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -070053 /** Reject traffic on metered networks. */
54 public static final int RULE_REJECT_METERED = 0x1;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070055
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -070056 private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
57
Jeff Sharkey14711eb2011-06-15 10:29:17 -070058 /**
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -070059 * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it
60 * applies to.
Jeff Sharkey14711eb2011-06-15 10:29:17 -070061 */
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -070062 public static final String EXTRA_NETWORK_TEMPLATE = "android.net.NETWORK_TEMPLATE";
Jeff Sharkey14711eb2011-06-15 10:29:17 -070063
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070064 private INetworkPolicyManager mService;
65
66 public NetworkPolicyManager(INetworkPolicyManager service) {
67 if (service == null) {
68 throw new IllegalArgumentException("missing INetworkPolicyManager");
69 }
70 mService = service;
71 }
72
Jeff Sharkey8fc27e82012-04-04 20:40:58 -070073 public static NetworkPolicyManager from(Context context) {
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070074 return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
75 }
76
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070077 /**
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -070078 * Set policy flags for specific UID.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070079 *
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -070080 * @param policy {@link #POLICY_NONE} or combination of flags like
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070081 * {@link #POLICY_REJECT_METERED_BACKGROUND}, {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070082 */
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -070083 public void setUidPolicy(int uid, int policy) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070084 try {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -070085 mService.setUidPolicy(uid, policy);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070086 } catch (RemoteException e) {
87 }
88 }
89
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070090 /**
91 * Add policy flags for specific UID. The given policy bits will be set for
92 * the uid. Policy flags may be either
93 * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
94 */
95 public void addUidPolicy(int uid, int policy) {
96 try {
97 mService.addUidPolicy(uid, policy);
98 } catch (RemoteException e) {
99 }
100 }
101
102 /**
103 * Clear/remove policy flags for specific UID. The given policy bits will be set for
104 * the uid. Policy flags may be either
105 * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
106 */
107 public void removeUidPolicy(int uid, int policy) {
108 try {
109 mService.removeUidPolicy(uid, policy);
110 } catch (RemoteException e) {
111 }
112 }
113
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700114 public int getUidPolicy(int uid) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700115 try {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700116 return mService.getUidPolicy(uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700117 } catch (RemoteException e) {
118 return POLICY_NONE;
119 }
120 }
Jeff Sharkeycd2ca402011-06-10 15:14:07 -0700121
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700122 public int[] getUidsWithPolicy(int policy) {
Jeff Sharkey854b2b12012-04-13 16:03:40 -0700123 try {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700124 return mService.getUidsWithPolicy(policy);
Jeff Sharkey854b2b12012-04-13 16:03:40 -0700125 } catch (RemoteException e) {
126 return new int[0];
127 }
128 }
129
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700130 public int[] getPowerSaveAppIdWhitelist() {
131 try {
132 return mService.getPowerSaveAppIdWhitelist();
133 } catch (RemoteException e) {
134 return new int[0];
135 }
136 }
137
Jeff Sharkey1a303952011-06-16 13:04:20 -0700138 public void registerListener(INetworkPolicyListener listener) {
139 try {
140 mService.registerListener(listener);
141 } catch (RemoteException e) {
142 }
143 }
144
145 public void unregisterListener(INetworkPolicyListener listener) {
146 try {
147 mService.unregisterListener(listener);
148 } catch (RemoteException e) {
149 }
150 }
151
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700152 public void setNetworkPolicies(NetworkPolicy[] policies) {
153 try {
154 mService.setNetworkPolicies(policies);
155 } catch (RemoteException e) {
156 }
157 }
158
159 public NetworkPolicy[] getNetworkPolicies() {
160 try {
161 return mService.getNetworkPolicies();
162 } catch (RemoteException e) {
163 return null;
164 }
165 }
166
167 public void setRestrictBackground(boolean restrictBackground) {
168 try {
169 mService.setRestrictBackground(restrictBackground);
170 } catch (RemoteException e) {
171 }
172 }
173
174 public boolean getRestrictBackground() {
175 try {
176 return mService.getRestrictBackground();
177 } catch (RemoteException e) {
178 return false;
179 }
180 }
181
Jeff Sharkeycd2ca402011-06-10 15:14:07 -0700182 /**
Stuart Scott984dc852015-03-30 13:17:11 -0700183 * Resets network policy settings back to factory defaults.
184 *
185 * @hide
186 */
187 public void factoryReset(String subscriber) {
188 // Turn mobile data limit off
189 NetworkPolicy[] policies = getNetworkPolicies();
190 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
191 for (NetworkPolicy policy : policies) {
192 if (policy.template.equals(template)) {
193 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
194 policy.inferred = false;
195 policy.clearSnooze();
196 }
197 }
198 setNetworkPolicies(policies);
199
200 // Turn restrict background data off
201 setRestrictBackground(false);
202
203 // Remove app's "restrict background data" flag
204 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
205 setUidPolicy(uid, NetworkPolicyManager.POLICY_NONE);
206 }
207 }
208
209 /**
Jeff Sharkeycd2ca402011-06-10 15:14:07 -0700210 * Compute the last cycle boundary for the given {@link NetworkPolicy}. For
211 * example, if cycle day is 20th, and today is June 15th, it will return May
212 * 20th. When cycle day doesn't exist in current month, it snaps to the 1st
213 * of following month.
214 *
215 * @hide
216 */
217 public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700218 if (policy.cycleDay == CYCLE_NONE) {
219 throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
220 }
221
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800222 final Time now = new Time(policy.cycleTimezone);
Jeff Sharkeycd2ca402011-06-10 15:14:07 -0700223 now.set(currentTime);
224
225 // first, find cycle boundary for current month
226 final Time cycle = new Time(now);
227 cycle.hour = cycle.minute = cycle.second = 0;
228 snapToCycleDay(cycle, policy.cycleDay);
229
230 if (Time.compare(cycle, now) >= 0) {
231 // cycle boundary is beyond now, use last cycle boundary; start by
232 // pushing ourselves squarely into last month.
233 final Time lastMonth = new Time(now);
234 lastMonth.hour = lastMonth.minute = lastMonth.second = 0;
235 lastMonth.monthDay = 1;
236 lastMonth.month -= 1;
237 lastMonth.normalize(true);
238
239 cycle.set(lastMonth);
240 snapToCycleDay(cycle, policy.cycleDay);
241 }
242
243 return cycle.toMillis(true);
244 }
245
246 /** {@hide} */
247 public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700248 if (policy.cycleDay == CYCLE_NONE) {
249 throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
250 }
251
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800252 final Time now = new Time(policy.cycleTimezone);
Jeff Sharkeycd2ca402011-06-10 15:14:07 -0700253 now.set(currentTime);
254
255 // first, find cycle boundary for current month
256 final Time cycle = new Time(now);
257 cycle.hour = cycle.minute = cycle.second = 0;
258 snapToCycleDay(cycle, policy.cycleDay);
259
260 if (Time.compare(cycle, now) <= 0) {
261 // cycle boundary is before now, use next cycle boundary; start by
262 // pushing ourselves squarely into next month.
263 final Time nextMonth = new Time(now);
264 nextMonth.hour = nextMonth.minute = nextMonth.second = 0;
265 nextMonth.monthDay = 1;
266 nextMonth.month += 1;
267 nextMonth.normalize(true);
268
269 cycle.set(nextMonth);
270 snapToCycleDay(cycle, policy.cycleDay);
271 }
272
273 return cycle.toMillis(true);
274 }
275
276 /**
277 * Snap to the cycle day for the current month given; when cycle day doesn't
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800278 * exist, it snaps to last second of current month.
Jeff Sharkeycd2ca402011-06-10 15:14:07 -0700279 *
280 * @hide
281 */
282 public static void snapToCycleDay(Time time, int cycleDay) {
283 if (cycleDay > time.getActualMaximum(MONTH_DAY)) {
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -0700284 // cycle day isn't valid this month; snap to last second of month
Jeff Sharkeycd2ca402011-06-10 15:14:07 -0700285 time.month += 1;
286 time.monthDay = 1;
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -0700287 time.second = -1;
Jeff Sharkeycd2ca402011-06-10 15:14:07 -0700288 } else {
289 time.monthDay = cycleDay;
290 }
291 time.normalize(true);
292 }
293
Jeff Sharkey497e4432011-06-14 17:27:29 -0700294 /**
295 * Check if given UID can have a {@link #setUidPolicy(int, int)} defined,
296 * usually to protect critical system services.
297 */
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700298 @Deprecated
Jeff Sharkey497e4432011-06-14 17:27:29 -0700299 public static boolean isUidValidForPolicy(Context context, int uid) {
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700300 // first, quick-reject non-applications
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700301 if (!UserHandle.isApp(uid)) {
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700302 return false;
303 }
304
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700305 if (!ALLOW_PLATFORM_APP_POLICY) {
306 final PackageManager pm = context.getPackageManager();
307 final HashSet<Signature> systemSignature;
308 try {
309 systemSignature = Sets.newHashSet(
310 pm.getPackageInfo("android", GET_SIGNATURES).signatures);
311 } catch (NameNotFoundException e) {
312 throw new RuntimeException("problem finding system signature", e);
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700313 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700314
315 try {
316 // reject apps signed with platform cert
317 for (String packageName : pm.getPackagesForUid(uid)) {
318 final HashSet<Signature> packageSignature = Sets.newHashSet(
319 pm.getPackageInfo(packageName, GET_SIGNATURES).signatures);
320 if (packageSignature.containsAll(systemSignature)) {
321 return false;
322 }
323 }
324 } catch (NameNotFoundException e) {
325 }
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700326 }
327
328 // nothing found above; we can apply policy to UID
329 return true;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700330 }
331
Jeff Sharkey1b861272011-05-22 00:34:52 -0700332 /** {@hide} */
333 public static void dumpPolicy(PrintWriter fout, int policy) {
334 fout.write("[");
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700335 if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
336 fout.write("REJECT_METERED_BACKGROUND");
Jeff Sharkey1b861272011-05-22 00:34:52 -0700337 }
338 fout.write("]");
339 }
340
341 /** {@hide} */
342 public static void dumpRules(PrintWriter fout, int rules) {
343 fout.write("[");
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700344 if ((rules & RULE_REJECT_METERED) != 0) {
345 fout.write("REJECT_METERED");
Jeff Sharkey1b861272011-05-22 00:34:52 -0700346 }
347 fout.write("]");
348 }
349
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700350}