summaryrefslogtreecommitdiff
path: root/framework/src/android/net/TestNetworkManager.java
blob: 4e78823efcf5d4abd3fcd38707a93bc157dafa83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.net;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.os.IBinder;
import android.os.RemoteException;

import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;

/**
 * Class that allows creation and management of per-app, test-only networks
 *
 * @hide
 */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public class TestNetworkManager {
    /**
     * Prefix for tun interfaces created by this class.
     * @hide
     */
    public static final String TEST_TUN_PREFIX = "testtun";

    /**
     * Prefix for tap interfaces created by this class.
     */
    public static final String TEST_TAP_PREFIX = "testtap";

    /**
     * Prefix for clat interfaces.
     * @hide
     */
    public static final String CLAT_INTERFACE_PREFIX = "v4-";

    @NonNull private static final String TAG = TestNetworkManager.class.getSimpleName();

    @NonNull private final ITestNetworkManager mService;

    private static final boolean TAP = false;
    private static final boolean TUN = true;
    private static final boolean BRING_UP = true;
    private static final LinkAddress[] NO_ADDRS = new LinkAddress[0];

    /** @hide */
    public TestNetworkManager(@NonNull ITestNetworkManager service) {
        mService = Objects.requireNonNull(service, "missing ITestNetworkManager");
    }

    /**
     * Teardown the capability-limited, testing-only network for a given interface
     *
     * @param network The test network that should be torn down
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public void teardownTestNetwork(@NonNull Network network) {
        try {
            mService.teardownTestNetwork(network.netId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private void setupTestNetwork(
            @NonNull String iface,
            @Nullable LinkProperties lp,
            boolean isMetered,
            @NonNull int[] administratorUids,
            @NonNull IBinder binder) {
        try {
            mService.setupTestNetwork(iface, lp, isMetered, administratorUids, binder);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Sets up a capability-limited, testing-only network for a given interface
     *
     * @param lp The LinkProperties for the TestNetworkService to use for this test network. Note
     *     that the interface name and link addresses will be overwritten, and the passed-in values
     *     discarded.
     * @param isMetered Whether or not the network should be considered metered.
     * @param binder A binder object guarding the lifecycle of this test network.
     * @hide
     */
    public void setupTestNetwork(
            @NonNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder) {
        Objects.requireNonNull(lp, "Invalid LinkProperties");
        setupTestNetwork(lp.getInterfaceName(), lp, isMetered, new int[0], binder);
    }

    /**
     * Sets up a capability-limited, testing-only network for a given interface
     *
     * @param iface the name of the interface to be used for the Network LinkProperties.
     * @param binder A binder object guarding the lifecycle of this test network.
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) {
        setupTestNetwork(iface, null, true, new int[0], binder);
    }

    /**
     * Sets up a capability-limited, testing-only network for a given interface with the given
     * administrator UIDs.
     *
     * @param iface the name of the interface to be used for the Network LinkProperties.
     * @param administratorUids The administrator UIDs to be used for the test-only network
     * @param binder A binder object guarding the lifecycle of this test network.
     * @hide
     */
    public void setupTestNetwork(
            @NonNull String iface, @NonNull int[] administratorUids, @NonNull IBinder binder) {
        setupTestNetwork(iface, null, true, administratorUids, binder);
    }

    /**
     * Create a tun interface for testing purposes
     *
     * @param linkAddrs an array of LinkAddresses to assign to the TUN interface
     * @return A ParcelFileDescriptor of the underlying TUN interface. Close this to tear down the
     *     TUN interface.
     * @deprecated Use {@link #createTunInterface(Collection)} instead.
     * @hide
     */
    @Deprecated
    @NonNull
    public TestNetworkInterface createTunInterface(@NonNull LinkAddress[] linkAddrs) {
        return createTunInterface(Arrays.asList(linkAddrs));
    }

    /**
     * Create a tun interface for testing purposes
     *
     * @param linkAddrs an array of LinkAddresses to assign to the TUN interface
     * @return A ParcelFileDescriptor of the underlying TUN interface. Close this to tear down the
     *     TUN interface.
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @NonNull
    public TestNetworkInterface createTunInterface(@NonNull Collection<LinkAddress> linkAddrs) {
        try {
            final LinkAddress[] arr = new LinkAddress[linkAddrs.size()];
            return mService.createInterface(TUN, BRING_UP, linkAddrs.toArray(arr),
                    null /* iface */);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Create a tap interface for testing purposes
     *
     * @return A ParcelFileDescriptor of the underlying TAP interface. Close this to tear down the
     *     TAP interface.
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @NonNull
    public TestNetworkInterface createTapInterface() {
        try {
            return mService.createInterface(TAP, BRING_UP, NO_ADDRS, null /* iface */);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Create a tap interface for testing purposes
     *
     * @param bringUp whether to bring up the interface before returning it.
     *
     * @return A ParcelFileDescriptor of the underlying TAP interface. Close this to tear down the
     *     TAP interface.
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
    @NonNull
    public TestNetworkInterface createTapInterface(boolean bringUp) {
        try {
            return mService.createInterface(TAP, bringUp, NO_ADDRS, null /* iface */);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Create a tap interface with a given interface name for testing purposes
     *
     * @param bringUp whether to bring up the interface before returning it.
     * @param iface interface name to be assigned, so far only interface name which starts with
     *              "v4-testtap" or "v4-testtun" is allowed to be created. If it's null, then use
     *              the default name(e.g. testtap or testtun).
     *
     * @return A ParcelFileDescriptor of the underlying TAP interface. Close this to tear down the
     *     TAP interface.
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
    @NonNull
    public TestNetworkInterface createTapInterface(boolean bringUp, @NonNull String iface) {
        try {
            return mService.createInterface(TAP, bringUp, NO_ADDRS, iface);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}