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