Home | History | Annotate | Download | only in ethernet
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.ethernet;
     18 
     19 import android.content.Context;
     20 import android.content.pm.PackageManager;
     21 import android.net.IEthernetManager;
     22 import android.net.IEthernetServiceListener;
     23 import android.net.IpConfiguration;
     24 import android.os.Binder;
     25 import android.os.Handler;
     26 import android.os.HandlerThread;
     27 import android.os.RemoteException;
     28 import android.util.Log;
     29 import android.util.PrintWriterPrinter;
     30 
     31 import com.android.internal.util.IndentingPrintWriter;
     32 
     33 import java.io.FileDescriptor;
     34 import java.io.PrintWriter;
     35 import java.util.concurrent.atomic.AtomicBoolean;
     36 
     37 /**
     38  * EthernetServiceImpl handles remote Ethernet operation requests by implementing
     39  * the IEthernetManager interface.
     40  */
     41 public class EthernetServiceImpl extends IEthernetManager.Stub {
     42     private static final String TAG = "EthernetServiceImpl";
     43 
     44     private final Context mContext;
     45     private final AtomicBoolean mStarted = new AtomicBoolean(false);
     46 
     47     private Handler mHandler;
     48     private EthernetTracker mTracker;
     49 
     50     public EthernetServiceImpl(Context context) {
     51         mContext = context;
     52     }
     53 
     54     private void enforceAccessPermission() {
     55         mContext.enforceCallingOrSelfPermission(
     56                 android.Manifest.permission.ACCESS_NETWORK_STATE,
     57                 "EthernetService");
     58     }
     59 
     60     private void enforceConnectivityInternalPermission() {
     61         mContext.enforceCallingOrSelfPermission(
     62                 android.Manifest.permission.CONNECTIVITY_INTERNAL,
     63                 "ConnectivityService");
     64     }
     65 
     66     private void enforceUseRestrictedNetworksPermission() {
     67         mContext.enforceCallingOrSelfPermission(
     68                 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS,
     69                 "ConnectivityService");
     70     }
     71 
     72     private boolean checkUseRestrictedNetworksPermission() {
     73         return mContext.checkCallingOrSelfPermission(
     74                 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS)
     75                 == PackageManager.PERMISSION_GRANTED;
     76     }
     77 
     78     public void start() {
     79         Log.i(TAG, "Starting Ethernet service");
     80 
     81         HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");
     82         handlerThread.start();
     83         mHandler = new Handler(handlerThread.getLooper());
     84 
     85         mTracker = new EthernetTracker(mContext, mHandler);
     86         mTracker.start();
     87 
     88         mStarted.set(true);
     89     }
     90 
     91     @Override
     92     public String[] getAvailableInterfaces() throws RemoteException {
     93         return mTracker.getInterfaces(checkUseRestrictedNetworksPermission());
     94     }
     95 
     96     /**
     97      * Get Ethernet configuration
     98      * @return the Ethernet Configuration, contained in {@link IpConfiguration}.
     99      */
    100     @Override
    101     public IpConfiguration getConfiguration(String iface) {
    102         enforceAccessPermission();
    103 
    104         if (mTracker.isRestrictedInterface(iface)) {
    105             enforceUseRestrictedNetworksPermission();
    106         }
    107 
    108         return new IpConfiguration(mTracker.getIpConfiguration(iface));
    109     }
    110 
    111     /**
    112      * Set Ethernet configuration
    113      */
    114     @Override
    115     public void setConfiguration(String iface, IpConfiguration config) {
    116         if (!mStarted.get()) {
    117             Log.w(TAG, "System isn't ready enough to change ethernet configuration");
    118         }
    119 
    120         enforceConnectivityInternalPermission();
    121 
    122         if (mTracker.isRestrictedInterface(iface)) {
    123             enforceUseRestrictedNetworksPermission();
    124         }
    125 
    126         // TODO: this does not check proxy settings, gateways, etc.
    127         // Fix this by making IpConfiguration a complete representation of static configuration.
    128         mTracker.updateIpConfiguration(iface, new IpConfiguration(config));
    129     }
    130 
    131     /**
    132      * Indicates whether given interface is available.
    133      */
    134     @Override
    135     public boolean isAvailable(String iface) {
    136         enforceAccessPermission();
    137 
    138         if (mTracker.isRestrictedInterface(iface)) {
    139             enforceUseRestrictedNetworksPermission();
    140         }
    141 
    142         return mTracker.isTrackingInterface(iface);
    143     }
    144 
    145     /**
    146      * Adds a listener.
    147      * @param listener A {@link IEthernetServiceListener} to add.
    148      */
    149     public void addListener(IEthernetServiceListener listener) {
    150         if (listener == null) {
    151             throw new IllegalArgumentException("listener must not be null");
    152         }
    153         enforceAccessPermission();
    154         mTracker.addListener(listener, checkUseRestrictedNetworksPermission());
    155     }
    156 
    157     /**
    158      * Removes a listener.
    159      * @param listener A {@link IEthernetServiceListener} to remove.
    160      */
    161     public void removeListener(IEthernetServiceListener listener) {
    162         if (listener == null) {
    163             throw new IllegalArgumentException("listener must not be null");
    164         }
    165         enforceAccessPermission();
    166         mTracker.removeListener(listener);
    167     }
    168 
    169     @Override
    170     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
    171         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
    172         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
    173                 != PackageManager.PERMISSION_GRANTED) {
    174             pw.println("Permission Denial: can't dump EthernetService from pid="
    175                     + Binder.getCallingPid()
    176                     + ", uid=" + Binder.getCallingUid());
    177             return;
    178         }
    179 
    180         pw.println("Current Ethernet state: ");
    181         pw.increaseIndent();
    182         mTracker.dump(fd, pw, args);
    183         pw.decreaseIndent();
    184 
    185         pw.println("Handler:");
    186         pw.increaseIndent();
    187         mHandler.dump(new PrintWriterPrinter(pw), "EthernetServiceImpl");
    188         pw.decreaseIndent();
    189     }
    190 }
    191