package com.android.server.connectivity.tethering;
+import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
+
+import android.content.ContentResolver;
import android.net.LinkProperties;
-import android.os.Handler;
import android.net.util.SharedLog;
+import android.os.Handler;
+import android.provider.Settings;
/**
* A class to encapsulate the business logic of programming the tethering
private final Handler mHandler;
private final OffloadHardwareInterface mHwInterface;
+ private final ContentResolver mContentResolver;
private final SharedLog mLog;
private boolean mConfigInitialized;
private boolean mControlInitialized;
private LinkProperties mUpstreamLinkProperties;
- public OffloadController(Handler h, OffloadHardwareInterface hwi, SharedLog log) {
+ public OffloadController(Handler h, OffloadHardwareInterface hwi,
+ ContentResolver contentResolver, SharedLog log) {
mHandler = h;
mHwInterface = hwi;
+ mContentResolver = contentResolver;
mLog = log.forSubComponent(TAG);
}
public void start() {
- if (started()) return;
+ if (isOffloadDisabled() || started()) return;
if (!mConfigInitialized) {
mConfigInitialized = mHwInterface.initOffloadConfig();
// TODO: public void addDownStream(...)
+ private boolean isOffloadDisabled() {
+ // Defaults to |false| if not present.
+ return (Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0) != 0);
+ }
+
private boolean started() {
return mConfigInitialized && mControlInitialized;
}
import static org.mockito.Mockito.when;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.os.RemoteException;
import android.os.test.TestLooper;
import android.os.UserHandle;
+import android.provider.Settings;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.CarrierConfigManager;
+import android.test.mock.MockContentResolver;
import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.connectivity.tethering.OffloadHardwareInterface;
import com.android.server.connectivity.tethering.TetheringDependencies;
private Vector<Intent> mIntents;
private BroadcastInterceptingContext mServiceContext;
+ private MockContentResolver mContentResolver;
private BroadcastReceiver mBroadcastReceiver;
private Tethering mTethering;
}
@Override
+ public ContentResolver getContentResolver() { return mContentResolver; }
+
+ @Override
+ public String getPackageName() { return "TetheringTest"; }
+
+ @Override
public Resources getResources() { return mResources; }
@Override
.thenReturn(new InterfaceConfiguration());
mServiceContext = new MockContext(mContext);
+ mContentResolver = new MockContentResolver(mServiceContext);
+ mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
mIntents = new Vector<>();
mBroadcastReceiver = new BroadcastReceiver() {
@Override
--- /dev/null
+/*
+ * Copyright (C) 2017 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 static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.util.SharedLog;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+import com.android.internal.util.test.FakeSettingsProvider;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class OffloadControllerTest {
+
+ @Mock private OffloadHardwareInterface mHardware;
+ @Mock private Context mContext;
+ private MockContentResolver mContentResolver;
+
+ @Before public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mContentResolver = new MockContentResolver(mContext);
+ mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ when(mContext.getPackageName()).thenReturn("OffloadControllerTest");
+ when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ }
+
+ private void setupFunctioningHardwareInterface() {
+ when(mHardware.initOffloadConfig()).thenReturn(true);
+ when(mHardware.initOffloadControl(any(OffloadHardwareInterface.ControlCallback.class)))
+ .thenReturn(true);
+ }
+
+ @Test
+ public void testNoSettingsValueAllowsStart() {
+ setupFunctioningHardwareInterface();
+ try {
+ Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED);
+ fail();
+ } catch (SettingNotFoundException expected) {}
+
+ final OffloadController offload =
+ new OffloadController(null, mHardware, mContentResolver, new SharedLog("test"));
+ offload.start();
+
+ final InOrder inOrder = inOrder(mHardware);
+ inOrder.verify(mHardware, times(1)).initOffloadConfig();
+ inOrder.verify(mHardware, times(1)).initOffloadControl(
+ any(OffloadHardwareInterface.ControlCallback.class));
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void testSettingsAllowsStart() {
+ setupFunctioningHardwareInterface();
+ Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0);
+
+ final OffloadController offload =
+ new OffloadController(null, mHardware, mContentResolver, new SharedLog("test"));
+ offload.start();
+
+ final InOrder inOrder = inOrder(mHardware);
+ inOrder.verify(mHardware, times(1)).initOffloadConfig();
+ inOrder.verify(mHardware, times(1)).initOffloadControl(
+ any(OffloadHardwareInterface.ControlCallback.class));
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void testSettingsDisablesStart() {
+ setupFunctioningHardwareInterface();
+ Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 1);
+
+ final OffloadController offload =
+ new OffloadController(null, mHardware, mContentResolver, new SharedLog("test"));
+ offload.start();
+
+ final InOrder inOrder = inOrder(mHardware);
+ inOrder.verify(mHardware, never()).initOffloadConfig();
+ inOrder.verify(mHardware, never()).initOffloadControl(anyObject());
+ inOrder.verifyNoMoreInteractions();
+ }
+}