Snap for 6593884 from 8e50511679 to mainline-release

Change-Id: Icc03fa21a8d7506ddd3181805eefe2bf8b2387ba
This commit is contained in:
android-build-team Robot
2020-06-16 07:09:33 +00:00
19 changed files with 448 additions and 421 deletions

View File

@@ -21,6 +21,7 @@
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:minHeight="?android:attr/listPreferredItemHeight"
android:focusable="false"
android:gravity="center_vertical">
<RelativeLayout
@@ -30,13 +31,14 @@
android:gravity="center_vertical"
android:layout_weight="1"
android:focusable="true"
android:clickable="true"
android:background="?android:attr/selectableItemBackground">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:focusable="false"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceListItem" />
@@ -48,6 +50,7 @@
android:layout_alignStart="@android:id/title"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:focusable="false"
android:maxLines="2" />
</RelativeLayout>
@@ -59,6 +62,7 @@
android:layout_marginStart="8dip"
android:layout_marginEnd="8dip"
android:layout_gravity="center_vertical"
android:focusable="true"
android:clickable="true" />
</LinearLayout>

View File

@@ -14,6 +14,8 @@
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Cell Broadcast settings title. [CHAR LIMIT=50] -->
<!-- Cell Broadcast settings title. [CHAR LIMIT=50]
This settings will be shown on devices with Italian SIMs.
Required Italian (it) translation for this message: "Allarmi Pubblici" -->
<string name="cell_broadcast_settings">Public warnings</string>
</resources>

View File

@@ -2752,6 +2752,10 @@
<string name="peak_refresh_rate_title">Smooth Display</string>
<!-- Display settings screen, peak refresh rate settings summary [CHAR LIMIT=NONE] -->
<string name="peak_refresh_rate_summary">Automatically raises the refresh rate from 60 to 90 Hz for some content. Increases battery usage.</string>
<!-- Display developer settings: Force to the highest refresh rate [CHAR LIMIT=NONE] -->
<string name="force_high_refresh_rate_toggle">Smooth Display</string>
<!-- Display developer settings: Force to the highest refresh rate description [CHAR LIMIT=NONE]-->
<string name="force_high_refresh_rate_desc">Highest refresh rate for improved touch responsiveness &amp; animation quality. Increases battery usage.</string>
<!-- Display settings screen, setting option name to enable adaptive sleep [CHAR LIMIT=30] -->
<string name="adaptive_sleep_title">Screen attention</string>
<!-- Setting option summary when adaptive sleep is on [CHAR LIMIT=NONE] -->
@@ -7280,7 +7284,7 @@
<!-- Call Manager settings summary. [CHAR LIMIT=50] -->
<string name="call_manager_summary"><xliff:g id="app">%1$s</xliff:g></string>
<!-- Cell Broadcast settings title. [CHAR LIMIT=50] -->
<string name="cell_broadcast_settings">Emergency alerts</string>
<string name="cell_broadcast_settings">Wireless emergency alerts</string>
<!-- Network operators settings title. [CHAR LIMIT=50] -->
<string name="network_operators_settings">Network operators</string>
<!-- Access point names title. [CHAR LIMIT=50] -->

View File

@@ -256,6 +256,11 @@
android:title="@string/overlay_settings_title"
android:summary="@string/overlay_settings_summary" />
<SwitchPreference
android:key="pref_key_peak_refresh_rate"
android:title="@string/force_high_refresh_rate_toggle"
android:summary="@string/force_high_refresh_rate_desc" />
</PreferenceCategory>
<PreferenceCategory

View File

