Snap for 6589438 from 4634271464 to mainline-release
Change-Id: I9e0a87d2378b20181f87443be37e4995a9e8a5ce
This commit is contained in:
@@ -30,21 +30,20 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/panel_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="94dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginStart="16dp">
|
||||
<ImageView
|
||||
android:id="@+id/title_icon"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"/>
|
||||
android:layout_width="@dimen/output_switcher_panel_icon_size"
|
||||
android:layout_height="@dimen/output_switcher_panel_icon_size"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -52,10 +51,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="9dp"
|
||||
android:paddingTop="9dp">
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/header_title"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -422,7 +422,9 @@
|
||||
<dimen name="list_preferred_item_padding">16dp</dimen>
|
||||
|
||||
<!-- Output switcher panel related dimensions -->
|
||||
<dimen name="output_switcher_slice_padding_top">12dp</dimen>
|
||||
<dimen name="output_switcher_slice_padding_top">11dp</dimen>
|
||||
<dimen name="output_switcher_slice_max_height">506dp</dimen>
|
||||
<dimen name="output_switcher_panel_icon_size">52dp</dimen>
|
||||
|
||||
<!-- Text padding for EmptyTextSettings -->
|
||||
<dimen name="empty_text_padding">24dp</dimen>
|
||||
|
||||
@@ -11816,6 +11816,8 @@
|
||||
<string name="network_connection_errorstate_dialog_message">Something came up. The application has cancelled the request to choose a device.</string>
|
||||
<!-- Toast message when connection is successful [CHAR LIMIT=30] -->
|
||||
<string name="network_connection_connect_successful">Connection successful</string>
|
||||
<!-- Toast message when connection is failure [CHAR LIMIT=30] -->
|
||||
<string name="network_connection_connect_failure">Connection failed</string>
|
||||
<!-- Neutral button for Network connection request Dialog [CHAR LIMIT=30] -->
|
||||
<string name="network_connection_request_dialog_showall">Show all</string>
|
||||
<!-- Message for Network connection searching progress Dialog. Searching for wifi ap. [CHAR LIMIT=40] -->
|
||||
|
||||
@@ -564,16 +564,17 @@
|
||||
</style>
|
||||
|
||||
<style name="SliceRow.Slider">
|
||||
<!-- 10dp start padding for the start icon -->
|
||||
<item name="titleItemStartPadding">10dp</item>
|
||||
<!-- 4dp start padding for the start icon -->
|
||||
<item name="titleItemStartPadding">4dp</item>
|
||||
|
||||
<!-- Padding between content and the start icon is 0dp -->
|
||||
<item name="contentStartPadding">0dp</item>
|
||||
<item name="contentEndPadding">36dp</item>
|
||||
|
||||
<!-- 0dp start padding for the end item -->
|
||||
<item name="endItemStartPadding">0dp</item>
|
||||
<!-- 24dp end padding for the end item -->
|
||||
<item name="endItemEndPadding">24dp</item>
|
||||
<!-- 8dp end padding for the end item -->
|
||||
<item name="endItemEndPadding">8dp</item>
|
||||
|
||||
<!-- Align text with slider -->
|
||||
<item name="titleStartPadding">11dp</item>
|
||||
|
||||
@@ -54,6 +54,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.deviceinfo.StorageWizardMoveConfirm;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
import com.android.settingslib.applications.ApplicationsState.Callbacks;
|
||||
import com.android.settingslib.applications.StorageStatsSource;
|
||||
import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
|
||||
@@ -321,7 +322,7 @@ public class AppStorageSettings extends AppInfoWithHeader
|
||||
.setButton1OnClickListener(v -> handleClearDataClick());
|
||||
}
|
||||
|
||||
if (mAppsControlDisallowedBySystem) {
|
||||
if (mAppsControlDisallowedBySystem || AppUtils.isMainlineModule(mPm, mPackageName)) {
|
||||
mButtonsPref.setButton1Enabled(false);
|
||||
}
|
||||
}
|
||||
@@ -579,7 +580,7 @@ public class AppStorageSettings extends AppInfoWithHeader
|
||||
.setButton2OnClickListener(v -> handleClearCacheClick());
|
||||
}
|
||||
}
|
||||
if (mAppsControlDisallowedBySystem) {
|
||||
if (mAppsControlDisallowedBySystem || AppUtils.isMainlineModule(mPm, mPackageName)) {
|
||||
mButtonsPref.setButton1Enabled(false).setButton2Enabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -744,7 +744,9 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
|
||||
}
|
||||
|
||||
private boolean isSystemModule() {
|
||||
return mAppEntry != null && AppUtils.isSystemModule(mContext, mAppEntry.info.packageName);
|
||||
return mAppEntry != null
|
||||
&& (AppUtils.isSystemModule(mContext, mAppEntry.info.packageName)
|
||||
|| AppUtils.isMainlineModule(mPm, mAppEntry.info.packageName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,7 +43,7 @@ public class AppInstallerInfoPreferenceController extends AppInfoPreferenceContr
|
||||
return DISABLED_FOR_USER;
|
||||
}
|
||||
|
||||
if (AppUtils.isMainlineModule(mContext, mPackageName)) {
|
||||
if (AppUtils.isMainlineModule(mContext.getPackageManager(), mPackageName)) {
|
||||
return DISABLED_FOR_USER;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.homepage.contextualcards.slices.BluetoothUpdateWorker;
|
||||
import com.android.settings.homepage.contextualcards.slices.SwipeDismissalDelegate;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.wifi.slice.ContextualWifiScanWorker;
|
||||
@@ -67,6 +68,7 @@ public class ContextualCardsFragment extends InstrumentedFragment implements
|
||||
final Context context = getContext();
|
||||
if (savedInstanceState == null) {
|
||||
FeatureFactory.getFactory(context).getSlicesFeatureProvider().newUiSession();
|
||||
BluetoothUpdateWorker.initLocalBtManager(getContext());
|
||||
}
|
||||
mContextualCardManager = new ContextualCardManager(context, getSettingsLifecycle(),
|
||||
savedInstanceState);
|
||||
|
||||
@@ -81,15 +81,12 @@ public class BluetoothDevicesSlice implements CustomSliceable {
|
||||
private static boolean sBluetoothEnabling;
|
||||
|
||||
private final Context mContext;
|
||||
private final AvailableMediaBluetoothDeviceUpdater mAvailableMediaBtDeviceUpdater;
|
||||
private final SavedBluetoothDeviceUpdater mSavedBtDeviceUpdater;
|
||||
private AvailableMediaBluetoothDeviceUpdater mAvailableMediaBtDeviceUpdater;
|
||||
private SavedBluetoothDeviceUpdater mSavedBtDeviceUpdater;
|
||||
|
||||
public BluetoothDevicesSlice(Context context) {
|
||||
mContext = context;
|
||||
mAvailableMediaBtDeviceUpdater = new AvailableMediaBluetoothDeviceUpdater(mContext,
|
||||
null /* fragment */, null /* devicePreferenceCallback */);
|
||||
mSavedBtDeviceUpdater = new SavedBluetoothDeviceUpdater(mContext,
|
||||
null /* fragment */, null /* devicePreferenceCallback */);
|
||||
BluetoothUpdateWorker.initLocalBtManager(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,16 +116,8 @@ public class BluetoothDevicesSlice implements CustomSliceable {
|
||||
// Add the header of Bluetooth on
|
||||
listBuilder.addRow(getBluetoothOnHeader());
|
||||
|
||||
// Get row builders of Bluetooth devices.
|
||||
final List<ListBuilder.RowBuilder> rows = getBluetoothRowBuilders();
|
||||
|
||||
// Determine the displayable row count.
|
||||
final int displayableCount = Math.min(rows.size(), DEFAULT_EXPANDED_ROW_COUNT);
|
||||
|
||||
// Add device rows up to the count.
|
||||
for (int i = 0; i < displayableCount; i++) {
|
||||
listBuilder.addRow(rows.get(i));
|
||||
}
|
||||
// Add row builders of Bluetooth devices.
|
||||
getBluetoothRowBuilders().forEach(row -> listBuilder.addRow(row));
|
||||
|
||||
return listBuilder.build();
|
||||
}
|
||||
@@ -181,19 +170,18 @@ public class BluetoothDevicesSlice implements CustomSliceable {
|
||||
List<CachedBluetoothDevice> getPairedBluetoothDevices() {
|
||||
final List<CachedBluetoothDevice> bluetoothDeviceList = new ArrayList<>();
|
||||
|
||||
// If Bluetooth is disable, skip to get the Bluetooth devices.
|
||||
// If Bluetooth is disable, skip getting the Bluetooth devices.
|
||||
if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
|
||||
Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is disabled.");
|
||||
return bluetoothDeviceList;
|
||||
}
|
||||
|
||||
// Get the Bluetooth devices from LocalBluetoothManager.
|
||||
final LocalBluetoothManager localBtManager =
|
||||
com.android.settings.bluetooth.Utils.getLocalBtManager(mContext);
|
||||
final LocalBluetoothManager localBtManager = BluetoothUpdateWorker.getLocalBtManager();
|
||||
if (localBtManager == null) {
|
||||
Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is unsupported.");
|
||||
Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is not ready.");
|
||||
return bluetoothDeviceList;
|
||||
}
|
||||
|
||||
final Collection<CachedBluetoothDevice> cachedDevices =
|
||||
localBtManager.getCachedDeviceManager().getCachedDevicesCopy();
|
||||
|
||||
@@ -292,8 +280,21 @@ public class BluetoothDevicesSlice implements CustomSliceable {
|
||||
|
||||
private List<ListBuilder.RowBuilder> getBluetoothRowBuilders() {
|
||||
final List<ListBuilder.RowBuilder> bluetoothRows = new ArrayList<>();
|
||||
final List<CachedBluetoothDevice> pairedDevices = getPairedBluetoothDevices();
|
||||
if (pairedDevices.isEmpty()) {
|
||||
return bluetoothRows;
|
||||
}
|
||||
|
||||
// Initialize updaters without being blocked after paired devices is available because
|
||||
// LocalBluetoothManager is ready.
|
||||
lazyInitUpdaters();
|
||||
|
||||
// Create row builders based on paired devices.
|
||||
for (CachedBluetoothDevice device : getPairedBluetoothDevices()) {
|
||||
for (CachedBluetoothDevice device : pairedDevices) {
|
||||
if (bluetoothRows.size() >= DEFAULT_EXPANDED_ROW_COUNT) {
|
||||
break;
|
||||
}
|
||||
|
||||
String summary = device.getConnectionSummary();
|
||||
if (summary == null) {
|
||||
summary = mContext.getString(
|
||||
@@ -321,6 +322,18 @@ public class BluetoothDevicesSlice implements CustomSliceable {
|
||||
return bluetoothRows;
|
||||
}
|
||||
|
||||
private void lazyInitUpdaters() {
|
||||
if (mAvailableMediaBtDeviceUpdater == null) {
|
||||
mAvailableMediaBtDeviceUpdater = new AvailableMediaBluetoothDeviceUpdater(mContext,
|
||||
null /* fragment */, null /* devicePreferenceCallback */);
|
||||
}
|
||||
|
||||
if (mSavedBtDeviceUpdater == null) {
|
||||
mSavedBtDeviceUpdater = new SavedBluetoothDeviceUpdater(mContext,
|
||||
null /* fragment */, null /* devicePreferenceCallback */);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
SliceAction buildPrimaryBluetoothAction(CachedBluetoothDevice bluetoothDevice) {
|
||||
final Intent intent = new Intent(getUri().toString())
|
||||
|
||||
@@ -18,9 +18,14 @@ package com.android.settings.homepage.contextualcards.slices;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.settings.slices.SliceBackgroundWorker;
|
||||
import com.android.settingslib.bluetooth.BluetoothCallback;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
@@ -30,29 +35,46 @@ public class BluetoothUpdateWorker extends SliceBackgroundWorker implements Blue
|
||||
|
||||
private static final String TAG = "BluetoothUpdateWorker";
|
||||
|
||||
private final LocalBluetoothManager mLocalBluetoothManager;
|
||||
private static LocalBluetoothManager sLocalBluetoothManager;
|
||||
|
||||
private LoadBtManagerHandler mLoadBtManagerHandler;
|
||||
|
||||
public BluetoothUpdateWorker(Context context, Uri uri) {
|
||||
super(context, uri);
|
||||
mLocalBluetoothManager = Utils.getLocalBtManager(context);
|
||||
mLoadBtManagerHandler = LoadBtManagerHandler.getInstance(context);
|
||||
if (sLocalBluetoothManager == null) {
|
||||
mLoadBtManagerHandler.startLoadingBtManager(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialize {@link LocalBluetoothManager} in the background */
|
||||
public static void initLocalBtManager(Context context) {
|
||||
if (sLocalBluetoothManager == null) {
|
||||
LoadBtManagerHandler.getInstance(context).startLoadingBtManager();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static LocalBluetoothManager getLocalBtManager() {
|
||||
return sLocalBluetoothManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSlicePinned() {
|
||||
if (mLocalBluetoothManager == null) {
|
||||
Log.i(TAG, "onSlicePinned() Bluetooth is unsupported.");
|
||||
final LocalBluetoothManager localBtManager = mLoadBtManagerHandler.getLocalBtManager();
|
||||
if (localBtManager == null) {
|
||||
return;
|
||||
}
|
||||
mLocalBluetoothManager.getEventManager().registerCallback(this);
|
||||
localBtManager.getEventManager().registerCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSliceUnpinned() {
|
||||
if (mLocalBluetoothManager == null) {
|
||||
Log.i(TAG, "onSliceUnpinned() Bluetooth is unsupported.");
|
||||
final LocalBluetoothManager localBtManager = mLoadBtManagerHandler.getLocalBtManager();
|
||||
if (localBtManager == null) {
|
||||
return;
|
||||
}
|
||||
mLocalBluetoothManager.getEventManager().unregisterCallback(this);
|
||||
localBtManager.getEventManager().unregisterCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,4 +106,59 @@ public class BluetoothUpdateWorker extends SliceBackgroundWorker implements Blue
|
||||
int bluetoothProfile) {
|
||||
notifySliceChange();
|
||||
}
|
||||
|
||||
private static class LoadBtManagerHandler extends Handler {
|
||||
|
||||
private static LoadBtManagerHandler sHandler;
|
||||
|
||||
private final Runnable mLoadBtManagerTask;
|
||||
private final Context mContext;
|
||||
private BluetoothUpdateWorker mWorker;
|
||||
|
||||
private static LoadBtManagerHandler getInstance(Context context) {
|
||||
if (sHandler == null) {
|
||||
final HandlerThread workerThread = new HandlerThread(TAG,
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
workerThread.start();
|
||||
sHandler = new LoadBtManagerHandler(context, workerThread.getLooper());
|
||||
}
|
||||
return sHandler;
|
||||
}
|
||||
|
||||
private LoadBtManagerHandler(Context context, Looper looper) {
|
||||
super(looper);
|
||||
mContext = context;
|
||||
mLoadBtManagerTask = () -> {
|
||||
Log.d(TAG, "LoadBtManagerHandler: start loading...");
|
||||
final long startTime = System.currentTimeMillis();
|
||||
sLocalBluetoothManager = getLocalBtManager();
|
||||
Log.d(TAG, "LoadBtManagerHandler took " + (System.currentTimeMillis() - startTime)
|
||||
+ " ms");
|
||||
};
|
||||
}
|
||||
|
||||
private LocalBluetoothManager getLocalBtManager() {
|
||||
if (sLocalBluetoothManager != null) {
|
||||
return sLocalBluetoothManager;
|
||||
}
|
||||
return LocalBluetoothManager.getInstance(mContext,
|
||||
(context, btManager) -> {
|
||||
if (mWorker != null) {
|
||||
// notify change if the worker is ready
|
||||
mWorker.notifySliceChange();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startLoadingBtManager() {
|
||||
if (!hasCallbacks(mLoadBtManagerTask)) {
|
||||
post(mLoadBtManagerTask);
|
||||
}
|
||||
}
|
||||
|
||||
private void startLoadingBtManager(BluetoothUpdateWorker worker) {
|
||||
mWorker = worker;
|
||||
startLoadingBtManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,9 @@ import android.text.BidiFormatter;
|
||||
import android.text.TextDirectionHeuristics;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.telephony.OperatorInfo;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -99,6 +102,35 @@ public final class CellInfoUtil {
|
||||
return cellId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CellInfo object from OperatorInfo. GsmCellInfo is used here only because
|
||||
* operatorInfo does not contain technology type while CellInfo is an abstract object that
|
||||
* requires to specify technology type. It doesn't matter which CellInfo type to use here, since
|
||||
* we only want to wrap the operator info and PLMN to a CellInfo object.
|
||||
*/
|
||||
public static CellInfo convertOperatorInfoToCellInfo(OperatorInfo operatorInfo) {
|
||||
final String operatorNumeric = operatorInfo.getOperatorNumeric();
|
||||
String mcc = null;
|
||||
String mnc = null;
|
||||
if (operatorNumeric != null && operatorNumeric.matches("^[0-9]{5,6}$")) {
|
||||
mcc = operatorNumeric.substring(0, 3);
|
||||
mnc = operatorNumeric.substring(3);
|
||||
}
|
||||
final CellIdentityGsm cig = new CellIdentityGsm(
|
||||
Integer.MAX_VALUE /* lac */,
|
||||
Integer.MAX_VALUE /* cid */,
|
||||
Integer.MAX_VALUE /* arfcn */,
|
||||
Integer.MAX_VALUE /* bsic */,
|
||||
mcc,
|
||||
mnc,
|
||||
operatorInfo.getOperatorAlphaLong(),
|
||||
operatorInfo.getOperatorAlphaShort(),
|
||||
Collections.emptyList());
|
||||
|
||||
final CellInfoGsm ci = new CellInfoGsm();
|
||||
ci.setCellIdentity(cig);
|
||||
return ci;
|
||||
}
|
||||
|
||||
/** Convert a list of cellInfos to readable string without sensitive info. */
|
||||
public static String cellInfoListToString(List<CellInfo> cellInfos) {
|
||||
|
||||
@@ -57,6 +57,7 @@ public class NetworkOperatorPreference extends Preference {
|
||||
private List<String> mForbiddenPlmns;
|
||||
private int mLevel = LEVEL_NONE;
|
||||
private boolean mShow4GForLTE;
|
||||
private boolean mUseNewApi;
|
||||
|
||||
public NetworkOperatorPreference(Context context, CellInfo cellinfo,
|
||||
List<String> forbiddenPlmns, boolean show4GForLTE) {
|
||||
@@ -75,6 +76,8 @@ public class NetworkOperatorPreference extends Preference {
|
||||
super(context);
|
||||
mForbiddenPlmns = forbiddenPlmns;
|
||||
mShow4GForLTE = show4GForLTE;
|
||||
mUseNewApi = context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,7 +218,7 @@ public class NetworkOperatorPreference extends Preference {
|
||||
}
|
||||
|
||||
private void updateIcon(int level) {
|
||||
if (level < 0 || level >= NUM_SIGNAL_STRENGTH_BINS) {
|
||||
if (!mUseNewApi || level < 0 || level >= NUM_SIGNAL_STRENGTH_BINS) {
|
||||
return;
|
||||
}
|
||||
final Context context = getContext();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.telephony.AccessNetworkConstants.AccessNetworkType;
|
||||
import android.telephony.CellInfo;
|
||||
import android.telephony.NetworkScan;
|
||||
@@ -25,9 +26,21 @@ import android.telephony.TelephonyManager;
|
||||
import android.telephony.TelephonyScanManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.telephony.CellNetworkScanResult;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A helper class that builds the common interface and performs the network scan for two different
|
||||
@@ -70,6 +83,33 @@ public class NetworkScanHelper {
|
||||
void onError(int errorCode);
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS, NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS})
|
||||
public @interface NetworkQueryType {}
|
||||
|
||||
/**
|
||||
* Performs the network scan using {@link TelephonyManager#getAvailableNetworks()}. The network
|
||||
* scan results won't be returned to the caller until the network scan is completed.
|
||||
*
|
||||
* <p> This is typically used when the modem doesn't support the new network scan api
|
||||
* {@link TelephonyManager#requestNetworkScan(
|
||||
* NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
|
||||
*/
|
||||
public static final int NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS = 1;
|
||||
|
||||
/**
|
||||
* Performs the network scan using {@link TelephonyManager#requestNetworkScan(
|
||||
* NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)} The network scan
|
||||
* results will be returned to the caller periodically in a small time window until the network
|
||||
* scan is completed. The complete results should be returned in the last called of
|
||||
* {@link NetworkScanCallback#onResults(List)}.
|
||||
*
|
||||
* <p> This is recommended to be used if modem supports the new network scan api
|
||||
* {@link TelephonyManager#requestNetworkScan(
|
||||
* NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}
|
||||
*/
|
||||
public static final int NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS = 2;
|
||||
|
||||
/** The constants below are used in the async network scan. */
|
||||
private static final boolean INCREMENTAL_RESULTS = true;
|
||||
private static final int SEARCH_PERIODICITY_SEC = 5;
|
||||
@@ -83,6 +123,9 @@ public class NetworkScanHelper {
|
||||
|
||||
private NetworkScan mNetworkScanRequester;
|
||||
|
||||
/** Callbacks for sync network scan */
|
||||
private ListenableFuture<List<CellInfo>> mNetworkScanFuture;
|
||||
|
||||
public NetworkScanHelper(TelephonyManager tm, NetworkScanCallback callback, Executor executor) {
|
||||
mTelephonyManager = tm;
|
||||
mNetworkScanCallback = callback;
|
||||
@@ -139,38 +182,63 @@ public class NetworkScanHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a network scan.
|
||||
* Performs a network scan for the given type {@code type}.
|
||||
* {@link #NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS} is recommended if modem supports
|
||||
* {@link TelephonyManager#requestNetworkScan(
|
||||
* NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
|
||||
*
|
||||
* Performs the network scan using {@link TelephonyManager#requestNetworkScan(
|
||||
* NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)} The network scan
|
||||
* results will be returned to the caller periodically in a small time window until the network
|
||||
* scan is completed. The complete results should be returned in the last called of
|
||||
* {@link NetworkScanCallback#onResults(List)}.
|
||||
* @param type used to tell which network scan API should be used.
|
||||
*/
|
||||
public void startNetworkScan() {
|
||||
if (mNetworkScanRequester != null) {
|
||||
return;
|
||||
}
|
||||
mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
|
||||
createNetworkScanForPreferredAccessNetworks(),
|
||||
mExecutor,
|
||||
mInternalNetworkScanCallback);
|
||||
if (mNetworkScanRequester == null) {
|
||||
onError(NetworkScan.ERROR_RADIO_INTERFACE_ERROR);
|
||||
public void startNetworkScan(@NetworkQueryType int type) {
|
||||
if (type == NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS) {
|
||||
mNetworkScanFuture = SettableFuture.create();
|
||||
Futures.addCallback(mNetworkScanFuture, new FutureCallback<List<CellInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(List<CellInfo> result) {
|
||||
onResults(result);
|
||||
onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
if (t instanceof CancellationException) {
|
||||
return;
|
||||
}
|
||||
int errCode = Integer.parseInt(t.getMessage());
|
||||
onError(errCode);
|
||||
}
|
||||
}, MoreExecutors.directExecutor());
|
||||
mExecutor.execute(new NetworkScanSyncTask(
|
||||
mTelephonyManager, (SettableFuture) mNetworkScanFuture));
|
||||
} else if (type == NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS) {
|
||||
if (mNetworkScanRequester != null) {
|
||||
return;
|
||||
}
|
||||
mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
|
||||
createNetworkScanForPreferredAccessNetworks(),
|
||||
mExecutor,
|
||||
mInternalNetworkScanCallback);
|
||||
if (mNetworkScanRequester == null) {
|
||||
onError(NetworkScan.ERROR_RADIO_INTERFACE_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the network scan.
|
||||
*
|
||||
* Use this method to stop an ongoing scan. When user requests a new scan, a {@link NetworkScan}
|
||||
* object will be returned, and the user can stop the scan by calling this method.
|
||||
* The network scan of type {@link #NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS} can't be stopped,
|
||||
* however, the result of the current network scan won't be returned to the callback after
|
||||
* calling this method.
|
||||
*/
|
||||
public void stopNetworkQuery() {
|
||||
if (mNetworkScanRequester != null) {
|
||||
mNetworkScanRequester.stopScan();
|
||||
mNetworkScanRequester = null;
|
||||
}
|
||||
|
||||
if (mNetworkScanFuture != null) {
|
||||
mNetworkScanFuture.cancel(true /* mayInterruptIfRunning */);
|
||||
mNetworkScanFuture = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void onResults(List<CellInfo> cellInfos) {
|
||||
@@ -185,6 +253,23 @@ public class NetworkScanHelper {
|
||||
mNetworkScanCallback.onError(errCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the status code of {@link CellNetworkScanResult} to one of the
|
||||
* {@link NetworkScan.ScanErrorCode}.
|
||||
* @param errCode status code from {@link CellNetworkScanResult}.
|
||||
*
|
||||
* @return one of the scan error code from {@link NetworkScan.ScanErrorCode}.
|
||||
*/
|
||||
private static int convertToScanErrorCode(int errCode) {
|
||||
switch (errCode) {
|
||||
case CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE:
|
||||
return NetworkScan.ERROR_RADIO_INTERFACE_ERROR;
|
||||
case CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE:
|
||||
default:
|
||||
return NetworkScan.ERROR_MODEM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private final class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback {
|
||||
public void onResults(List<CellInfo> results) {
|
||||
Log.d(TAG, "Async scan onResults() results = "
|
||||
@@ -202,4 +287,35 @@ public class NetworkScanHelper {
|
||||
NetworkScanHelper.this.onError(errCode);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class NetworkScanSyncTask implements Runnable {
|
||||
private final SettableFuture<List<CellInfo>> mCallback;
|
||||
private final TelephonyManager mTelephonyManager;
|
||||
|
||||
NetworkScanSyncTask(
|
||||
TelephonyManager telephonyManager, SettableFuture<List<CellInfo>> callback) {
|
||||
mTelephonyManager = telephonyManager;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final CellNetworkScanResult result = mTelephonyManager.getAvailableNetworks();
|
||||
if (result.getStatus() == CellNetworkScanResult.STATUS_SUCCESS) {
|
||||
final List<CellInfo> cellInfos = result.getOperators()
|
||||
.stream()
|
||||
.map(operatorInfo
|
||||
-> CellInfoUtil.convertOperatorInfoToCellInfo(operatorInfo))
|
||||
.collect(Collectors.toList());
|
||||
Log.d(TAG, "Sync network scan completed, cellInfos = "
|
||||
+ CellInfoUtil.cellInfoListToString(cellInfos));
|
||||
mCallback.set(cellInfos);
|
||||
} else {
|
||||
final Throwable error = new Throwable(
|
||||
Integer.toString(convertToScanErrorCode(result.getStatus())));
|
||||
mCallback.setException(error);
|
||||
Log.d(TAG, "Sync network scan error, ex = " + error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,8 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
mUseNewApi = getContext().getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
|
||||
mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID);
|
||||
|
||||
mPreferenceCategory = findPreference(PREF_KEY_NETWORK_OPERATORS);
|
||||
@@ -464,7 +466,10 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
if (mNetworkScanHelper != null) {
|
||||
mRequestIdManualNetworkScan = getNewRequestId();
|
||||
mWaitingForNumberOfScanResults = MIN_NUMBER_OF_SCAN_REQUIRED;
|
||||
mNetworkScanHelper.startNetworkScan();
|
||||
mNetworkScanHelper.startNetworkScan(
|
||||
mUseNewApi
|
||||
? NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS
|
||||
: NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ public class PanelFragment extends Fragment {
|
||||
private ImageView mTitleIcon;
|
||||
private TextView mHeaderTitle;
|
||||
private TextView mHeaderSubtitle;
|
||||
private int mMaxHeight;
|
||||
|
||||
private final Map<Uri, LiveData<Slice>> mSliceLiveData = new LinkedHashMap<>();
|
||||
|
||||
@@ -105,6 +106,18 @@ public class PanelFragment extends Fragment {
|
||||
return false;
|
||||
};
|
||||
|
||||
private final ViewTreeObserver.OnGlobalLayoutListener mPanelLayoutListener =
|
||||
new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
if (mLayoutView.getHeight() > mMaxHeight) {
|
||||
final ViewGroup.LayoutParams params = mLayoutView.getLayoutParams();
|
||||
params.height = mMaxHeight;
|
||||
mLayoutView.setLayoutParams(params);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener =
|
||||
new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
@@ -123,6 +136,9 @@ public class PanelFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
mLayoutView = inflater.inflate(R.layout.panel_layout, container, false);
|
||||
mLayoutView.getViewTreeObserver()
|
||||
.addOnGlobalLayoutListener(mPanelLayoutListener);
|
||||
mMaxHeight = getResources().getDimensionPixelSize(R.dimen.output_switcher_slice_max_height);
|
||||
createPanelContent();
|
||||
return mLayoutView;
|
||||
}
|
||||
@@ -159,6 +175,9 @@ public class PanelFragment extends Fragment {
|
||||
if (mLayoutView == null) {
|
||||
activity.finish();
|
||||
}
|
||||
final ViewGroup.LayoutParams params = mLayoutView.getLayoutParams();
|
||||
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
mLayoutView.setLayoutParams(params);
|
||||
|
||||
mPanelSlices = mLayoutView.findViewById(R.id.panel_parent_layout);
|
||||
mSeeMoreButton = mLayoutView.findViewById(R.id.see_more);
|
||||
@@ -214,6 +233,12 @@ public class PanelFragment extends Fragment {
|
||||
mHeaderSubtitle.setText(mPanel.getSubTitle());
|
||||
if (mPanel.getHeaderIconIntent() != null) {
|
||||
mTitleIcon.setOnClickListener(getHeaderIconListener());
|
||||
mTitleIcon.setLayoutParams(new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
} else {
|
||||
final int size = getResources().getDimensionPixelSize(
|
||||
R.dimen.output_switcher_panel_icon_size);
|
||||
mTitleIcon.setLayoutParams(new LinearLayout.LayoutParams(size, size));
|
||||
}
|
||||
}
|
||||
mSeeMoreButton.setOnClickListener(getSeeMoreListener());
|
||||
@@ -378,6 +403,9 @@ public class PanelFragment extends Fragment {
|
||||
mPanelClosedKey = PanelClosedKeys.KEY_OTHERS;
|
||||
}
|
||||
|
||||
if (mLayoutView != null) {
|
||||
mLayoutView.getViewTreeObserver().removeOnGlobalLayoutListener(mPanelLayoutListener);
|
||||
}
|
||||
mMetricsProvider.action(
|
||||
0 /* attribution */,
|
||||
SettingsEnums.PAGE_HIDE,
|
||||
|
||||
@@ -216,13 +216,12 @@ public class NetworkRequestDialogActivity extends FragmentActivity implements
|
||||
|
||||
@Override
|
||||
public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
|
||||
if (mIsSpecifiedSsid) {
|
||||
showSingleSsidRequestDialog(
|
||||
WifiInfo.sanitizeSsid(mMatchedConfig.SSID), true /* isTryAgain */);
|
||||
return;
|
||||
if (!isFinishing()) {
|
||||
Toast.makeText(this, R.string.network_connection_connect_failure, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
|
||||
mDialogFragment.onUserSelectionConnectFailure(wificonfiguration);
|
||||
}
|
||||
|
||||
// Called when user click "Connect" button. Called by
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -91,7 +90,4 @@ abstract public class NetworkRequestDialogBaseFragment extends InstrumentedDialo
|
||||
|
||||
protected void onMatch(List<ScanResult> scanResults) {
|
||||
}
|
||||
|
||||
protected void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,11 +324,6 @@ public class NetworkRequestDialogFragment extends NetworkRequestDialogBaseFragme
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
|
||||
// Do nothing when selection is failed, let user could try again easily.
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
final class FilterWifiTracker {
|
||||
private final List<String> mAccessPointKeys;
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.android.settings.applications;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -28,6 +28,10 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ModuleInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
@@ -51,6 +55,8 @@ public class AppStorageSettingsTest {
|
||||
private AppStorageSettings mSettings;
|
||||
private Button mLeftButton;
|
||||
private Button mRightButton;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -58,6 +64,8 @@ public class AppStorageSettingsTest {
|
||||
mLeftButton = new Button(RuntimeEnvironment.application);
|
||||
mRightButton = new Button(RuntimeEnvironment.application);
|
||||
mSettings = spy(new AppStorageSettings());
|
||||
mSettings.mPm = mPackageManager;
|
||||
mSettings.mPackageName = "Package";
|
||||
mSettings.mSizeController = mSizesController;
|
||||
mButtonsPref = createMock();
|
||||
mSettings.mButtonsPref = mButtonsPref;
|
||||
@@ -77,7 +85,9 @@ public class AppStorageSettingsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiWithSize_noAppStats_shouldDisableClearButtons() {
|
||||
public void updateUiWithSize_noAppStats_shouldDisableClearButtons()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
mockMainlineModule(mSettings.mPackageName, false /* isMainlineModule */);
|
||||
mSettings.updateUiWithSize(null);
|
||||
|
||||
verify(mSizesController).updateUi(nullable(Context.class));
|
||||
@@ -86,12 +96,15 @@ public class AppStorageSettingsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiWithSize_hasDataAndCache_shouldEnableClearButtons() {
|
||||
public void updateUiWithSize_hasDataAndCache_shouldEnableClearButtons()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final AppStorageStats stats = mock(AppStorageStats.class);
|
||||
when(stats.getCacheBytes()).thenReturn(5000L);
|
||||
when(stats.getDataBytes()).thenReturn(10000L);
|
||||
doNothing().when(mSettings).handleClearCacheClick();
|
||||
doNothing().when(mSettings).handleClearDataClick();
|
||||
mockMainlineModule(mSettings.mPackageName, false /* isMainlineModule */);
|
||||
|
||||
|
||||
mSettings.updateUiWithSize(stats);
|
||||
verify(mButtonsPref).setButton1Enabled(true);
|
||||
@@ -105,6 +118,22 @@ public class AppStorageSettingsTest {
|
||||
verify(mSettings).handleClearCacheClick();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiWithSize_mainlineModule_shouldDisableClearButtons()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final AppStorageStats stats = mock(AppStorageStats.class);
|
||||
when(stats.getCacheBytes()).thenReturn(5000L);
|
||||
when(stats.getDataBytes()).thenReturn(10000L);
|
||||
doNothing().when(mSettings).handleClearCacheClick();
|
||||
doNothing().when(mSettings).handleClearDataClick();
|
||||
mockMainlineModule(mSettings.mPackageName, true /* isMainlineModule */);
|
||||
|
||||
|
||||
mSettings.updateUiWithSize(stats);
|
||||
verify(mButtonsPref).setButton1Enabled(false);
|
||||
verify(mButtonsPref).setButton2Enabled(false);
|
||||
}
|
||||
|
||||
private ActionButtonsPreference createMock() {
|
||||
final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
|
||||
when(pref.setButton1Text(anyInt())).thenReturn(pref);
|
||||
@@ -121,5 +150,23 @@ public class AppStorageSettingsTest {
|
||||
|
||||
return pref;
|
||||
}
|
||||
|
||||
private void mockMainlineModule(String packageName, boolean isMainlineModule)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final PackageInfo packageInfo = new PackageInfo();
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.sourceDir = "apex";
|
||||
packageInfo.applicationInfo = applicationInfo;
|
||||
|
||||
if (isMainlineModule) {
|
||||
when(mPackageManager.getModuleInfo(packageName, 0 /* flags */)).thenReturn(
|
||||
new ModuleInfo());
|
||||
} else {
|
||||
when(mPackageManager.getPackageInfo(packageName, 0 /* flags */)).thenReturn(
|
||||
packageInfo);
|
||||
when(mPackageManager.getModuleInfo(packageName, 0 /* flags */)).thenThrow(
|
||||
new PackageManager.NameNotFoundException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -543,6 +543,19 @@ public class AppButtonsPreferenceControllerTest {
|
||||
assertThat(i.getBooleanExtra(KEY_REMOVE_TASK_WHEN_FINISHING, false)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowAppUtils.class)
|
||||
public void isAvailable_nonMainlineModule_isTrue() {
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowAppUtils.class)
|
||||
public void isAvailable_mainlineModule_isFalse() {
|
||||
ShadowAppUtils.addMainlineModule(mController.mPackageName);
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
/**
|
||||
* The test fragment which implements
|
||||
* {@link ButtonActionDialogFragment.AppButtonsDialogListener}
|
||||
@@ -597,16 +610,22 @@ public class AppButtonsPreferenceControllerTest {
|
||||
public static class ShadowAppUtils {
|
||||
|
||||
public static Set<String> sSystemModules = new ArraySet<>();
|
||||
public static Set<String> sMainlineModules = new ArraySet<>();
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sSystemModules.clear();
|
||||
sMainlineModules.clear();
|
||||
}
|
||||
|
||||
public static void addHiddenModule(String pkg) {
|
||||
sSystemModules.add(pkg);
|
||||
}
|
||||
|
||||
public static void addMainlineModule(String pkg) {
|
||||
sMainlineModules.add(pkg);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isInstant(ApplicationInfo info) {
|
||||
return false;
|
||||
@@ -616,5 +635,10 @@ public class AppButtonsPreferenceControllerTest {
|
||||
protected static boolean isSystemModule(Context context, String packageName) {
|
||||
return sSystemModules.contains(packageName);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isMainlineModule(PackageManager pm, String packageName) {
|
||||
return sMainlineModules.contains(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,12 +99,15 @@ public class AppInstallerInfoPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_hasAppLabel_shouldReturnAvailable() {
|
||||
public void getAvailabilityStatus_hasAppLabel_shouldReturnAvailable()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final String packageName = "Package1";
|
||||
when(mUserManager.isManagedProfile()).thenReturn(false);
|
||||
when(mAppInfo.loadLabel(mPackageManager)).thenReturn("Label1");
|
||||
mController = new AppInstallerInfoPreferenceController(mContext, "test_key");
|
||||
mController.setPackageName("Package1");
|
||||
mController.setPackageName(packageName);
|
||||
mController.setParentFragment(mFragment);
|
||||
mockMainlineModule(packageName, false /* isMainlineModule */);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||
@@ -153,12 +156,31 @@ public class AppInstallerInfoPreferenceControllerTest {
|
||||
@Test
|
||||
public void getAvailabilityStatus_isMainlineModule_shouldReturnDisabled()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final String packageName = "Package";
|
||||
when(mUserManager.isManagedProfile()).thenReturn(false);
|
||||
when(mAppInfo.loadLabel(mPackageManager)).thenReturn("Label");
|
||||
mController.setPackageName("Package");
|
||||
when(mPackageManager.getModuleInfo("Package", 0 /* flags */)).thenReturn(new ModuleInfo());
|
||||
mController.setPackageName(packageName);
|
||||
mockMainlineModule(packageName, true /* isMainlineModule */);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.DISABLED_FOR_USER);
|
||||
}
|
||||
|
||||
private void mockMainlineModule(String packageName, boolean isMainlineModule)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final PackageInfo packageInfo = new PackageInfo();
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.sourceDir = "apex";
|
||||
packageInfo.applicationInfo = applicationInfo;
|
||||
|
||||
if (isMainlineModule) {
|
||||
when(mPackageManager.getModuleInfo(packageName, 0 /* flags */)).thenReturn(
|
||||
new ModuleInfo());
|
||||
} else {
|
||||
when(mPackageManager.getPackageInfo(packageName, 0 /* flags */)).thenReturn(
|
||||
packageInfo);
|
||||
when(mPackageManager.getModuleInfo(packageName, 0 /* flags */)).thenThrow(
|
||||
new PackageManager.NameNotFoundException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,8 @@ public class NetworkScanHelperTest {
|
||||
}
|
||||
|
||||
private void startNetworkScan_incremental(boolean waitForCompletion) {
|
||||
mNetworkScanHelper.startNetworkScan();
|
||||
mNetworkScanHelper.startNetworkScan(
|
||||
NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS);
|
||||
if (!waitForCompletion) {
|
||||
mNetworkScanHelper.stopNetworkQuery();
|
||||
}
|
||||
|
||||
@@ -126,4 +126,13 @@ public class NetworkRequestDialogActivityTest {
|
||||
|
||||
verify(mActivity).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateAccessPointList_onUserSelectionConnectFailure_shouldFinishActivity() {
|
||||
final WifiConfiguration config = new WifiConfiguration();
|
||||
config.SSID = "Test AP 3";
|
||||
mActivity.onUserSelectionConnectFailure(config);
|
||||
|
||||
verify(mActivity).finish();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user