OSDN Git Service

2cd1f9bd2c8500cbf2857d2c80b3e840db3ac801
[android-x86/frameworks-base.git] / core / java / android / net / NetworkPolicyManager.java
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
17 package android.net;
18
19 import static android.content.pm.PackageManager.GET_SIGNATURES;
20 import static android.net.NetworkPolicy.CYCLE_NONE;
21 import static android.text.format.Time.MONTH_DAY;
22
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.content.pm.PackageManager.NameNotFoundException;
27 import android.content.pm.Signature;
28 import android.os.RemoteException;
29 import android.os.UserHandle;
30 import android.text.format.Time;
31
32 import com.google.android.collect.Sets;
33
34 import java.io.PrintWriter;
35 import java.util.HashSet;
36
37 /**
38  * Manager for creating and modifying network policy rules.
39  *
40  * {@hide}
41  */
42 public class NetworkPolicyManager {
43
44     /** No specific network policy, use system default. */
45     public static final int POLICY_NONE = 0x0;
46     /** Reject network usage on metered networks when application in background. */
47     public static final int POLICY_REJECT_METERED_BACKGROUND = 0x1;
48
49     /** All network traffic should be allowed. */
50     public static final int RULE_ALLOW_ALL = 0x0;
51     /** Reject traffic on metered networks. */
52     public static final int RULE_REJECT_METERED = 0x1;
53
54     private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
55
56     /**
57      * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it
58      * applies to.
59      */
60     public static final String EXTRA_NETWORK_TEMPLATE = "android.net.NETWORK_TEMPLATE";
61
62     private INetworkPolicyManager mService;
63
64     public NetworkPolicyManager(INetworkPolicyManager service) {
65         if (service == null) {
66             throw new IllegalArgumentException("missing INetworkPolicyManager");
67         }
68         mService = service;
69     }
70
71     public static NetworkPolicyManager from(Context context) {
72         return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
73     }
74
75     /**
76      * Set policy flags for specific UID.
77      *
78      * @param policy {@link #POLICY_NONE} or combination of flags like
79      *            {@link #POLICY_REJECT_METERED_BACKGROUND}.
80      */
81     public void setUidPolicy(int uid, int policy) {
82         try {
83             mService.setUidPolicy(uid, policy);
84         } catch (RemoteException e) {
85         }
86     }
87
88     public int getUidPolicy(int uid) {
89         try {
90             return mService.getUidPolicy(uid);
91         } catch (RemoteException e) {
92             return POLICY_NONE;
93         }
94     }
95
96     public int[] getUidsWithPolicy(int policy) {
97         try {
98             return mService.getUidsWithPolicy(policy);
99         } catch (RemoteException e) {
100             return new int[0];
101         }
102     }
103
104     public void registerListener(INetworkPolicyListener listener) {
105         try {
106             mService.registerListener(listener);
107         } catch (RemoteException e) {
108         }
109     }
110
111     public void unregisterListener(INetworkPolicyListener listener) {
112         try {
113             mService.unregisterListener(listener);
114         } catch (RemoteException e) {
115         }
116     }
117
118     public void setNetworkPolicies(NetworkPolicy[] policies) {
119         try {
120             mService.setNetworkPolicies(policies);
121         } catch (RemoteException e) {
122         }
123     }
124
125     public NetworkPolicy[] getNetworkPolicies() {
126         try {
127             return mService.getNetworkPolicies();
128         } catch (RemoteException e) {
129             return null;
130         }
131     }
132
133     public void setRestrictBackground(boolean restrictBackground) {
134         try {
135             mService.setRestrictBackground(restrictBackground);
136         } catch (RemoteException e) {
137         }
138     }
139
140     public boolean getRestrictBackground() {
141         try {
142             return mService.getRestrictBackground();
143         } catch (RemoteException e) {
144             return false;
145         }
146     }
147
148     /**
149      * Compute the last cycle boundary for the given {@link NetworkPolicy}. For
150      * example, if cycle day is 20th, and today is June 15th, it will return May
151      * 20th. When cycle day doesn't exist in current month, it snaps to the 1st
152      * of following month.
153      *
154      * @hide
155      */
156     public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
157         if (policy.cycleDay == CYCLE_NONE) {
158             throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
159         }
160
161         final Time now = new Time(policy.cycleTimezone);
162         now.set(currentTime);
163
164         // first, find cycle boundary for current month
165         final Time cycle = new Time(now);
166         cycle.hour = cycle.minute = cycle.second = 0;
167         snapToCycleDay(cycle, policy.cycleDay);
168
169         if (Time.compare(cycle, now) >= 0) {
170             // cycle boundary is beyond now, use last cycle boundary; start by
171             // pushing ourselves squarely into last month.
172             final Time lastMonth = new Time(now);
173             lastMonth.hour = lastMonth.minute = lastMonth.second = 0;
174             lastMonth.monthDay = 1;
175             lastMonth.month -= 1;
176             lastMonth.normalize(true);
177
178             cycle.set(lastMonth);
179             snapToCycleDay(cycle, policy.cycleDay);
180         }
181
182         return cycle.toMillis(true);
183     }
184
185     /** {@hide} */
186     public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
187         if (policy.cycleDay == CYCLE_NONE) {
188             throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
189         }
190
191         final Time now = new Time(policy.cycleTimezone);
192         now.set(currentTime);
193
194         // first, find cycle boundary for current month
195         final Time cycle = new Time(now);
196         cycle.hour = cycle.minute = cycle.second = 0;
197         snapToCycleDay(cycle, policy.cycleDay);
198
199         if (Time.compare(cycle, now) <= 0) {
200             // cycle boundary is before now, use next cycle boundary; start by
201             // pushing ourselves squarely into next month.
202             final Time nextMonth = new Time(now);
203             nextMonth.hour = nextMonth.minute = nextMonth.second = 0;
204             nextMonth.monthDay = 1;
205             nextMonth.month += 1;
206             nextMonth.normalize(true);
207
208             cycle.set(nextMonth);
209             snapToCycleDay(cycle, policy.cycleDay);
210         }
211
212         return cycle.toMillis(true);
213     }
214
215     /**
216      * Snap to the cycle day for the current month given; when cycle day doesn't
217      * exist, it snaps to last second of current month.
218      *
219      * @hide
220      */
221     public static void snapToCycleDay(Time time, int cycleDay) {
222         if (cycleDay > time.getActualMaximum(MONTH_DAY)) {
223             // cycle day isn't valid this month; snap to last second of month
224             time.month += 1;
225             time.monthDay = 1;
226             time.second = -1;
227         } else {
228             time.monthDay = cycleDay;
229         }
230         time.normalize(true);
231     }
232
233     /**
234      * Check if given UID can have a {@link #setUidPolicy(int, int)} defined,
235      * usually to protect critical system services.
236      */
237     @Deprecated
238     public static boolean isUidValidForPolicy(Context context, int uid) {
239         // first, quick-reject non-applications
240         if (!UserHandle.isApp(uid)) {
241             return false;
242         }
243
244         if (!ALLOW_PLATFORM_APP_POLICY) {
245             final PackageManager pm = context.getPackageManager();
246             final HashSet<Signature> systemSignature;
247             try {
248                 systemSignature = Sets.newHashSet(
249                         pm.getPackageInfo("android", GET_SIGNATURES).signatures);
250             } catch (NameNotFoundException e) {
251                 throw new RuntimeException("problem finding system signature", e);
252             }
253
254             try {
255                 // reject apps signed with platform cert
256                 for (String packageName : pm.getPackagesForUid(uid)) {
257                     final HashSet<Signature> packageSignature = Sets.newHashSet(
258                             pm.getPackageInfo(packageName, GET_SIGNATURES).signatures);
259                     if (packageSignature.containsAll(systemSignature)) {
260                         return false;
261                     }
262                 }
263             } catch (NameNotFoundException e) {
264             }
265         }
266
267         // nothing found above; we can apply policy to UID
268         return true;
269     }
270
271     /** {@hide} */
272     public static void dumpPolicy(PrintWriter fout, int policy) {
273         fout.write("[");
274         if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
275             fout.write("REJECT_METERED_BACKGROUND");
276         }
277         fout.write("]");
278     }
279
280     /** {@hide} */
281     public static void dumpRules(PrintWriter fout, int rules) {
282         fout.write("[");
283         if ((rules & RULE_REJECT_METERED) != 0) {
284             fout.write("REJECT_METERED");
285         }
286         fout.write("]");
287     }
288
289 }