@@ -459,6 +459,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
controllers.add(new SelectDebugAppPreferenceController(context, fragment));
controllers.add(new WaitForDebuggerPreferenceController(context));
controllers.add(new EnableGpuDebugLayersPreferenceController(context));
controllers.add(new ForcePeakRefreshRatePreferenceController(context));
controllers.add(new EnableVerboseVendorLoggingPreferenceController(context));
controllers.add(new VerifyAppsOverUsbPreferenceController(context));
controllers.add(new ArtVerifierPreferenceController(context));

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) 2020 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.settings.development;
import android.content.Context;
import android.hardware.display.DisplayManager;
import android.provider.Settings;
import android.util.Log;
import android.view.Display;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
public class ForcePeakRefreshRatePreferenceController extends DeveloperOptionsPreferenceController
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
@VisibleForTesting
static float DEFAULT_REFRESH_RATE = 60f;
@VisibleForTesting
static float NO_CONFIG = 0f;
@VisibleForTesting
float mPeakRefreshRate;
private static final String TAG = "ForcePeakRefreshRateCtr";
private static final String PREFERENCE_KEY = "pref_key_peak_refresh_rate";
public ForcePeakRefreshRatePreferenceController(Context context) {
super(context);
final DisplayManager dm = context.getSystemService(DisplayManager.class);
final Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
if (display == null) {
Log.w(TAG, "No valid default display device");
mPeakRefreshRate = DEFAULT_REFRESH_RATE;
} else {
mPeakRefreshRate = findPeakRefreshRate(display.getSupportedModes());
}
Log.d(TAG, "DEFAULT_REFRESH_RATE : " + DEFAULT_REFRESH_RATE
+ " mPeakRefreshRate : " + mPeakRefreshRate);
}
@Override
public String getPreferenceKey() {
return PREFERENCE_KEY;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean isEnabled = (Boolean) newValue;
forcePeakRefreshRate(isEnabled);
return true;
}
@Override
public void updateState(Preference preference) {
((SwitchPreference) mPreference).setChecked(isForcePeakRefreshRateEnabled());
}
@Override
public boolean isAvailable() {
if (mContext.getResources().getBoolean(R.bool.config_show_smooth_display)) {
return mPeakRefreshRate > DEFAULT_REFRESH_RATE;
} else {
return false;
}
}
@Override
protected void onDeveloperOptionsSwitchDisabled() {
super.onDeveloperOptionsSwitchDisabled();
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.MIN_REFRESH_RATE, NO_CONFIG);
((SwitchPreference) mPreference).setChecked(false);
}
@VisibleForTesting
void forcePeakRefreshRate(boolean enable) {
final float peakRefreshRate = enable ? mPeakRefreshRate : NO_CONFIG;
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.MIN_REFRESH_RATE, peakRefreshRate);
}
boolean isForcePeakRefreshRateEnabled() {
final float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
Settings.System.MIN_REFRESH_RATE, NO_CONFIG);
return peakRefreshRate >= mPeakRefreshRate;
}
private float findPeakRefreshRate(Display.Mode[] modes) {
float peakRefreshRate = DEFAULT_REFRESH_RATE;
for (Display.Mode mode : modes) {
if (Math.round(mode.getRefreshRate()) > DEFAULT_REFRESH_RATE) {
peakRefreshRate = mode.getRefreshRate();
}
}
return peakRefreshRate;
}
}

View File

