1 /* 2 * Copyright (C) 2018 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 package android.net; 17 18 import static android.Manifest.permission.NETWORK_STACK; 19 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.SystemApi; 24 import android.annotation.TestApi; 25 import android.content.Context; 26 import android.os.IBinder; 27 import android.os.ServiceManager; 28 29 import java.util.ArrayList; 30 import java.util.Arrays; 31 /** 32 * Constants and utilities for client code communicating with the network stack service. 33 * @hide 34 */ 35 @SystemApi 36 @TestApi 37 public class NetworkStack { 38 /** 39 * Permission granted only to the NetworkStack APK, defined in NetworkStackStub with signature 40 * protection level. 41 * @hide 42 */ 43 @SystemApi 44 @TestApi 45 public static final String PERMISSION_MAINLINE_NETWORK_STACK = 46 "android.permission.MAINLINE_NETWORK_STACK"; 47 48 @Nullable 49 private static volatile IBinder sMockService; 50 51 /** 52 * Get an {@link IBinder} representing the NetworkStack stable AIDL Interface, if registered. 53 * @hide 54 */ 55 @Nullable 56 @SystemApi 57 @TestApi getService()58 public static IBinder getService() { 59 final IBinder mockService = sMockService; 60 if (mockService != null) return mockService; 61 return ServiceManager.getService(Context.NETWORK_STACK_SERVICE); 62 } 63 64 /** 65 * Set a mock service for testing, to be returned by future calls to {@link #getService()}. 66 * 67 * <p>Passing a {@code null} {@code mockService} resets {@link #getService()} to normal 68 * behavior. 69 * @hide 70 */ 71 @TestApi setServiceForTest(@ullable IBinder mockService)72 public static void setServiceForTest(@Nullable IBinder mockService) { 73 sMockService = mockService; 74 } 75 NetworkStack()76 private NetworkStack() {} 77 78 /** 79 * If the NetworkStack, MAINLINE_NETWORK_STACK are not allowed for a particular process, throw a 80 * {@link SecurityException}. 81 * 82 * @param context {@link android.content.Context} for the process. 83 * 84 * @hide 85 */ checkNetworkStackPermission(final @NonNull Context context)86 public static void checkNetworkStackPermission(final @NonNull Context context) { 87 checkNetworkStackPermissionOr(context); 88 } 89 90 /** 91 * If the NetworkStack, MAINLINE_NETWORK_STACK or other specified permissions are not allowed 92 * for a particular process, throw a {@link SecurityException}. 93 * 94 * @param context {@link android.content.Context} for the process. 95 * @param otherPermissions The set of permissions that could be the candidate permissions , or 96 * empty string if none of other permissions needed. 97 * @hide 98 */ checkNetworkStackPermissionOr(final @NonNull Context context, final @NonNull String... otherPermissions)99 public static void checkNetworkStackPermissionOr(final @NonNull Context context, 100 final @NonNull String... otherPermissions) { 101 ArrayList<String> permissions = new ArrayList<String>(Arrays.asList(otherPermissions)); 102 permissions.add(NETWORK_STACK); 103 permissions.add(PERMISSION_MAINLINE_NETWORK_STACK); 104 enforceAnyPermissionOf(context, permissions.toArray(new String[0])); 105 } 106 enforceAnyPermissionOf(final @NonNull Context context, final @NonNull String... permissions)107 private static void enforceAnyPermissionOf(final @NonNull Context context, 108 final @NonNull String... permissions) { 109 if (!checkAnyPermissionOf(context, permissions)) { 110 throw new SecurityException("Requires one of the following permissions: " 111 + String.join(", ", permissions) + "."); 112 } 113 } 114 checkAnyPermissionOf(final @NonNull Context context, final @NonNull String... permissions)115 private static boolean checkAnyPermissionOf(final @NonNull Context context, 116 final @NonNull String... permissions) { 117 for (String permission : permissions) { 118 if (context.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) { 119 return true; 120 } 121 } 122 return false; 123 } 124 125 } 126