Test: as follows
- built (bullhead)
- flashed
- booted
- runtest frameworks-net passes
Change-Id: I1a8e15149bf9dbedc6a09c0d8ab6abb2ef4f8fee
137 lines
4.5 KiB
Java
137 lines
4.5 KiB
Java
/*
|
|
* Copyright (C) 2016 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.util;
|
|
|
|
import android.net.INetd;
|
|
import android.os.RemoteException;
|
|
import android.os.ServiceManager;
|
|
import android.os.ServiceSpecificException;
|
|
import android.os.SystemClock;
|
|
import android.util.Log;
|
|
|
|
|
|
/**
|
|
* @hide
|
|
*/
|
|
public class NetdService {
|
|
private static final String TAG = NetdService.class.getSimpleName();
|
|
private static final String NETD_SERVICE_NAME = "netd";
|
|
private static final long BASE_TIMEOUT_MS = 100;
|
|
private static final long MAX_TIMEOUT_MS = 1000;
|
|
|
|
|
|
/**
|
|
* Return an INetd instance, or null if not available.
|
|
*
|
|
* It is the caller's responsibility to check for a null return value
|
|
* and to handle RemoteException errors from invocations on the returned
|
|
* interface if, for example, netd dies and is restarted.
|
|
*
|
|
* Returned instances of INetd should not be cached.
|
|
*
|
|
* @return an INetd instance or null.
|
|
*/
|
|
public static INetd getInstance() {
|
|
// NOTE: ServiceManager does no caching for the netd service,
|
|
// because netd is not one of the defined common services.
|
|
final INetd netdInstance = INetd.Stub.asInterface(
|
|
ServiceManager.getService(NETD_SERVICE_NAME));
|
|
if (netdInstance == null) {
|
|
Log.w(TAG, "WARNING: returning null INetd instance.");
|
|
}
|
|
return netdInstance;
|
|
}
|
|
|
|
/**
|
|
* Blocks for a specified time until an INetd instance is available.
|
|
*
|
|
* It is the caller's responsibility to handle RemoteException errors
|
|
* from invocations on the returned interface if, for example, netd
|
|
* dies after this interface was returned.
|
|
*
|
|
* Returned instances of INetd should not be cached.
|
|
*
|
|
* Special values of maxTimeoutMs include: 0, meaning try to obtain an
|
|
* INetd instance only once, and -1 (or any value less than 0), meaning
|
|
* try to obtain an INetd instance indefinitely.
|
|
*
|
|
* @param maxTimeoutMs the maximum time to spend getting an INetd instance
|
|
* @return an INetd instance or null if no instance is available
|
|
* within |maxTimeoutMs| milliseconds.
|
|
*/
|
|
public static INetd get(long maxTimeoutMs) {
|
|
if (maxTimeoutMs == 0) return getInstance();
|
|
|
|
final long stop = (maxTimeoutMs > 0)
|
|
? SystemClock.elapsedRealtime() + maxTimeoutMs
|
|
: Long.MAX_VALUE;
|
|
|
|
long timeoutMs = 0;
|
|
while (true) {
|
|
final INetd netdInstance = getInstance();
|
|
if (netdInstance != null) {
|
|
return netdInstance;
|
|
}
|
|
|
|
final long remaining = stop - SystemClock.elapsedRealtime();
|
|
if (remaining <= 0) break;
|
|
|
|
// No netdInstance was received; sleep and retry.
|
|
timeoutMs = Math.min(timeoutMs + BASE_TIMEOUT_MS, MAX_TIMEOUT_MS);
|
|
timeoutMs = Math.min(timeoutMs, remaining);
|
|
try {
|
|
Thread.sleep(timeoutMs);
|
|
} catch (InterruptedException e) {}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Blocks until an INetd instance is available.
|
|
*
|
|
* It is the caller's responsibility to handle RemoteException errors
|
|
* from invocations on the returned interface if, for example, netd
|
|
* dies after this interface was returned.
|
|
*
|
|
* Returned instances of INetd should not be cached.
|
|
*
|
|
* @return an INetd instance.
|
|
*/
|
|
public static INetd get() {
|
|
return get(-1);
|
|
}
|
|
|
|
public static interface NetdCommand {
|
|
void run(INetd netd) throws RemoteException;
|
|
}
|
|
|
|
/**
|
|
* Blocks until an INetd instance is availabe, and retries until either
|
|
* the command succeeds or a runtime exception is thrown.
|
|
*/
|
|
public static void run(NetdCommand cmd) {
|
|
while (true) {
|
|
try {
|
|
cmd.run(get());
|
|
return;
|
|
} catch (RemoteException re) {
|
|
Log.e(TAG, "error communicating with netd: " + re);
|
|
}
|
|
}
|
|
}
|
|
}
|