@@ -27,6 +27,7 @@ import android.util.Log;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RelativeLayout;
import android.widget.Toast;
import androidx.preference.Preference;
@@ -34,19 +35,32 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
public class ApnPreference extends Preference implements CompoundButton.OnCheckedChangeListener {
/**
* Preference of APN UI entry
*/
public class ApnPreference extends Preference implements CompoundButton.OnCheckedChangeListener,
View.OnClickListener {
final static String TAG = "ApnPreference";
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
/**
* Constructor of Preference
*/
public ApnPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Constructor of Preference
*/
public ApnPreference(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.apnPreferenceStyle);
}
/**
* Constructor of Preference
*/
public ApnPreference(Context context) {
this(context, null);
}
@@ -61,6 +75,9 @@ public class ApnPreference extends Preference implements CompoundButton.OnChecke
public void onBindViewHolder(PreferenceViewHolder view) {
super.onBindViewHolder(view);
final RelativeLayout textArea = (RelativeLayout) view.findViewById(R.id.text_layout);
textArea.setOnClickListener(this);
final View widget = view.findViewById(R.id.apn_radiobutton);
if ((widget != null) && widget instanceof RadioButton) {
final RadioButton rb = (RadioButton) widget;
@@ -111,22 +128,25 @@ public class ApnPreference extends Preference implements CompoundButton.OnChecke
}
@Override
protected void onClick() {
public void onClick(View layoutView) {
super.onClick();
final Context context = getContext();
if (context != null) {
if (mHideDetails) {
Toast.makeText(context, context.getString(
R.string.cannot_change_apn_toast), Toast.LENGTH_LONG).show();
return;
}
final int pos = Integer.parseInt(getKey());
final Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
final Intent editIntent = new Intent(Intent.ACTION_EDIT, url);
editIntent.putExtra(ApnSettings.SUB_ID, mSubId);
editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(editIntent);
final int pos = Integer.parseInt(getKey());
if (context == null) {
Log.w(TAG, "No context available for pos=" + pos);
return;
}
if (mHideDetails) {
Toast.makeText(context, context.getString(
R.string.cannot_change_apn_toast), Toast.LENGTH_LONG).show();
return;
}
final Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
final Intent editIntent = new Intent(Intent.ACTION_EDIT, url);
editIntent.putExtra(ApnSettings.SUB_ID, mSubId);
editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(editIntent);
}
public void setSelectable(boolean selectable) {

View File

@@ -16,13 +16,19 @@
package com.android.settings.network;
import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
import static android.net.TetheringManager.TETHERING_INVALID;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
import static android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.TetheringConstants;
import android.net.TetheringManager;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.os.UserHandle;
@@ -52,23 +58,19 @@ public class TetherProvisioningActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mResultReceiver = (ResultReceiver)getIntent().getParcelableExtra(
ConnectivityManager.EXTRA_PROVISION_CALLBACK);
mResultReceiver = (ResultReceiver) getIntent().getParcelableExtra(EXTRA_PROVISION_CALLBACK);
final int tetherType = getIntent().getIntExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE,
ConnectivityManager.TETHERING_INVALID);
final int tetherType = getIntent().getIntExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_INVALID);
final int tetherSubId = getIntent().getIntExtra(EXTRA_SUBID,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
final int tetherSubId = getIntent().getIntExtra(EXTRA_SUBID, INVALID_SUBSCRIPTION_ID);
final int subId = SubscriptionManager.getActiveDataSubscriptionId();
if (tetherSubId != subId) {
Log.e(TAG, "This Provisioning request is outdated, current subId: " + subId);
mResultReceiver.send(TetheringManager.TETHER_ERROR_PROVISIONING_FAILED, null);
mResultReceiver.send(TETHER_ERROR_PROVISIONING_FAILED, null);
finish();
return;
}
String[] provisionApp = getIntent().getStringArrayExtra(
TetheringConstants.EXTRA_RUN_PROVISION);
String[] provisionApp = getIntent().getStringArrayExtra(EXTRA_RUN_PROVISION);
if (provisionApp == null || provisionApp.length < 2) {
final Resources res = Utils.getResourcesForSubId(this, subId);
provisionApp = res.getStringArray(
@@ -77,8 +79,8 @@ public class TetherProvisioningActivity extends Activity {
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName(provisionApp[0], provisionApp[1]);
intent.putExtra(EXTRA_TETHER_TYPE, tetherType);
intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
intent.putExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK, mResultReceiver);
intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId);
intent.putExtra(EXTRA_PROVISION_CALLBACK, mResultReceiver);
if (DEBUG) {
Log.d(TAG, "Starting provisioning app: " + provisionApp[0] + "." + provisionApp[1]);
}
@@ -86,7 +88,7 @@ public class TetherProvisioningActivity extends Activity {
if (getPackageManager().queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
Log.e(TAG, "Provisioning app is configured, but not available.");
mResultReceiver.send(TetheringManager.TETHER_ERROR_PROVISIONING_FAILED, null);
mResultReceiver.send(TETHER_ERROR_PROVISIONING_FAILED, null);
finish();
return;
}
@@ -99,9 +101,8 @@ public class TetherProvisioningActivity extends Activity {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == PROVISION_REQUEST) {
if (DEBUG) Log.d(TAG, "Got result from app: " + resultCode);
int result = resultCode == Activity.RESULT_OK ?
TetheringManager.TETHER_ERROR_NO_ERROR :
TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
int result = resultCode == Activity.RESULT_OK
? TETHER_ERROR_NO_ERROR : TETHER_ERROR_PROVISIONING_FAILED;
mResultReceiver.send(result, null);
finish();
}

View File

@@ -20,7 +20,6 @@ import android.content.Context;
import android.content.Intent;
import android.media.RoutingSessionInfo;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -136,11 +135,6 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final MediaDevice device = mLocalMediaManager.getMediaDeviceById(preference.getKey());
if (device == null) {
Log.e(TAG, "Unable to find " + preference.getKey() + " to set volume");
return false;
}
ThreadUtils.postOnBackgroundThread(() -> {
mLocalMediaManager.adjustSessionVolume(preference.getKey(), (int) newValue);
});
@@ -184,6 +178,5 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
@Override
public void onSelectedDeviceStateChanged(MediaDevice device, int state) {
}
}

View File

@@ -821,6 +821,14 @@ public class ChooseLockGeneric extends SettingsActivity {
@Override
public void onDestroy() {
super.onDestroy();
if (mUserPassword != null) {
mUserPassword.zeroize();
}
// Force a garbage collection immediately to remove remnant of user password shards
// from memory.
System.gc();
System.runFinalization();
System.gc();
}
@Override

View File

@@ -530,6 +530,19 @@ public class ChooseLockPassword extends SettingsActivity {
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mCurrentCredential != null) {
mCurrentCredential.zeroize();
}
// Force a garbage collection immediately to remove remnant of user password shards
// from memory.
System.gc();
System.runFinalization();
System.gc();
}
protected int getStageType() {
return mForFingerprint ? Stage.TYPE_FINGERPRINT :
mForFace ? Stage.TYPE_FACE :

View File

@@ -617,6 +617,19 @@ public class ChooseLockPattern extends SettingsActivity {
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mCurrentCredential != null) {
mCurrentCredential.zeroize();
}
// Force a garbage collection immediately to remove remnant of user password shards
// from memory.
System.gc();
System.runFinalization();
System.gc();
}
protected Intent getRedactionInterstitialIntent(Context context) {
return RedactionInterstitial.createStartIntent(context, mUserId);
}

View File

@@ -157,6 +157,16 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi
}
}
@Override
public void onDestroy() {
super.onDestroy();
// Force a garbage collection immediately to remove remnant of user password shards
// from memory.
System.gc();
System.runFinalization();
System.gc();
}
@Override
public void finish() {
super.finish();

View File

@@ -217,6 +217,17 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
}
}
@Override
public void onDestroy() {
super.onDestroy();
mPasswordEntry.setText(null);
// Force a garbage collection immediately to remove remnant of user password shards
// from memory.
System.gc();
System.runFinalization();
System.gc();
}
private int getDefaultHeader() {
if (mFrp) {
return mIsAlpha ? R.string.lockpassword_confirm_your_password_header_frp

View File

@@ -1,55 +0,0 @@
package com.android.settings.wifi.tether;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.util.Log;
/**
* This receiver catches when quick settings turns off the hotspot, so we can
* cancel the alarm in that case. All other cancels are handled in tethersettings.
*/
public class HotspotOffReceiver extends BroadcastReceiver {
private static final String TAG = "HotspotOffReceiver";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private Context mContext;
private boolean mRegistered;
public HotspotOffReceiver(Context context) {
mContext = context;
}
@Override
public void onReceive(Context context, Intent intent) {
if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (wifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_DISABLED) {
if (DEBUG) Log.d(TAG, "TetherService.cancelRecheckAlarmIfNecessary called");
// The hotspot has been turned off, we don't need to recheck tethering.
TetherService.cancelRecheckAlarmIfNecessary(
context, ConnectivityManager.TETHERING_WIFI);
}
}
}
public void register() {
if (!mRegistered) {
mContext.registerReceiver(this,
new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION));
mRegistered = true;
}
}
public void unregister() {
if (mRegistered) {
mContext.unregisterReceiver(this);
mRegistered = false;
}
}
}

View File

@@ -16,15 +16,24 @@
package com.android.settings.wifi.tether;
import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
import static android.net.TetheringConstants.EXTRA_REM_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import static android.net.TetheringManager.TETHERING_INVALID;
import static android.net.TetheringManager.TETHERING_USB;
import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
import static android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.usage.UsageStatsManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile.ServiceListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -33,10 +42,9 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.TetheringManager;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -74,7 +82,6 @@ public class TetherService extends Service {
private TetherServiceWrapper mWrapper;
private ArrayList<Integer> mCurrentTethers;
private ArrayMap<Integer, List<ResultReceiver>> mPendingCallbacks;
private HotspotOffReceiver mHotspotReceiver;
@Override
public IBinder onBind(Intent intent) {
@@ -93,18 +100,16 @@ public class TetherService extends Service {
mCurrentTethers = stringToTethers(prefs.getString(KEY_TETHERS, ""));
mCurrentTypeIndex = 0;
mPendingCallbacks = new ArrayMap<>(3);
mPendingCallbacks.put(ConnectivityManager.TETHERING_WIFI, new ArrayList<ResultReceiver>());
mPendingCallbacks.put(ConnectivityManager.TETHERING_USB, new ArrayList<ResultReceiver>());
mPendingCallbacks.put(
ConnectivityManager.TETHERING_BLUETOOTH, new ArrayList<ResultReceiver>());
mHotspotReceiver = new HotspotOffReceiver(this);
mPendingCallbacks.put(TETHERING_WIFI, new ArrayList<ResultReceiver>());
mPendingCallbacks.put(TETHERING_USB, new ArrayList<ResultReceiver>());
mPendingCallbacks.put(TETHERING_BLUETOOTH, new ArrayList<ResultReceiver>());
mPendingCallbacks.put(TETHERING_ETHERNET, new ArrayList<ResultReceiver>());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.hasExtra(EXTRA_SUBID)) {
final int tetherSubId = intent.getIntExtra(EXTRA_SUBID,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
final int tetherSubId = intent.getIntExtra(EXTRA_SUBID, INVALID_SUBSCRIPTION_ID);
final int subId = getTetherServiceWrapper().getActiveDataSubscriptionId();
if (tetherSubId != subId) {
Log.e(TAG, "This Provisioning request is outdated, current subId: " + subId);
@@ -114,18 +119,16 @@ public class TetherService extends Service {
return START_NOT_STICKY;
}
}
if (intent.hasExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE)) {
int type = intent.getIntExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE,
ConnectivityManager.TETHERING_INVALID);
ResultReceiver callback =
intent.getParcelableExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK);
if (intent.hasExtra(EXTRA_ADD_TETHER_TYPE)) {
int type = intent.getIntExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_INVALID);
ResultReceiver callback = intent.getParcelableExtra(EXTRA_PROVISION_CALLBACK);
if (callback != null) {
List<ResultReceiver> callbacksForType = mPendingCallbacks.get(type);
if (callbacksForType != null) {
callbacksForType.add(callback);
} else {
// Invalid tether type. Just ignore this request and report failure.
callback.send(ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE, null);
callback.send(TETHER_ERROR_UNKNOWN_IFACE, null);
stopSelf();
return START_NOT_STICKY;
}
@@ -137,30 +140,20 @@ public class TetherService extends Service {
}
}
if (intent.hasExtra(ConnectivityManager.EXTRA_REM_TETHER_TYPE)) {
if (intent.hasExtra(EXTRA_REM_TETHER_TYPE)) {
if (!mInProvisionCheck) {
int type = intent.getIntExtra(ConnectivityManager.EXTRA_REM_TETHER_TYPE,
ConnectivityManager.TETHERING_INVALID);
int type = intent.getIntExtra(EXTRA_REM_TETHER_TYPE, TETHERING_INVALID);
int index = mCurrentTethers.indexOf(type);
if (DEBUG) Log.d(TAG, "Removing tether " + type + ", index " + index);
if (index >= 0) {
removeTypeAtIndex(index);
}
cancelAlarmIfNecessary();
} else {
if (DEBUG) Log.d(TAG, "Don't cancel alarm during provisioning");
if (DEBUG) Log.d(TAG, "Don't remove tether type during provisioning");
}
}
// Only set the alarm if we have one tether, meaning the one just added,
// to avoid setting it when it was already set previously for another
// type.
if (intent.getBooleanExtra(ConnectivityManager.EXTRA_SET_ALARM, false)
&& mCurrentTethers.size() == 1) {
scheduleAlarm();
}
if (intent.getBooleanExtra(ConnectivityManager.EXTRA_RUN_PROVISION, false)) {
if (intent.getBooleanExtra(EXTRA_RUN_PROVISION, false)) {
startProvisioning(mCurrentTypeIndex);
} else if (!mInProvisionCheck) {
// If we aren't running any provisioning, no reason to stay alive.
@@ -182,16 +175,11 @@ public class TetherService extends Service {
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
prefs.edit().putString(KEY_TETHERS, tethersToString(mCurrentTethers)).commit();
unregisterReceivers();
unregisterReceiver(mReceiver);
if (DEBUG) Log.d(TAG, "Destroying TetherService");
super.onDestroy();
}
private void unregisterReceivers() {
unregisterReceiver(mReceiver);
mHotspotReceiver.unregister();
}
private void removeTypeAtIndex(int index) {
mCurrentTethers.remove(index);
// If we are currently in the middle of a check, we may need to adjust the
@@ -202,11 +190,6 @@ public class TetherService extends Service {
}
}
@VisibleForTesting
void setHotspotOffReceiver(HotspotOffReceiver receiver) {
mHotspotReceiver = receiver;
}
private ArrayList<Integer> stringToTethers(String tethersStr) {
ArrayList<Integer> ret = new ArrayList<Integer>();
if (TextUtils.isEmpty(tethersStr)) return ret;
@@ -231,32 +214,9 @@ public class TetherService extends Service {
return buffer.toString();
}
private void disableWifiTethering() {
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
cm.stopTethering(ConnectivityManager.TETHERING_WIFI);
}
private void disableUsbTethering() {
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
cm.setUsbTethering(false);
}
private void disableBtTethering() {
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
adapter.getProfileProxy(this, new ServiceListener() {
@Override
public void onServiceDisconnected(int profile) { }
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
((BluetoothPan) proxy).setBluetoothTethering(false);
adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
}
}, BluetoothProfile.PAN);
}
private void disableTethering(final int tetheringType) {
final TetheringManager tm = (TetheringManager) getSystemService(Context.TETHERING_SERVICE);
tm.stopTethering(tetheringType);
}
private void startProvisioning(int index) {
@@ -279,7 +239,7 @@ public class TetherService extends Service {
Intent intent = new Intent(provisionAction);
int type = mCurrentTethers.get(index);
intent.putExtra(TETHER_CHOICE, type);
intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId);
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
@@ -304,55 +264,13 @@ public class TetherService extends Service {
}
}
@VisibleForTesting
void scheduleAlarm() {
Intent intent = new Intent(this, TetherService.class);
intent.putExtra(ConnectivityManager.EXTRA_RUN_PROVISION, true);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
int period = getResourceForActiveDataSubId().getInteger(
com.android.internal.R.integer.config_mobile_hotspot_provision_check_period);
long periodMs = period * MS_PER_HOUR;
long firstTime = SystemClock.elapsedRealtime() + periodMs;
if (DEBUG) Log.d(TAG, "Scheduling alarm at interval " + periodMs);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, firstTime, periodMs,
pendingIntent);
mHotspotReceiver.register();
}
/**
* Cancels the recheck alarm only if no tethering is currently active.
*
* Runs in the background, to get access to bluetooth service that takes time to bind.
*/
public static void cancelRecheckAlarmIfNecessary(final Context context, int type) {
Intent intent = new Intent(context, TetherService.class);
intent.putExtra(ConnectivityManager.EXTRA_REM_TETHER_TYPE, type);
context.startService(intent);
}
@VisibleForTesting
void cancelAlarmIfNecessary() {
if (mCurrentTethers.size() != 0) {
if (DEBUG) Log.d(TAG, "Tethering still active, not cancelling alarm");
return;
}
Intent intent = new Intent(this, TetherService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
if (DEBUG) Log.d(TAG, "Tethering no longer active, canceling recheck");
mHotspotReceiver.unregister();
}
private void fireCallbacksForType(int type, int result) {
List<ResultReceiver> callbacksForType = mPendingCallbacks.get(type);
if (callbacksForType == null) {
return;
}
int errorCode = result == RESULT_OK ? ConnectivityManager.TETHER_ERROR_NO_ERROR :
ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
int errorCode = result == RESULT_OK ? TETHER_ERROR_NO_ERROR :
TETHER_ERROR_PROVISIONING_FAILED;
for (ResultReceiver callback : callbacksForType) {
if (DEBUG) Log.d(TAG, "Firing result: " + errorCode + " to callback");
callback.send(errorCode, null);
@@ -375,19 +293,7 @@ public class TetherService extends Service {
int checkType = mCurrentTethers.get(mCurrentTypeIndex);
mInProvisionCheck = false;
int result = intent.getIntExtra(EXTRA_RESULT, RESULT_DEFAULT);
if (result != RESULT_OK) {
switch (checkType) {
case ConnectivityManager.TETHERING_WIFI:
disableWifiTethering();
break;
case ConnectivityManager.TETHERING_BLUETOOTH:
disableBtTethering();
break;
case ConnectivityManager.TETHERING_USB:
disableUsbTethering();
break;
}
}
if (result != RESULT_OK) disableTethering(checkType);
fireCallbacksForType(checkType, result);
if (++mCurrentTypeIndex >= mCurrentTethers.size()) {

View File

@@ -0,0 +1,133 @@
/*
* Copyright (C) 2020 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.settings.development;
import static com.android.settings.development.ForcePeakRefreshRatePreferenceController.DEFAULT_REFRESH_RATE;
import static com.android.settings.development.ForcePeakRefreshRatePreferenceController.NO_CONFIG;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import android.util.Log;
@RunWith(RobolectricTestRunner.class)
public class ForcePeakRefreshRatePreferenceControllerTest {
@Mock
private SwitchPreference mPreference;
@Mock
private PreferenceScreen mScreen;
private Context mContext;
private ForcePeakRefreshRatePreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new ForcePeakRefreshRatePreferenceController(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
mController.displayPreference(mScreen);
}
@Test
public void onPreferenceChange_preferenceChecked_shouldEnableForcePeak() {
mController.mPeakRefreshRate = 88f;
mController.onPreferenceChange(mPreference, true);
assertThat(Settings.System.getFloat(mContext.getContentResolver(),
Settings.System.MIN_REFRESH_RATE, NO_CONFIG)).isEqualTo(88f);
}
@Test
public void onPreferenceChange_preferenceUnchecked_shouldDisableForcePeak() {
mController.mPeakRefreshRate = 88f;
mController.onPreferenceChange(mPreference, false);
assertThat(Settings.System.getFloat(mContext.getContentResolver(),
Settings.System.MIN_REFRESH_RATE, NO_CONFIG)).isEqualTo(NO_CONFIG);
}
@Test
public void updateState_enableForcePeak_shouldCheckedToggle() {
mController.mPeakRefreshRate = 88f;
mController.forcePeakRefreshRate(true);
mController.updateState(mPreference);
verify(mPreference).setChecked(true);
}
@Test
public void updateState_disableForcePeak_shouldUncheckedToggle() {
mController.mPeakRefreshRate = 88f;
mController.forcePeakRefreshRate(false);
mController.updateState(mPreference);
verify(mPreference).setChecked(false);
}
@Test
@Config(qualifiers = "mcc999")
public void isAvailable_withConfigNoShow_returnUnsupported() {
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_refreshRateLargerThanDefault_returnTrue() {
mController.mPeakRefreshRate = DEFAULT_REFRESH_RATE + 1;
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void getAvailabilityStatus_refreshRateEqualToDefault_returnFalse() {
mController.mPeakRefreshRate = DEFAULT_REFRESH_RATE;
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void onDeveloperOptionsDisabled_shouldDisablePreference() {
mController.onDeveloperOptionsSwitchDisabled();
assertThat(Settings.System.getFloat(mContext.getContentResolver(),
Settings.System.MIN_REFRESH_RATE, -1f)).isEqualTo(NO_CONFIG);
assertThat(mPreference.isChecked()).isFalse();
assertThat(mPreference.isEnabled()).isFalse();
}
}

View File

@@ -1,130 +0,0 @@
/*
* 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.settings.wifi.tether;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.net.wifi.WifiManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowApplication.Wrapper;
import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
@RunWith(RobolectricTestRunner.class)
public class TetherServiceTest {
private static final int CHECK_PERIOD_HOURS = 24;
@Mock
private Context mContext;
@Mock
private Resources mResources;
private Context mAppContext;
private TetherService mService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mAppContext = RuntimeEnvironment.application;
mService = spy(new TetherService());
ReflectionHelpers.setField(mService, "mBase", mAppContext);
mService.setHotspotOffReceiver(new HotspotOffReceiver(mContext));
doReturn(CHECK_PERIOD_HOURS).when(mResources).getInteger(
com.android.internal.R.integer.config_mobile_hotspot_provision_check_period);
doReturn(mResources).when(mService).getResourceForActiveDataSubId();
}
@Test
public void scheduleAlarm_shouldRegisterReceiver() {
mService.setHotspotOffReceiver(new HotspotOffReceiver(mAppContext));
mService.scheduleAlarm();
boolean found = false;
for (Wrapper wrapper : ShadowApplication.getInstance().getRegisteredReceivers()) {
if (wrapper.intentFilter.matchAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
found = true;
break;
}
}
assertThat(found).isTrue();
}
@Test
public void cancelAlarmIfNecessary_hasActiveTethers_shouldNotUnregisterReceiver() {
mService.scheduleAlarm();
final ArrayList<Integer> tethers = new ArrayList<>();
tethers.add(1);
ReflectionHelpers.setField(mService, "mCurrentTethers", tethers);
mService.cancelAlarmIfNecessary();
verify(mContext, never()).unregisterReceiver(any(HotspotOffReceiver.class));
}
@Test
public void cancelAlarmIfNecessary_noActiveTethers_shouldUnregisterReceiver() {
final ArrayList<Integer> tethers = new ArrayList<>();
ReflectionHelpers.setField(mService, "mCurrentTethers", tethers);
mService.scheduleAlarm();
mService.cancelAlarmIfNecessary();
verify(mContext).unregisterReceiver(any(HotspotOffReceiver.class));
}
@Test
public void onDestroy_shouldUnregisterReceiver() {
final ArrayList<Integer> tethers = new ArrayList<>();
ReflectionHelpers.setField(mService, "mCurrentTethers", tethers);
ReflectionHelpers.setField(mService, "mBase", mContext);
final SharedPreferences prefs = mock(SharedPreferences .class);
final SharedPreferences.Editor editor = mock(SharedPreferences.Editor.class);
when(mContext.getSharedPreferences(anyString(), anyInt())).thenReturn(prefs);
when(prefs.edit()).thenReturn(editor);
when(editor.putString(anyString(), anyString())).thenReturn(editor);
final HotspotOffReceiver hotspotOffReceiver = mock(HotspotOffReceiver.class);
mService.setHotspotOffReceiver(hotspotOffReceiver);
mService.onDestroy();
verify(hotspotOffReceiver).unregister();
}
}

View File

@@ -16,27 +16,23 @@
package com.android.settings.wifi.tether;
import static android.net.ConnectivityManager.EXTRA_ADD_TETHER_TYPE;
import static android.net.ConnectivityManager.EXTRA_PROVISION_CALLBACK;
import static android.net.ConnectivityManager.EXTRA_REM_TETHER_TYPE;
import static android.net.ConnectivityManager.EXTRA_RUN_PROVISION;
import static android.net.ConnectivityManager.EXTRA_SET_ALARM;
import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
import static android.net.ConnectivityManager.TETHERING_INVALID;
import static android.net.ConnectivityManager.TETHERING_USB;
import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_INVALID;
import static android.net.TetheringManager.TETHERING_USB;
import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.usage.UsageStatsManager;
import android.content.BroadcastReceiver;
@@ -51,7 +47,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.TetheringManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.ResultReceiver;
@@ -92,8 +88,7 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
private ProvisionReceiver mProvisionReceiver;
private Receiver mResultReceiver;
@Mock private AlarmManager mAlarmManager;
@Mock private ConnectivityManager mConnectivityManager;
@Mock private TetheringManager mTetheringManager;
@Mock private PackageManager mPackageManager;
@Mock private WifiManager mWifiManager;
@Mock private SharedPreferences mPrefs;
@@ -158,15 +153,6 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
super.tearDown();
}
private void cancelAllProvisioning() {
int[] types = new int[]{TETHERING_BLUETOOTH, TETHERING_WIFI, TETHERING_USB};
for (int type : types) {
Intent intent = new Intent();
intent.putExtra(EXTRA_REM_TETHER_TYPE, type);
startService(intent);
}
}
public void testStartForProvision() {
runProvisioningForType(TETHERING_WIFI);
@@ -184,19 +170,6 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
assertTrue(mWrapper.isAppInactive(FAKE_PACKAGE_NAME));
}
public void testScheduleRechecks() {
Intent intent = new Intent();
intent.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI);
intent.putExtra(EXTRA_SET_ALARM, true);
startService(intent);
long period = TEST_CHECK_PERIOD * MS_PER_HOUR;
verify(mAlarmManager).setRepeating(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
eq(period), mPiCaptor.capture());
PendingIntent pi = mPiCaptor.getValue();
assertEquals(TetherService.class.getName(), pi.getIntent().getComponent().getClassName());
}
public void testStartMultiple() {
runProvisioningForType(TETHERING_WIFI);
@@ -235,9 +208,9 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
runProvisioningForType(TETHERING_WIFI);
assertTrue(waitForProvisionRequest(TETHERING_WIFI));
assertTrue(waitForProvisionResponse(TETHER_ERROR_PROVISION_FAILED));
assertTrue(waitForProvisionResponse(TETHER_ERROR_PROVISIONING_FAILED));
verify(mConnectivityManager).stopTethering(ConnectivityManager.TETHERING_WIFI);
verify(mTetheringManager).stopTethering(TETHERING_WIFI);
}
public void testFailureStopsTethering_Usb() {
@@ -246,24 +219,9 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
runProvisioningForType(TETHERING_USB);
assertTrue(waitForProvisionRequest(TETHERING_USB));
assertTrue(waitForProvisionResponse(TETHER_ERROR_PROVISION_FAILED));
assertTrue(waitForProvisionResponse(TETHER_ERROR_PROVISIONING_FAILED));
verify(mConnectivityManager).setUsbTethering(eq(false));
}
public void testCancelAlarm() {
runProvisioningForType(TETHERING_WIFI);
assertTrue(waitForProvisionRequest(TETHERING_WIFI));
assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
Intent intent = new Intent();
intent.putExtra(EXTRA_REM_TETHER_TYPE, TETHERING_WIFI);
startService(intent);
verify(mAlarmManager).cancel(mPiCaptor.capture());
PendingIntent pi = mPiCaptor.getValue();
assertEquals(TetherService.class.getName(), pi.getIntent().getComponent().getClassName());
verify(mTetheringManager).stopTethering(TETHERING_USB);
}
public void testIgnoreOutdatedRequest() {
@@ -387,10 +345,8 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
@Override
public Object getSystemService(String name) {
if (ALARM_SERVICE.equals(name)) {
return mAlarmManager;
} else if (CONNECTIVITY_SERVICE.equals(name)) {
return mConnectivityManager;
if (TETHERING_SERVICE.equals(name)) {
return mTetheringManager;
} else if (WIFI_SERVICE.equals(name)) {
return mWifiManager;
}