blob: 456f2f7f27f5978c96d4e8592a458f063ac88978 [file] [log] [blame]
/*
* Copyright (C) 2019 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 com.android.server.connectivity.tethering;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.ITetherInternalCallback;
import android.net.ITetheringConnector;
import android.net.NetworkRequest;
import android.net.util.SharedLog;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.ResultReceiver;
import android.os.SystemProperties;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import java.io.FileDescriptor;
import java.io.PrintWriter;
/**
* Android service used to manage tethering.
*
* <p>The service returns a binder for the system server to communicate with the tethering.
*/
public class TetheringService extends Service {
private static final String TAG = TetheringService.class.getSimpleName();
private final SharedLog mLog = new SharedLog(TAG);
private TetheringConnector mConnector;
private Context mContext;
private TetheringDependencies mDeps;
private Tethering mTethering;
@Override
public void onCreate() {
mLog.mark("onCreate");
mDeps = getTetheringDependencies();
mContext = mDeps.getContext();
mTethering = makeTethering(mDeps);
}
/**
* Make a reference to Tethering object.
*/
@VisibleForTesting
public Tethering makeTethering(TetheringDependencies deps) {
return new Tethering(deps);
}
/**
* Create a binder connector for the system server to communicate with the tethering.
*/
private synchronized IBinder makeConnector() {
if (mConnector == null) {
mConnector = new TetheringConnector(mTethering);
}
return mConnector;
}
@NonNull
@Override
public IBinder onBind(Intent intent) {
mLog.mark("onBind");
return makeConnector();
}
private static class TetheringConnector extends ITetheringConnector.Stub {
private final Tethering mService;
TetheringConnector(Tethering tether) {
mService = tether;
}
@Override
public void tether(String iface) {
mService.tether(iface);
}
@Override
public void untether(String iface) {
mService.untether(iface);
}
@Override
public void setUsbTethering(boolean enable) {
mService.setUsbTethering(enable);
}
@Override
public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
mService.startTethering(type, receiver, showProvisioningUi);
}
@Override
public void stopTethering(int type) {
mService.stopTethering(type);
}
@Override
public void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
boolean showEntitlementUi) {
mService.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
}
@Override
public void registerTetherInternalCallback(ITetherInternalCallback callback) {
mService.registerTetherInternalCallback(callback);
}
}
@Override
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
@Nullable String[] args) {
mTethering.dump(fd, writer, args);
}
/**
* An injection method for testing.
*/
@VisibleForTesting
public TetheringDependencies getTetheringDependencies() {
if (mDeps == null) {
mDeps = new TetheringDependencies() {
@Override
public NetworkRequest getDefaultNetworkRequest() {
ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
return cm.getDefaultRequest();
}
@Override
public Looper getTetheringLooper() {
final HandlerThread tetherThread = new HandlerThread("android.tethering");
tetherThread.start();
return tetherThread.getLooper();
}
@Override
public boolean isTetheringSupported() {
int defaultVal =
SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
return tetherSupported;
}
@Override
public Context getContext() {
return TetheringService.this;
}
};
}
return mDeps;
}
}