1c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline/* 2c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * Copyright (C) 2016 The Android Open Source Project 3c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * 4c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * Licensed under the Apache License, Version 2.0 (the "License"); 5c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * you may not use this file except in compliance with the License. 6c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * You may obtain a copy of the License at 7c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * 8c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * http://www.apache.org/licenses/LICENSE-2.0 9c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * 10c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * Unless required by applicable law or agreed to in writing, software 11c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * distributed under the License is distributed on an "AS IS" BASIS, 12c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * See the License for the specific language governing permissions and 14c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * limitations under the License. 15c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline */ 16c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline 17c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Klinepackage android.net.util; 18c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline 19c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Klineimport android.net.INetd; 20af39244a34f4449c12a5f925222c9bc8d8049320Erik Klineimport android.os.RemoteException; 21c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Klineimport android.os.ServiceManager; 22af39244a34f4449c12a5f925222c9bc8d8049320Erik Klineimport android.os.ServiceSpecificException; 23af39244a34f4449c12a5f925222c9bc8d8049320Erik Klineimport android.os.SystemClock; 24c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Klineimport android.util.Log; 25c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline 26c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline 27c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline/** 28c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * @hide 29c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline */ 30c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Klinepublic class NetdService { 31c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline private static final String TAG = NetdService.class.getSimpleName(); 32c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline private static final String NETD_SERVICE_NAME = "netd"; 33af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline private static final long BASE_TIMEOUT_MS = 100; 34af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline private static final long MAX_TIMEOUT_MS = 1000; 35af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline 36c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline 37c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline /** 38af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * Return an INetd instance, or null if not available. 39af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * 40c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * It is the caller's responsibility to check for a null return value 41c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * and to handle RemoteException errors from invocations on the returned 42c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * interface if, for example, netd dies and is restarted. 43c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * 44af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * Returned instances of INetd should not be cached. 45af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * 46c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline * @return an INetd instance or null. 47c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline */ 48c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline public static INetd getInstance() { 49af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline // NOTE: ServiceManager does no caching for the netd service, 50af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline // because netd is not one of the defined common services. 51c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline final INetd netdInstance = INetd.Stub.asInterface( 52c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline ServiceManager.getService(NETD_SERVICE_NAME)); 53c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline if (netdInstance == null) { 54c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline Log.w(TAG, "WARNING: returning null INetd instance."); 55c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline } 56c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline return netdInstance; 57c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline } 58af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline 59af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline /** 60af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * Blocks for a specified time until an INetd instance is available. 61af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * 62af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * It is the caller's responsibility to handle RemoteException errors 63af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * from invocations on the returned interface if, for example, netd 64af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * dies after this interface was returned. 65af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * 66af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * Returned instances of INetd should not be cached. 67af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * 68af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * Special values of maxTimeoutMs include: 0, meaning try to obtain an 69af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * INetd instance only once, and -1 (or any value less than 0), meaning 70af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * try to obtain an INetd instance indefinitely. 71af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * 72af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * @param maxTimeoutMs the maximum time to spend getting an INetd instance 73af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * @return an INetd instance or null if no instance is available 74af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * within |maxTimeoutMs| milliseconds. 75af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline */ 76af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline public static INetd get(long maxTimeoutMs) { 77af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline if (maxTimeoutMs == 0) return getInstance(); 78af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline 79af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline final long stop = (maxTimeoutMs > 0) 80af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline ? SystemClock.elapsedRealtime() + maxTimeoutMs 81af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline : Long.MAX_VALUE; 82af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline 83af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline long timeoutMs = 0; 84af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline while (true) { 85af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline final INetd netdInstance = getInstance(); 86af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline if (netdInstance != null) { 87af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline return netdInstance; 88af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } 89af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline 90af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline final long remaining = stop - SystemClock.elapsedRealtime(); 91af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline if (remaining <= 0) break; 92af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline 93af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline // No netdInstance was received; sleep and retry. 94af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline timeoutMs = Math.min(timeoutMs + BASE_TIMEOUT_MS, MAX_TIMEOUT_MS); 95af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline timeoutMs = Math.min(timeoutMs, remaining); 96af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline try { 97af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline Thread.sleep(timeoutMs); 98af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } catch (InterruptedException e) {} 99af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } 100af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline return null; 101af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } 102af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline 103af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline /** 104af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * Blocks until an INetd instance is available. 105af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * 106af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * It is the caller's responsibility to handle RemoteException errors 107af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * from invocations on the returned interface if, for example, netd 108af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * dies after this interface was returned. 109af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * 110af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * Returned instances of INetd should not be cached. 111af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * 112af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * @return an INetd instance. 113af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline */ 114af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline public static INetd get() { 115af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline return get(-1); 116af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } 117af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline 118af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline public static interface NetdCommand { 119af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline void run(INetd netd) throws RemoteException; 120af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } 121af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline 122af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline /** 123af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * Blocks until an INetd instance is availabe, and retries until either 124af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline * the command succeeds or a runtime exception is thrown. 125af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline */ 126af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline public static void run(NetdCommand cmd) { 127af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline while (true) { 128af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline try { 129af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline cmd.run(get()); 130af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline return; 131af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } catch (RemoteException re) { 132af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline Log.e(TAG, "error communicating with netd: " + re); 133af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } 134af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } 135af39244a34f4449c12a5f925222c9bc8d8049320Erik Kline } 136c1bc0be161f5be3b7f26938fc163cf6f6778b753Erik Kline} 137