• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 com.android.server.wifi.util;
18 
19 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
20 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
21 
22 import android.annotation.NonNull;
23 import android.app.ActivityManager;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.PackageManager;
26 import android.os.Process;
27 import android.os.UserHandle;
28 import android.os.WorkSource;
29 import android.util.Log;
30 
31 /**
32  * Class for wrapping a WorkSource object and providing some (wifi specific) utility methods.
33  *
34  * This is primarily used in {@link com.android.server.wifi.HalDeviceManager} class.
35  */
36 public class WorkSourceHelper {
37     private static final String TAG = "WorkSourceHelper";
38     private static final int APP_INFO_FLAGS_SYSTEM_APP =
39             ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
40     private final WorkSource mWorkSource;
41     private final WifiPermissionsUtil mWifiPermissionsUtil;
42     private final ActivityManager mActivityManager;
43     private final PackageManager mPackageManager;
44 
WorkSourceHelper( @onNull WorkSource workSource, @NonNull WifiPermissionsUtil wifiPermissionsUtil, @NonNull ActivityManager activityManager, @NonNull PackageManager packageManager)45     public WorkSourceHelper(
46             @NonNull WorkSource workSource,
47             @NonNull WifiPermissionsUtil wifiPermissionsUtil,
48             @NonNull ActivityManager activityManager,
49             @NonNull PackageManager packageManager) {
50         mWorkSource = workSource;
51         mWifiPermissionsUtil = wifiPermissionsUtil;
52         mActivityManager = activityManager;
53         mPackageManager = packageManager;
54     }
55 
56     @Override
toString()57     public String toString() {
58         return mWorkSource.toString();
59     }
60 
isPrivileged(int uid)61     private boolean isPrivileged(int uid) {
62         return mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
63                 || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)
64                 || mWifiPermissionsUtil.checkNetworkStackPermission(uid)
65                 || mWifiPermissionsUtil.checkMainlineNetworkStackPermission(uid);
66     }
67 
68     /**
69      * Returns whether any of the one or more worksource objects contains a privileged app
70      * request.
71      *
72      * Privileged = Request from an app with NETWORK_SETTINGS, NETWORK_SETUP_WIZARD or
73      * NETWORK_STACK permissions.
74      */
hasAnyPrivilegedAppRequest()75     public boolean hasAnyPrivilegedAppRequest() {
76         for (int i = 0; i < mWorkSource.size(); i++) {
77             if (isPrivileged(mWorkSource.getUid(i))) return true;
78         }
79         return false;
80     }
81 
isSystem(String packageName, int uid)82     private boolean isSystem(String packageName, int uid) {
83         // when checking ActiveModeWarden#INTERNAL_REQUESTOR_WS
84         if (packageName == null) {
85             return false;
86         }
87         try {
88             ApplicationInfo info = mPackageManager.getApplicationInfoAsUser(
89                     packageName, 0, UserHandle.getUserHandleForUid(uid));
90             return (info.flags & APP_INFO_FLAGS_SYSTEM_APP) != 0;
91         } catch (PackageManager.NameNotFoundException e) {
92             Log.e(TAG, "Failed to retrieve app info for packageName=" + packageName + " uid=" + uid,
93                     e);
94             // In case of exception, assume unknown app (more strict checking)
95             // Note: This case will never happen since checkPackage is
96             // called to verify validity before checking App's version.
97             return false;
98         }
99     }
100 
101     /**
102      * Returns whether any of the one or more worksource objects contains a system app
103      * request.
104      */
hasAnySystemAppRequest()105     public boolean hasAnySystemAppRequest() {
106         for (int i = 0; i < mWorkSource.size(); i++) {
107             if (isSystem(mWorkSource.getPackageName(i), mWorkSource.getUid(i))) return true;
108         }
109         return false;
110     }
111 
112     /**
113      * Check if the request comes from foreground app.
114      */
isForegroundApp(@onNull String requestorPackageName)115     private boolean isForegroundApp(@NonNull String requestorPackageName) {
116         try {
117             return mActivityManager.getPackageImportance(requestorPackageName)
118                     <= IMPORTANCE_FOREGROUND;
119         } catch (SecurityException e) {
120             Log.e(TAG, "Failed to check the app state", e);
121             return false;
122         }
123     }
124 
125     /**
126      * Returns whether any of the one or more worksource objects contains a foreground app
127      * request.
128      */
hasAnyForegroundAppRequest()129     public boolean hasAnyForegroundAppRequest() {
130         for (int i = 0; i < mWorkSource.size(); i++) {
131             if (isForegroundApp(mWorkSource.getPackageName(i))) return true;
132         }
133         return false;
134     }
135 
136     /**
137      * Check if the request comes from foreground service.
138      */
isForegroundService(@onNull String requestorPackageName)139     private boolean isForegroundService(@NonNull String requestorPackageName) {
140         try {
141             int importance = mActivityManager.getPackageImportance(requestorPackageName);
142             return IMPORTANCE_FOREGROUND < importance
143                     && importance <= IMPORTANCE_FOREGROUND_SERVICE;
144         } catch (SecurityException e) {
145             Log.e(TAG, "Failed to check the app state", e);
146             return false;
147         }
148     }
149 
150     /**
151      * Returns whether any of the one or more worksource objects contains a foreground service
152      * request.
153      */
hasAnyForegroundServiceRequest()154     public boolean hasAnyForegroundServiceRequest() {
155         for (int i = 0; i < mWorkSource.size(); i++) {
156             if (isForegroundService(mWorkSource.getPackageName(i))) return true;
157         }
158         return false;
159     }
160 
161     /**
162      * Returns whether any of the one or more worksource objects contains an internal
163      * (i.e uid = Process.WIFI_UID) request.
164      */
hasAnyInternalRequest()165     public boolean hasAnyInternalRequest() {
166         for (int i = 0; i < mWorkSource.size(); i++) {
167             if (mWorkSource.getUid(i) == Process.WIFI_UID) return true;
168         }
169         return false;
170     }
171 }
172