blob: 56d41c5a72aa5db2af00f4a494bba61d0d356004 [file] [log] [blame]
Felipe Leme50a235e2016-01-15 18:37:06 -08001/*
2 * Copyright (C) 2016 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 com.android.server.net;
18
Felipe Leme57e3d312016-08-23 14:42:52 -070019import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
Felipe Leme9982b302016-03-01 13:40:31 -080020import static android.net.NetworkPolicyManager.POLICY_NONE;
21import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
Felipe Lemede4e8e32016-02-02 18:55:22 -080022
Felipe Lemeb1a65ee2016-02-08 10:12:01 -080023import android.content.Context;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060024import android.net.NetworkPolicyManager;
Felipe Lemeb1a65ee2016-02-08 10:12:01 -080025import android.net.wifi.WifiConfiguration;
26import android.net.wifi.WifiManager;
Felipe Leme50a235e2016-01-15 18:37:06 -080027import android.os.RemoteException;
28import android.os.ShellCommand;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060029
30import java.io.PrintWriter;
31import java.util.List;
Felipe Leme50a235e2016-01-15 18:37:06 -080032
Felipe Lemede4e8e32016-02-02 18:55:22 -080033class NetworkPolicyManagerShellCommand extends ShellCommand {
Felipe Leme50a235e2016-01-15 18:37:06 -080034
Jeff Sharkey003d3e62018-03-30 14:35:04 -060035 private final NetworkPolicyManagerService mInterface;
Felipe Lemeb1a65ee2016-02-08 10:12:01 -080036 private final WifiManager mWifiManager;
Felipe Leme50a235e2016-01-15 18:37:06 -080037
Jeff Sharkey003d3e62018-03-30 14:35:04 -060038 NetworkPolicyManagerShellCommand(Context context, NetworkPolicyManagerService service) {
Felipe Leme50a235e2016-01-15 18:37:06 -080039 mInterface = service;
Felipe Lemeb1a65ee2016-02-08 10:12:01 -080040 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Felipe Leme50a235e2016-01-15 18:37:06 -080041 }
42
43 @Override
44 public int onCommand(String cmd) {
45 if (cmd == null) {
46 return handleDefaultCommands(cmd);
47 }
48 final PrintWriter pw = getOutPrintWriter();
49 try {
50 switch(cmd) {
51 case "get":
52 return runGet();
53 case "set":
54 return runSet();
55 case "list":
56 return runList();
57 case "add":
58 return runAdd();
59 case "remove":
60 return runRemove();
61 default:
62 return handleDefaultCommands(cmd);
63 }
64 } catch (RemoteException e) {
65 pw.println("Remote exception: " + e);
66 }
67 return -1;
68 }
69
70 @Override
71 public void onHelp() {
72 final PrintWriter pw = getOutPrintWriter();
73 pw.println("Network policy manager (netpolicy) commands:");
74 pw.println(" help");
75 pw.println(" Print this help text.");
76 pw.println("");
Felipe Leme50a235e2016-01-15 18:37:06 -080077 pw.println(" add restrict-background-whitelist UID");
78 pw.println(" Adds a UID to the whitelist for restrict background usage.");
Felipe Leme9982b302016-03-01 13:40:31 -080079 pw.println(" add restrict-background-blacklist UID");
80 pw.println(" Adds a UID to the blacklist for restrict background usage.");
Felipe Lemede4e8e32016-02-02 18:55:22 -080081 pw.println(" get restrict-background");
82 pw.println(" Gets the global restrict background usage status.");
Jeff Sharkey43d2a172017-07-12 10:50:42 -060083 pw.println(" list wifi-networks [true|false]");
Felipe Lemeb9aee90a2016-03-30 16:14:54 -070084 pw.println(" Lists all saved wifi networks and whether they are metered or not.");
Felipe Lemede4e8e32016-02-02 18:55:22 -080085 pw.println(" If a boolean argument is passed, filters just the metered (or unmetered)");
86 pw.println(" networks.");
87 pw.println(" list restrict-background-whitelist");
88 pw.println(" Lists UIDs that are whitelisted for restrict background usage.");
Felipe Leme9982b302016-03-01 13:40:31 -080089 pw.println(" list restrict-background-blacklist");
90 pw.println(" Lists UIDs that are blacklisted for restrict background usage.");
Felipe Leme50a235e2016-01-15 18:37:06 -080091 pw.println(" remove restrict-background-whitelist UID");
92 pw.println(" Removes a UID from the whitelist for restrict background usage.");
Felipe Leme9982b302016-03-01 13:40:31 -080093 pw.println(" remove restrict-background-blacklist UID");
94 pw.println(" Removes a UID from the blacklist for restrict background usage.");
Jeff Sharkey43d2a172017-07-12 10:50:42 -060095 pw.println(" set metered-network ID [undefined|true|false]");
Felipe Lemeb9aee90a2016-03-30 16:14:54 -070096 pw.println(" Toggles whether the given wi-fi network is metered.");
Felipe Lemede4e8e32016-02-02 18:55:22 -080097 pw.println(" set restrict-background BOOLEAN");
98 pw.println(" Sets the global restrict background usage status.");
Jeff Sharkey003d3e62018-03-30 14:35:04 -060099 pw.println(" set sub-plan-owner subId [packageName]");
100 pw.println(" Sets the data plan owner package for subId.");
Felipe Leme50a235e2016-01-15 18:37:06 -0800101 }
102
103 private int runGet() throws RemoteException {
104 final PrintWriter pw = getOutPrintWriter();
105 final String type = getNextArg();
106 if (type == null) {
107 pw.println("Error: didn't specify type of data to get");
108 return -1;
109 }
110 switch(type) {
111 case "restrict-background":
Felipe Leme9778f762016-01-27 14:46:39 -0800112 return getRestrictBackground();
Felipe Leme50a235e2016-01-15 18:37:06 -0800113 }
114 pw.println("Error: unknown get type '" + type + "'");
115 return -1;
116 }
117
118 private int runSet() throws RemoteException {
119 final PrintWriter pw = getOutPrintWriter();
120 final String type = getNextArg();
121 if (type == null) {
122 pw.println("Error: didn't specify type of data to set");
123 return -1;
124 }
125 switch(type) {
Felipe Lemede4e8e32016-02-02 18:55:22 -0800126 case "metered-network":
Felipe Lemeb1a65ee2016-02-08 10:12:01 -0800127 return setMeteredWifiNetwork();
Felipe Leme50a235e2016-01-15 18:37:06 -0800128 case "restrict-background":
Felipe Leme9778f762016-01-27 14:46:39 -0800129 return setRestrictBackground();
Jeff Sharkey003d3e62018-03-30 14:35:04 -0600130 case "sub-plan-owner":
131 return setSubPlanOwner();
Felipe Leme50a235e2016-01-15 18:37:06 -0800132 }
133 pw.println("Error: unknown set type '" + type + "'");
134 return -1;
135 }
136
137 private int runList() throws RemoteException {
138 final PrintWriter pw = getOutPrintWriter();
139 final String type = getNextArg();
140 if (type == null) {
141 pw.println("Error: didn't specify type of data to list");
142 return -1;
143 }
144 switch(type) {
Felipe Lemeb9aee90a2016-03-30 16:14:54 -0700145 case "wifi-networks":
146 return listWifiNetworks();
Felipe Leme50a235e2016-01-15 18:37:06 -0800147 case "restrict-background-whitelist":
Felipe Lemeb1a65ee2016-02-08 10:12:01 -0800148 return listRestrictBackgroundWhitelist();
Felipe Leme9982b302016-03-01 13:40:31 -0800149 case "restrict-background-blacklist":
150 return listRestrictBackgroundBlacklist();
Felipe Leme50a235e2016-01-15 18:37:06 -0800151 }
152 pw.println("Error: unknown list type '" + type + "'");
153 return -1;
154 }
155
156 private int runAdd() throws RemoteException {
157 final PrintWriter pw = getOutPrintWriter();
158 final String type = getNextArg();
159 if (type == null) {
160 pw.println("Error: didn't specify type of data to add");
161 return -1;
162 }
163 switch(type) {
164 case "restrict-background-whitelist":
165 return addRestrictBackgroundWhitelist();
Felipe Leme9982b302016-03-01 13:40:31 -0800166 case "restrict-background-blacklist":
167 return addRestrictBackgroundBlacklist();
Felipe Leme50a235e2016-01-15 18:37:06 -0800168 }
169 pw.println("Error: unknown add type '" + type + "'");
170 return -1;
171 }
172
173 private int runRemove() throws RemoteException {
174 final PrintWriter pw = getOutPrintWriter();
175 final String type = getNextArg();
176 if (type == null) {
177 pw.println("Error: didn't specify type of data to remove");
178 return -1;
179 }
180 switch(type) {
181 case "restrict-background-whitelist":
182 return removeRestrictBackgroundWhitelist();
Felipe Leme9982b302016-03-01 13:40:31 -0800183 case "restrict-background-blacklist":
184 return removeRestrictBackgroundBlacklist();
Felipe Leme50a235e2016-01-15 18:37:06 -0800185 }
186 pw.println("Error: unknown remove type '" + type + "'");
187 return -1;
188 }
189
Felipe Leme57e3d312016-08-23 14:42:52 -0700190 private int listUidPolicies(String msg, int policy) throws RemoteException {
Felipe Leme50a235e2016-01-15 18:37:06 -0800191 final PrintWriter pw = getOutPrintWriter();
Felipe Leme57e3d312016-08-23 14:42:52 -0700192 final int[] uids = mInterface.getUidsWithPolicy(policy);
193 pw.print(msg); pw.print(": ");
Felipe Leme50a235e2016-01-15 18:37:06 -0800194 if (uids.length == 0) {
195 pw.println("none");
196 } else {
197 for (int i = 0; i < uids.length; i++) {
198 int uid = uids[i];
199 pw.print(uid);
200 pw.print(' ');
201 }
202 }
203 pw.println();
204 return 0;
205 }
206
Felipe Leme57e3d312016-08-23 14:42:52 -0700207 private int listRestrictBackgroundWhitelist() throws RemoteException {
208 return listUidPolicies("Restrict background whitelisted UIDs",
209 POLICY_ALLOW_METERED_BACKGROUND);
210 }
Felipe Leme9982b302016-03-01 13:40:31 -0800211
Felipe Leme57e3d312016-08-23 14:42:52 -0700212 private int listRestrictBackgroundBlacklist() throws RemoteException {
213 return listUidPolicies("Restrict background blacklisted UIDs",
214 POLICY_REJECT_METERED_BACKGROUND);
Felipe Leme9982b302016-03-01 13:40:31 -0800215 }
216
Felipe Leme9778f762016-01-27 14:46:39 -0800217 private int getRestrictBackground() throws RemoteException {
Felipe Leme50a235e2016-01-15 18:37:06 -0800218 final PrintWriter pw = getOutPrintWriter();
219 pw.print("Restrict background status: ");
220 pw.println(mInterface.getRestrictBackground() ? "enabled" : "disabled");
221 return 0;
222 }
223
Felipe Leme9778f762016-01-27 14:46:39 -0800224 private int setRestrictBackground() throws RemoteException {
Felipe Leme50a235e2016-01-15 18:37:06 -0800225 final int enabled = getNextBooleanArg();
226 if (enabled < 0) {
227 return enabled;
228 }
Felipe Leme6a05eee2016-02-19 14:43:51 -0800229 mInterface.setRestrictBackground(enabled > 0);
Felipe Leme50a235e2016-01-15 18:37:06 -0800230 return 0;
231 }
232
Jeff Sharkey003d3e62018-03-30 14:35:04 -0600233 private int setSubPlanOwner() throws RemoteException {
234 final int subId = Integer.parseInt(getNextArgRequired());
235 final String packageName = getNextArg();
236 mInterface.setSubscriptionPlansOwner(subId, packageName);
237 return 0;
238 }
239
Felipe Leme57e3d312016-08-23 14:42:52 -0700240 private int setUidPolicy(int policy) throws RemoteException {
Felipe Leme50a235e2016-01-15 18:37:06 -0800241 final int uid = getUidFromNextArg();
242 if (uid < 0) {
243 return uid;
244 }
Felipe Leme57e3d312016-08-23 14:42:52 -0700245 mInterface.setUidPolicy(uid, policy);
Felipe Leme50a235e2016-01-15 18:37:06 -0800246 return 0;
247 }
248
Felipe Leme57e3d312016-08-23 14:42:52 -0700249 private int resetUidPolicy(String errorMessage, int expectedPolicy) throws RemoteException {
Felipe Leme9982b302016-03-01 13:40:31 -0800250 final int uid = getUidFromNextArg();
251 if (uid < 0) {
252 return uid;
253 }
Felipe Leme57e3d312016-08-23 14:42:52 -0700254 int actualPolicy = mInterface.getUidPolicy(uid);
255 if (actualPolicy != expectedPolicy) {
256 final PrintWriter pw = getOutPrintWriter();
257 pw.print("Error: UID "); pw.print(uid); pw.print(' '); pw.println(errorMessage);
258 return -1;
Felipe Leme9982b302016-03-01 13:40:31 -0800259 }
260 mInterface.setUidPolicy(uid, POLICY_NONE);
261 return 0;
262 }
263
Felipe Leme57e3d312016-08-23 14:42:52 -0700264 private int addRestrictBackgroundWhitelist() throws RemoteException {
265 return setUidPolicy(POLICY_ALLOW_METERED_BACKGROUND);
266 }
267
268 private int removeRestrictBackgroundWhitelist() throws RemoteException {
269 return resetUidPolicy("not whitelisted", POLICY_ALLOW_METERED_BACKGROUND);
270 }
271
272 private int addRestrictBackgroundBlacklist() throws RemoteException {
273 return setUidPolicy(POLICY_REJECT_METERED_BACKGROUND);
274 }
275
276 private int removeRestrictBackgroundBlacklist() throws RemoteException {
277 return resetUidPolicy("not blacklisted", POLICY_REJECT_METERED_BACKGROUND);
278 }
279
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600280 private int listWifiNetworks() {
Felipe Lemede4e8e32016-02-02 18:55:22 -0800281 final PrintWriter pw = getOutPrintWriter();
282 final String arg = getNextArg();
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600283 final int match;
284 if (arg == null) {
285 match = WifiConfiguration.METERED_OVERRIDE_NONE;
286 } else if (Boolean.parseBoolean(arg)) {
287 match = WifiConfiguration.METERED_OVERRIDE_METERED;
288 } else {
289 match = WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
290 }
291
292 final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
293 for (WifiConfiguration config : configs) {
294 if (arg == null || config.meteredOverride == match) {
295 pw.print(NetworkPolicyManager.resolveNetworkId(config));
296 pw.print(';');
297 pw.println(overrideToString(config.meteredOverride));
Felipe Lemede4e8e32016-02-02 18:55:22 -0800298 }
Felipe Lemede4e8e32016-02-02 18:55:22 -0800299 }
300 return 0;
301 }
302
Felipe Lemeb1a65ee2016-02-08 10:12:01 -0800303 private int setMeteredWifiNetwork() throws RemoteException {
Felipe Lemede4e8e32016-02-02 18:55:22 -0800304 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600305 final String networkId = getNextArg();
306 if (networkId == null) {
307 pw.println("Error: didn't specify networkId");
Felipe Lemede4e8e32016-02-02 18:55:22 -0800308 return -1;
309 }
310 final String arg = getNextArg();
311 if (arg == null) {
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600312 pw.println("Error: didn't specify meteredOverride");
Felipe Lemede4e8e32016-02-02 18:55:22 -0800313 return -1;
314 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600315 mInterface.setWifiMeteredOverride(NetworkPolicyManager.resolveNetworkId(networkId),
316 stringToOverride(arg));
Felipe Leme70f30ec2016-09-27 17:31:09 -0700317 return -1;
Felipe Lemede4e8e32016-02-02 18:55:22 -0800318 }
319
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600320 private static String overrideToString(int override) {
321 switch (override) {
322 case WifiConfiguration.METERED_OVERRIDE_METERED: return "true";
323 case WifiConfiguration.METERED_OVERRIDE_NOT_METERED: return "false";
324 default: return "none";
Felipe Lemeb1a65ee2016-02-08 10:12:01 -0800325 }
Felipe Lemeb1a65ee2016-02-08 10:12:01 -0800326 }
327
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600328 private static int stringToOverride(String override) {
329 switch (override) {
330 case "true": return WifiConfiguration.METERED_OVERRIDE_METERED;
331 case "false": return WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
332 default: return WifiConfiguration.METERED_OVERRIDE_NONE;
333 }
Felipe Lemede4e8e32016-02-02 18:55:22 -0800334 }
335
Felipe Leme50a235e2016-01-15 18:37:06 -0800336 private int getNextBooleanArg() {
337 final PrintWriter pw = getOutPrintWriter();
338 final String arg = getNextArg();
339 if (arg == null) {
340 pw.println("Error: didn't specify BOOLEAN");
341 return -1;
342 }
343 return Boolean.valueOf(arg) ? 1 : 0;
344 }
345
346 private int getUidFromNextArg() {
347 final PrintWriter pw = getOutPrintWriter();
348 final String arg = getNextArg();
349 if (arg == null) {
350 pw.println("Error: didn't specify UID");
351 return -1;
352 }
353 try {
354 return Integer.parseInt(arg);
355 } catch (NumberFormatException e) {
356 pw.println("Error: UID (" + arg + ") should be a number");
357 return -2;
358 }
359 }
360}