120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti/* 220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * Copyright (C) 2014 The Android Open Source Project 320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * 420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License"); 520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * you may not use this file except in compliance with the License. 620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * You may obtain a copy of the License at 720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * 820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * http://www.apache.org/licenses/LICENSE-2.0 920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * 1020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * Unless required by applicable law or agreed to in writing, software 1120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS, 1220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * See the License for the specific language governing permissions and 1420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * limitations under the License. 1520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti */ 1620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 1720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittipackage com.android.server.ethernet; 1820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 1920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.content.Context; 2020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.content.pm.PackageManager; 2120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.IEthernetManager; 22a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kimimport android.net.IEthernetServiceListener; 2320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.IpConfiguration; 2420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.Binder; 2520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.Handler; 2620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.HandlerThread; 2720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.RemoteException; 2820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.util.Log; 2920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.util.PrintWriterPrinter; 3020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 31a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kimimport com.android.internal.util.IndentingPrintWriter; 32a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim 3320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport java.io.FileDescriptor; 3420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport java.io.PrintWriter; 3520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport java.util.concurrent.atomic.AtomicBoolean; 3620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 3720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti/** 3820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * EthernetServiceImpl handles remote Ethernet operation requests by implementing 3920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * the IEthernetManager interface. 4020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti */ 4120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittipublic class EthernetServiceImpl extends IEthernetManager.Stub { 4220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private static final String TAG = "EthernetServiceImpl"; 4320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 4420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private final Context mContext; 4520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private final AtomicBoolean mStarted = new AtomicBoolean(false); 4620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 4720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private Handler mHandler; 48caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev private EthernetTracker mTracker; 4920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 5020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti public EthernetServiceImpl(Context context) { 5120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mContext = context; 5220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 5320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 5420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private void enforceAccessPermission() { 5520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mContext.enforceCallingOrSelfPermission( 5620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti android.Manifest.permission.ACCESS_NETWORK_STATE, 5720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti "EthernetService"); 5820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 5920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 6020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private void enforceConnectivityInternalPermission() { 6120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mContext.enforceCallingOrSelfPermission( 6220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti android.Manifest.permission.CONNECTIVITY_INTERNAL, 6320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti "ConnectivityService"); 6420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 6520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 66caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev private void enforceUseRestrictedNetworksPermission() { 67caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev mContext.enforceCallingOrSelfPermission( 68caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS, 69caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev "ConnectivityService"); 70caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev } 71caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev 72caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev private boolean checkUseRestrictedNetworksPermission() { 73caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev return mContext.checkCallingOrSelfPermission( 74caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS) 75caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev == PackageManager.PERMISSION_GRANTED; 76caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev } 77caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev 7820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti public void start() { 7920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.i(TAG, "Starting Ethernet service"); 8020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 8120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti HandlerThread handlerThread = new HandlerThread("EthernetServiceThread"); 8220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti handlerThread.start(); 8320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mHandler = new Handler(handlerThread.getLooper()); 8420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 85caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev mTracker = new EthernetTracker(mContext, mHandler); 86caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev mTracker.start(); 8720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 8820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mStarted.set(true); 8920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 9020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 91caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev @Override 92caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev public String[] getAvailableInterfaces() throws RemoteException { 93caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev return mTracker.getInterfaces(checkUseRestrictedNetworksPermission()); 94caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev } 95caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev 9620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti /** 9720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * Get Ethernet configuration 9820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * @return the Ethernet Configuration, contained in {@link IpConfiguration}. 9920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti */ 100a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim @Override 101caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev public IpConfiguration getConfiguration(String iface) { 10220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti enforceAccessPermission(); 10320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 104caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev if (mTracker.isRestrictedInterface(iface)) { 105caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev enforceUseRestrictedNetworksPermission(); 10620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 107caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev 108caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev return new IpConfiguration(mTracker.getIpConfiguration(iface)); 10920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 11020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 11120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti /** 11220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * Set Ethernet configuration 11320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti */ 114a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim @Override 115caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev public void setConfiguration(String iface, IpConfiguration config) { 11620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti if (!mStarted.get()) { 11720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.w(TAG, "System isn't ready enough to change ethernet configuration"); 11820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 11920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 12020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti enforceConnectivityInternalPermission(); 12120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 122caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev if (mTracker.isRestrictedInterface(iface)) { 123caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev enforceUseRestrictedNetworksPermission(); 12420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 125caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev 126caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev // TODO: this does not check proxy settings, gateways, etc. 127caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev // Fix this by making IpConfiguration a complete representation of static configuration. 128caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev mTracker.updateIpConfiguration(iface, new IpConfiguration(config)); 12920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 130a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim 131a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim /** 132caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev * Indicates whether given interface is available. 133a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim */ 134a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim @Override 135caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev public boolean isAvailable(String iface) { 136a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim enforceAccessPermission(); 137caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev 138caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev if (mTracker.isRestrictedInterface(iface)) { 139caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev enforceUseRestrictedNetworksPermission(); 140caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev } 141caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev 142caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev return mTracker.isTrackingInterface(iface); 143a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 144a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim 145a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim /** 146caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev * Adds a listener. 147a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim * @param listener A {@link IEthernetServiceListener} to add. 148a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim */ 149a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim public void addListener(IEthernetServiceListener listener) { 150a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim if (listener == null) { 151a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim throw new IllegalArgumentException("listener must not be null"); 152a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 153a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim enforceAccessPermission(); 154caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev mTracker.addListener(listener, checkUseRestrictedNetworksPermission()); 155a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 156a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim 157a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim /** 158a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim * Removes a listener. 159a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim * @param listener A {@link IEthernetServiceListener} to remove. 160a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim */ 161a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim public void removeListener(IEthernetServiceListener listener) { 162a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim if (listener == null) { 163a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim throw new IllegalArgumentException("listener must not be null"); 164a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 165a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim enforceAccessPermission(); 166caf5246eb0ad453bc1a1707ce69fab3502b7dccbPavel Maltsev mTracker.removeListener(listener); 167a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 16820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 16920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti @Override 17020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 17120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 17220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 17320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti != PackageManager.PERMISSION_GRANTED) { 17420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti pw.println("Permission Denial: can't dump EthernetService from pid=" 17520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti + Binder.getCallingPid() 17620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti + ", uid=" + Binder.getCallingUid()); 17720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti return; 17820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 17920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 180aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.println("Current Ethernet state: "); 181aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.increaseIndent(); 182aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti mTracker.dump(fd, pw, args); 183aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.decreaseIndent(); 184aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti 18520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti pw.println("Handler:"); 18620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti pw.increaseIndent(); 18720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mHandler.dump(new PrintWriterPrinter(pw), "EthernetServiceImpl"); 18820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti pw.decreaseIndent(); 18920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 19020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti} 191