Merge "RadioInfo: Disable ims provisioning switches in USER-build" am: 61c5a296e6
am: 59eb9e9d90
Change-Id: Ia0f24f55c529b166cfcd2bba4ca7af85d2e70759
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2f910e4..ba407c9 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -727,7 +727,6 @@
android:label="@string/zen_mode_settings_title"
android:icon="@drawable/ic_notifications"
android:exported="true"
- android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
<intent-filter android:priority="1">
<action android:name="android.settings.ZEN_MODE_SETTINGS" />
@@ -929,7 +928,6 @@
android:label="@string/night_display_title"
android:enabled="@*android:bool/config_nightDisplayAvailable"
android:icon="@drawable/ic_settings_night_display"
- android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -2616,7 +2614,6 @@
<activity
android:name="Settings$ZenAccessSettingsActivity"
android:label="@string/manage_zen_access_title"
- android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
<intent-filter android:priority="1">
<action android:name="android.settings.NOTIFICATION_POLICY_ACCESS_SETTINGS" />
@@ -3313,10 +3310,15 @@
</provider>
<receiver
- android:name=".slices.SliceBroadcastReceiver" >
- <intent-filter>
- <action android:name="com.android.settings.slice.action.WIFI_CHANGED"/>
- </intent-filter>
+ android:name=".slices.SliceBroadcastReceiver"
+ android:exported="false">
+ </receiver>
+
+ <receiver
+ android:name=".slices.SliceRelayReceiver"
+ android:permission="android.permission.MANAGE_SLICE_PERMISSIONS"
+ android:exported="true">
+
</receiver>
<!-- Couldn't be triggered from outside of settings. Statsd can trigger it because we send
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d3d4e6d..e2a4773 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9413,13 +9413,13 @@
<string name="notification_log_details_ranking_none">Ranking object doesn\'t contain this key.</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which turns on emulation of a display cutout. -->
- <string name="display_cutout_emulation">Simulate a display with a cutout</string>
+ <string name="display_cutout_emulation">Display cutout</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Search keywords for the setting which turns on emulation of a display cutout. -->
<string name="display_cutout_emulation_keywords">display cutout, notch</string>
- <!-- [CHAR_LIMIT=NONE] Developer Settings: Label for the option that turns off display cutout emulation. -->
- <string name="display_cutout_emulation_none">None</string>
+ <!-- [CHAR_LIMIT=NONE] Developer Settings: Label for the option that turns off display cutout emulation, (i.e. on devices whose screen actually has a cutout, selecting this option will show that cutout).-->
+ <string name="display_cutout_emulation_device_default">Device default</string>
<!-- [CHAR_LIMIT=60] Label for special access screen -->
<string name="special_access">Special app access</string>
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index 3dac8b8..3d499ab 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -71,10 +71,18 @@
<intent android:action="android.settings.SHOW_REGULATORY_INFO"/>
</Preference>
+ <!-- Safety & regulatory manual -->
+ <Preference
+ android:key="safety_info"
+ android:order="7"
+ android:title="@string/safety_and_regulatory_info">
+ <intent android:action="android.settings.SHOW_SAFETY_AND_REGULATORY_INFO"/>
+ </Preference>
+
<!-- SIM status -->
<Preference
android:key="sim_status"
- android:order="7"
+ android:order="8"
android:title="@string/sim_status_title"
settings:keywords="@string/keywords_sim_status"
android:summary="@string/summary_placeholder"
@@ -129,14 +137,6 @@
android:summary="@string/summary_placeholder"
android:selectable="false"/>
- <!-- Safety & regulatory manual -->
- <Preference
- android:key="safety_info"
- android:order="39"
- android:title="@string/safety_and_regulatory_info">
- <intent android:action="android.settings.SHOW_SAFETY_AND_REGULATORY_INFO"/>
- </Preference>
-
<!-- Manual -->
<Preference
android:key="manual"
@@ -166,4 +166,4 @@
android:summary="@string/summary_placeholder"
settings:allowDividerAbove="true"/>
-</PreferenceScreen>
\ No newline at end of file
+</PreferenceScreen>
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 7e77047..644bcee 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -291,8 +291,10 @@
launchSettingFragment(initialFragmentName, isSubSettings, intent);
}
+ final boolean deviceProvisioned = Utils.isDeviceProvisioned(this);
if (mIsShowingDashboard) {
- findViewById(R.id.search_bar).setVisibility(View.VISIBLE);
+ findViewById(R.id.search_bar).setVisibility(
+ deviceProvisioned ? View.VISIBLE : View.INVISIBLE);
findViewById(R.id.action_bar).setVisibility(View.GONE);
final Toolbar toolbar = findViewById(R.id.search_action_bar);
FeatureFactory.getFactory(this).getSearchFeatureProvider()
@@ -311,7 +313,6 @@
ActionBar actionBar = getActionBar();
if (actionBar != null) {
- boolean deviceProvisioned = Utils.isDeviceProvisioned(this);
actionBar.setDisplayHomeAsUpEnabled(deviceProvisioned);
actionBar.setHomeButtonEnabled(deviceProvisioned);
actionBar.setDisplayShowTitleEnabled(!mIsShowingDashboard);
diff --git a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
index 930d9ff..1da1cae 100644
--- a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
@@ -97,6 +97,11 @@
if (DBG) {
Log.d(TAG, "isFilterMatched() current audio profile : " + currentAudioProfile);
}
+ // If device is Hearing Aid, it is compatible with HFP and A2DP.
+ // It would show in Available Devices group.
+ if (cachedDevice.isConnectedHearingAidDevice()) {
+ return true;
+ }
// According to the current audio profile type,
// this page will show the bluetooth device that have corresponding profile.
// For example:
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
index dca7e20..0bfc494 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
@@ -18,9 +18,11 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.util.Pair;
+
import androidx.preference.PreferenceFragment;
import androidx.preference.PreferenceScreen;
-import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
@@ -36,6 +38,7 @@
*/
public class BluetoothDetailsHeaderController extends BluetoothDetailsController {
private static final String KEY_DEVICE_HEADER = "bluetooth_device_header";
+ private static final String TAG = "BluetoothDetailsHeaderController";
private EntityHeaderController mHeaderController;
private LocalBluetoothManager mLocalManager;
@@ -63,12 +66,16 @@
.getBtClassDrawableWithDescription(mContext, mCachedDevice,
mContext.getResources().getFraction(R.fraction.bt_battery_scale_fraction, 1, 1));
String summaryText = mCachedDevice.getConnectionSummary();
- // If both the hearing aids are connected, two battery status should be shown.
- final String pairDeviceSummary = mDeviceManager
- .getHearingAidPairDeviceSummary(mCachedDevice);
- if (pairDeviceSummary != null) {
+
+ if (mCachedDevice.isHearingAidDevice()) {
+ // For Hearing Aid device, display the other battery status.
+ final String pairDeviceSummary = mDeviceManager
+ .getHearingAidPairDeviceSummary(mCachedDevice);
+ Log.d(TAG, "setHeaderProperties: HearingAid: summaryText=" + summaryText
+ + ", pairDeviceSummary=" + pairDeviceSummary);
mHeaderController.setSecondSummary(pairDeviceSummary);
}
+
mHeaderController.setLabel(mCachedDevice.getName());
mHeaderController.setIcon(pair.first);
mHeaderController.setIconContentDescription(pair.second);
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingController.java b/src/com/android/settings/bluetooth/BluetoothPairingController.java
index 5120cc0..c39f1d9 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingController.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingController.java
@@ -23,10 +23,14 @@
import android.util.Log;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
+
+import androidx.annotation.VisibleForTesting;
+
import com.android.settings.R;
import com.android.settings.bluetooth.BluetoothPairingDialogFragment.BluetoothPairingDialogListener;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
+
import java.util.Locale;
/**
@@ -50,8 +54,10 @@
// Bluetooth dependencies for the connection we are trying to establish
private LocalBluetoothManager mBluetoothManager;
- private BluetoothDevice mDevice;
- private int mType;
+ @VisibleForTesting
+ BluetoothDevice mDevice;
+ @VisibleForTesting
+ int mType;
private String mUserInput;
private String mPasskeyFormatted;
private int mPasskey;
@@ -82,7 +88,6 @@
mDeviceName = mBluetoothManager.getCachedDeviceManager().getName(mDevice);
mPbapClientProfile = mBluetoothManager.getProfileManager().getPbapClientProfile();
mPasskeyFormatted = formatKey(mPasskey);
-
}
@Override
@@ -96,12 +101,13 @@
@Override
public void onDialogPositiveClick(BluetoothPairingDialogFragment dialog) {
+ if (mPbapAllowed) {
+ mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
+ } else {
+ mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_REJECTED);
+ }
+
if (getDialogType() == USER_ENTRY_DIALOG) {
- if (mPbapAllowed) {
- mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
- } else {
- mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_REJECTED);
- }
onPair(mUserInput);
} else {
onPair(null);
diff --git a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
index c22aa5a..845d2e2 100644
--- a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
@@ -97,6 +97,11 @@
if (DBG) {
Log.d(TAG, "isFilterMatched() current audio profile : " + currentAudioProfile);
}
+ // If device is Hearing Aid, it is compatible with HFP and A2DP.
+ // It would not show in Connected Devices group.
+ if (cachedDevice.isConnectedHearingAidDevice()) {
+ return false;
+ }
// According to the current audio profile type,
// this page will show the bluetooth device that doesn't have corresponding profile.
// For example:
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index e77c27b..db941a6 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -26,4 +26,5 @@
public static final String BLUETOOTH_WHILE_DRIVING = "settings_bluetooth_while_driving";
public static final String DATA_USAGE_SETTINGS_V2 = "settings_data_usage_v2";
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
+ public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
}
diff --git a/src/com/android/settings/development/EmulateDisplayCutoutPreferenceController.java b/src/com/android/settings/development/EmulateDisplayCutoutPreferenceController.java
index 3d551cd..c9bb9b7 100644
--- a/src/com/android/settings/development/EmulateDisplayCutoutPreferenceController.java
+++ b/src/com/android/settings/development/EmulateDisplayCutoutPreferenceController.java
@@ -33,6 +33,7 @@
import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+import java.util.Comparator;
import java.util.List;
public class EmulateDisplayCutoutPreferenceController extends
@@ -40,6 +41,8 @@
PreferenceControllerMixin {
private static final String KEY = "display_cutout_emulation";
+ private static final Comparator<OverlayInfo> OVERLAY_INFO_COMPARATOR =
+ Comparator.comparingInt(a -> a.priority);
private final OverlayManagerWrapper mOverlayManager;
private final boolean mAvailable;
@@ -120,7 +123,7 @@
int current = 0;
pkgs[0] = "";
- labels[0] = mContext.getString(R.string.display_cutout_emulation_none);
+ labels[0] = mContext.getString(R.string.display_cutout_emulation_device_default);
for (int i = 0; i < overlays.length; i++) {
OverlayInfo o = overlays[i];
@@ -153,6 +156,7 @@
overlayInfos.remove(i);
}
}
+ overlayInfos.sort(OVERLAY_INFO_COMPARATOR);
return overlayInfos.toArray(new OverlayInfo[overlayInfos.size()]);
}
diff --git a/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java b/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java
new file mode 100644
index 0000000..30d5cd7
--- /dev/null
+++ b/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 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.featureflags;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.core.FeatureFlags;
+
+import java.util.HashSet;
+
+/**
+ * Helper class to get feature persistent flag information.
+ */
+public class FeatureFlagPersistent {
+ private static final HashSet<String> PERSISTENT_FLAGS;
+ static {
+ PERSISTENT_FLAGS = new HashSet<>();
+ PERSISTENT_FLAGS.add(FeatureFlags.HEARING_AID_SETTINGS);
+ }
+
+ public static boolean isEnabled(Context context, String feature) {
+ String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + feature);
+ if (!TextUtils.isEmpty(value)) {
+ return Boolean.parseBoolean(value);
+ } else {
+ return FeatureFlagUtils.isEnabled(context, feature);
+ }
+ }
+
+ public static void setEnabled(Context context, String feature, boolean enabled) {
+ SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + feature, enabled ? "true" : "false");
+ FeatureFlagUtils.setEnabled(context, feature, enabled);
+ }
+
+ public static boolean isPersistent(String feature) {
+ return PERSISTENT_FLAGS.contains(feature);
+ }
+
+ /**
+ * Returns all persistent flags in their raw form.
+ */
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ static HashSet<String> getAllPersistentFlags() {
+ return PERSISTENT_FLAGS;
+ }
+}
+
diff --git a/src/com/android/settings/development/featureflags/FeatureFlagPreference.java b/src/com/android/settings/development/featureflags/FeatureFlagPreference.java
index 7dd8f28..16a5be1 100644
--- a/src/com/android/settings/development/featureflags/FeatureFlagPreference.java
+++ b/src/com/android/settings/development/featureflags/FeatureFlagPreference.java
@@ -19,23 +19,36 @@
import android.content.Context;
import androidx.preference.SwitchPreference;
import android.util.FeatureFlagUtils;
+import android.util.Log;
public class FeatureFlagPreference extends SwitchPreference {
private final String mKey;
+ private final boolean mIsPersistent;
public FeatureFlagPreference(Context context, String key) {
super(context);
mKey = key;
setKey(key);
setTitle(key);
- setCheckedInternal(FeatureFlagUtils.isEnabled(context, mKey));
+ mIsPersistent = FeatureFlagPersistent.isPersistent(key);
+ boolean isFeatureEnabled;
+ if (mIsPersistent) {
+ isFeatureEnabled = FeatureFlagPersistent.isEnabled(context, key);
+ } else {
+ isFeatureEnabled = FeatureFlagUtils.isEnabled(context, key);
+ }
+ setCheckedInternal(isFeatureEnabled);
}
@Override
public void setChecked(boolean isChecked) {
setCheckedInternal(isChecked);
- FeatureFlagUtils.setEnabled(getContext(), mKey, isChecked);
+ if (mIsPersistent) {
+ FeatureFlagPersistent.setEnabled(getContext(), mKey, isChecked);
+ } else {
+ FeatureFlagUtils.setEnabled(getContext(), mKey, isChecked);
+ }
}
private void setCheckedInternal(boolean isChecked) {
diff --git a/src/com/android/settings/display/BrightnessLevelPreferenceController.java b/src/com/android/settings/display/BrightnessLevelPreferenceController.java
index be79f66..07882d8 100644
--- a/src/com/android/settings/display/BrightnessLevelPreferenceController.java
+++ b/src/com/android/settings/display/BrightnessLevelPreferenceController.java
@@ -151,12 +151,20 @@
}
@VisibleForTesting
+ IVrManager safeGetVrManager() {
+ return IVrManager.Stub.asInterface(ServiceManager.getService(
+ Context.VR_SERVICE));
+ }
+
+ @VisibleForTesting
boolean isInVrMode() {
- try {
- return IVrManager.Stub.asInterface(ServiceManager.getService(Context.VR_SERVICE))
- .getVrModeState();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to check vr mode!", e);
+ IVrManager vrManager = safeGetVrManager();
+ if (vrManager != null) {
+ try {
+ return vrManager.getVrModeState();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to check vr mode!", e);
+ }
}
return false;
}
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 4a3e6d4..8540f0f 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -24,8 +24,8 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.BatteryStats;
-import android.os.Bundle;
import android.os.Build;
+import android.os.Bundle;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -35,7 +35,6 @@
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
-import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.SparseLongArray;
@@ -48,7 +47,6 @@
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
import com.android.settings.fuelgauge.batterytip.StatsManagerConfig;
import com.android.settings.overlay.FeatureFactory;
-
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
import com.android.settingslib.utils.PowerUtil;
@@ -93,14 +91,14 @@
public static BatteryUtils getInstance(Context context) {
if (sInstance == null || sInstance.isDataCorrupted()) {
- sInstance = new BatteryUtils(context);
+ sInstance = new BatteryUtils(context.getApplicationContext());
}
return sInstance;
}
@VisibleForTesting
BatteryUtils(Context context) {
- mContext = context.getApplicationContext();
+ mContext = context;
mPackageManager = context.getPackageManager();
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mPowerUsageFeatureProvider = FeatureFactory.getFactory(
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index 89e1eb8..72714d5 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -94,7 +94,8 @@
@Override
public PowerUsageFeatureProvider getPowerUsageFeatureProvider(Context context) {
if (mPowerUsageFeatureProvider == null) {
- mPowerUsageFeatureProvider = new PowerUsageFeatureProviderImpl(context);
+ mPowerUsageFeatureProvider = new PowerUsageFeatureProviderImpl(
+ context.getApplicationContext());
}
return mPowerUsageFeatureProvider;
}
@@ -102,7 +103,8 @@
@Override
public DashboardFeatureProvider getDashboardFeatureProvider(Context context) {
if (mDashboardFeatureProvider == null) {
- mDashboardFeatureProvider = new DashboardFeatureProviderImpl(context);
+ mDashboardFeatureProvider = new DashboardFeatureProviderImpl(
+ context.getApplicationContext());
}
return mDashboardFeatureProvider;
}
@@ -118,10 +120,11 @@
@Override
public ApplicationFeatureProvider getApplicationFeatureProvider(Context context) {
if (mApplicationFeatureProvider == null) {
- mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(context,
- new PackageManagerWrapper(context.getPackageManager()),
+ final Context appContext = context.getApplicationContext();
+ mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(appContext,
+ new PackageManagerWrapper(appContext.getPackageManager()),
AppGlobals.getPackageManager(),
- (DevicePolicyManager) context
+ (DevicePolicyManager) appContext
.getSystemService(Context.DEVICE_POLICY_SERVICE));
}
return mApplicationFeatureProvider;
@@ -138,12 +141,14 @@
@Override
public EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(Context context) {
if (mEnterprisePrivacyFeatureProvider == null) {
- mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(context,
- (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE),
- new PackageManagerWrapper(context.getPackageManager()),
- UserManager.get(context),
- (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
- context.getResources());
+ final Context appContext = context.getApplicationContext();
+ mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(appContext,
+ (DevicePolicyManager) appContext
+ .getSystemService(Context.DEVICE_POLICY_SERVICE),
+ new PackageManagerWrapper(appContext.getPackageManager()),
+ UserManager.get(appContext),
+ (ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE),
+ appContext.getResources());
}
return mEnterprisePrivacyFeatureProvider;
}
@@ -172,7 +177,8 @@
@Override
public SuggestionFeatureProvider getSuggestionFeatureProvider(Context context) {
if (mSuggestionFeatureProvider == null) {
- mSuggestionFeatureProvider = new SuggestionFeatureProviderImpl(context);
+ mSuggestionFeatureProvider = new SuggestionFeatureProviderImpl(
+ context.getApplicationContext());
}
return mSuggestionFeatureProvider;
}
@@ -180,7 +186,7 @@
@Override
public UserFeatureProvider getUserFeatureProvider(Context context) {
if (mUserFeatureProvider == null) {
- mUserFeatureProvider = new UserFeatureProviderImpl(context);
+ mUserFeatureProvider = new UserFeatureProviderImpl(context.getApplicationContext());
}
return mUserFeatureProvider;
}
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index add05e4..4af83f3 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -164,6 +164,11 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ final Activity activity = getActivity();
+ if (!Utils.isDeviceProvisioned(activity) && !canRunBeforeDeviceProvisioned()) {
+ activity.finish();
+ return;
+ }
String chooseLockAction = getActivity().getIntent().getAction();
mFingerprintManager = Utils.getFingerprintManagerOrNull(getActivity());
@@ -249,6 +254,10 @@
addHeaderView();
}
+ protected boolean canRunBeforeDeviceProvisioned() {
+ return false;
+ }
+
protected void addHeaderView() {
if (mForFingerprint) {
setHeaderView(R.layout.choose_lock_generic_fingerprint_header);
diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java
index a720473..b96ebea 100644
--- a/src/com/android/settings/password/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/password/SetupChooseLockGeneric.java
@@ -129,6 +129,11 @@
return layout.onCreateRecyclerView(inflater, parent, savedInstanceState);
}
+ @Override
+ protected boolean canRunBeforeDeviceProvisioned() {
+ return true;
+ }
+
/***
* Disables preferences that are less secure than required quality and shows only secure
* screen lock options here.
diff --git a/src/com/android/settings/search/actionbar/SearchMenuController.java b/src/com/android/settings/search/actionbar/SearchMenuController.java
index 1729ccd..131f788 100644
--- a/src/com/android/settings/search/actionbar/SearchMenuController.java
+++ b/src/com/android/settings/search/actionbar/SearchMenuController.java
@@ -25,6 +25,7 @@
import android.view.MenuItem;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.SearchFeatureProvider;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -52,6 +53,9 @@
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ if (!Utils.isDeviceProvisioned(mHost.getContext())) {
+ return;
+ }
if (menu == null) {
return;
}
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 4b9a7ec..b327f02 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -382,7 +382,7 @@
void registerIntentToUri(IntentFilter intentFilter, Uri sliceUri) {
Log.d(TAG, "Registering Uri for broadcast relay: " + sliceUri);
mRegisteredUris.add(sliceUri);
- SliceBroadcastRelay.registerReceiver(getContext(), sliceUri, SliceBroadcastReceiver.class,
+ SliceBroadcastRelay.registerReceiver(getContext(), sliceUri, SliceRelayReceiver.class,
intentFilter);
}
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index d81734a..53fa4be 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -44,7 +44,6 @@
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.WifiSliceBuilder;
-import com.android.settingslib.SliceBroadcastRelay;
/**
* Responds to actions performed on slices and notifies slices of updates in state changes.
@@ -84,12 +83,6 @@
case ACTION_ZEN_MODE_SLICE_CHANGED:
ZenModeSliceBuilder.handleUriChange(context, intent);
break;
- default:
- final String uriString = intent.getStringExtra(SliceBroadcastRelay.EXTRA_URI);
- if (!TextUtils.isEmpty(uriString)) {
- final Uri uri = Uri.parse(uriString);
- context.getContentResolver().notifyChange(uri, null /* observer */);
- }
}
}
diff --git a/src/com/android/settings/slices/SliceRelayReceiver.java b/src/com/android/settings/slices/SliceRelayReceiver.java
new file mode 100644
index 0000000..c8ec12e
--- /dev/null
+++ b/src/com/android/settings/slices/SliceRelayReceiver.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 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.slices;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.text.TextUtils;
+import com.android.settingslib.SliceBroadcastRelay;
+
+/**
+ * Receives broadcasts to notify that Settings Slices are potentially stale.
+ */
+public class SliceRelayReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String uriString = intent.getStringExtra(SliceBroadcastRelay.EXTRA_URI);
+ if (!TextUtils.isEmpty(uriString)) {
+ final Uri uri = Uri.parse(uriString);
+ context.getContentResolver().notifyChange(uri, null /* observer */);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/wrapper/OverlayManagerWrapper.java b/src/com/android/settings/wrapper/OverlayManagerWrapper.java
index 6e3c234..371504f 100644
--- a/src/com/android/settings/wrapper/OverlayManagerWrapper.java
+++ b/src/com/android/settings/wrapper/OverlayManagerWrapper.java
@@ -81,18 +81,21 @@
public static final String CATEGORY_THEME = android.content.om.OverlayInfo.CATEGORY_THEME;
public final String packageName;
public final String category;
+ public final int priority;
private final boolean mEnabled;
- public OverlayInfo(String packageName, String category, boolean enabled) {
+ public OverlayInfo(String packageName, String category, boolean enabled, int priority) {
this.packageName = packageName;
this.category = category;
mEnabled = enabled;
+ this.priority = priority;
}
public OverlayInfo(android.content.om.OverlayInfo info) {
mEnabled = info.isEnabled();
category = info.category;
packageName = info.packageName;
+ priority = info.priority;
}
public boolean isEnabled() {
diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
index 2096629..54b01ea 100644
--- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
@@ -16,6 +16,7 @@
package com.android.settings;
+import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -27,17 +28,25 @@
import android.app.ActivityManager;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.provider.Settings.Global;
+import android.view.View;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
public class SettingsActivityTest {
@@ -49,16 +58,47 @@
@Mock
private Bitmap mBitmap;
private SettingsActivity mActivity;
+ private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
mActivity = spy(new SettingsActivity());
doReturn(mBitmap).when(mActivity).getBitmapFromXmlResource(anyInt());
}
@Test
+ @Config(shadows = {
+ SettingsShadowResourcesImpl.class,
+ SettingsShadowResources.SettingsShadowTheme.class,
+ })
+ public void onCreate_deviceNotProvisioned_shouldDisableSearch() {
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
+ final Intent intent = new Intent(mContext, Settings.class);
+ final SettingsActivity activity =
+ Robolectric.buildActivity(SettingsActivity.class, intent).create(Bundle.EMPTY).get();
+
+ assertThat(activity.findViewById(R.id.search_bar).getVisibility())
+ .isEqualTo(View.INVISIBLE);
+ }
+
+ @Test
+ @Config(shadows = {
+ SettingsShadowResourcesImpl.class,
+ SettingsShadowResources.SettingsShadowTheme.class,
+ })
+ public void onCreate_deviceProvisioned_shouldEnableSearch() {
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
+ final Intent intent = new Intent(mContext, Settings.class);
+ final SettingsActivity activity =
+ Robolectric.buildActivity(SettingsActivity.class, intent).create(Bundle.EMPTY).get();
+
+ assertThat(activity.findViewById(R.id.search_bar).getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
public void launchSettingFragment_nullExtraShowFragment_shouldNotCrash() {
when(mActivity.getFragmentManager()).thenReturn(mFragmentManager);
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
index ced8fc4..0b1311d 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
@@ -204,6 +204,33 @@
}
@Test
+ public void onProfileConnectionStateChanged_hearingAidDeviceConnected_notInCall_addPreference()
+ {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater.
+ isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedHearingAidDevice()).thenReturn(true);
+
+ mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+ }
+
+ @Test
+ public void onProfileConnectionStateChanged_hearingAidDeviceConnected_inCall_addPreference() {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_CALL);
+ when(mBluetoothDeviceUpdater.
+ isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedHearingAidDevice()).thenReturn(true);
+
+ mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+ }
+
+ @Test
public void onProfileConnectionStateChanged_deviceDisconnected_removePreference() {
mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
index 2567f53..e3f26b2 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
@@ -19,6 +19,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -96,7 +97,7 @@
verify(mHeaderController).setIcon(any(Drawable.class));
verify(mHeaderController).setIconContentDescription(any(String.class));
verify(mHeaderController).setSummary(any(String.class));
- verify(mHeaderController).setSecondSummary(any(String.class));
+ verify(mHeaderController, never()).setSecondSummary(any(String.class));
verify(mHeaderController).done(mActivity, true);
}
@@ -119,4 +120,12 @@
inOrder.verify(mHeaderController)
.setSummary(mContext.getString(R.string.bluetooth_connecting));
}
+
+ @Test
+ public void testSecondSummary_isHearingAidDevice_showSecondSummary() {
+ when(mCachedDevice.isHearingAidDevice()).thenReturn(true);
+ showScreen(mController);
+
+ verify(mHeaderController).setSecondSummary(any(String.class));
+ }
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingControllerTest.java
new file mode 100644
index 0000000..b28a8b2
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingControllerTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 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.bluetooth;
+
+import static android.bluetooth.BluetoothDevice.PAIRING_VARIANT_CONSENT;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.Intent;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settings.testutils.shadow.ShadowBluetoothPan;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothPan.class, ShadowBluetoothAdapter.class})
+public class BluetoothPairingControllerTest {
+ @Mock
+ private BluetoothDevice mBluetoothDevice;
+ private Context mContext;
+ private BluetoothPairingController mBluetoothPairingController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ final Intent intent = new Intent();
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
+ mBluetoothPairingController = spy(new BluetoothPairingController(intent, mContext));
+ }
+
+ @Test
+ public void onDialogPositiveClick_confirmationDialog_setPBAP() {
+ mBluetoothPairingController.mType = PAIRING_VARIANT_CONSENT;
+ mBluetoothPairingController.onCheckedChanged(null, true);
+
+ mBluetoothPairingController.onDialogPositiveClick(null);
+
+ verify(mBluetoothDevice).setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
index 483df01..8120d91 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
@@ -205,6 +205,34 @@
}
@Test
+ public void onProfileConnectionStateChanged_hearingAidDeviceConnected_inCall_removePreference()
+ {
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_CALL);
+ when(mBluetoothDeviceUpdater.
+ isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedHearingAidDevice()).thenReturn(true);
+
+ mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
+
+ verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+ }
+
+ @Test
+ public void onProfileConnectionStateChanged_hearingAidDeviceConnected_notInCall_removePreference
+ () {
+ mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater.
+ isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedHearingAidDevice()).thenReturn(true);
+
+ mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
+
+ verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+ }
+
+ @Test
public void onProfileConnectionStateChanged_deviceDisconnected_removePreference() {
mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);
diff --git a/tests/robotests/src/com/android/settings/development/EmulateDisplayCutoutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/EmulateDisplayCutoutPreferenceControllerTest.java
index 34a0581..68a0ffd 100644
--- a/tests/robotests/src/com/android/settings/development/EmulateDisplayCutoutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/EmulateDisplayCutoutPreferenceControllerTest.java
@@ -17,6 +17,8 @@
package com.android.settings.development;
import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -38,6 +40,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.AdditionalMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -46,10 +49,10 @@
@RunWith(SettingsRobolectricTestRunner.class)
public class EmulateDisplayCutoutPreferenceControllerTest {
- private static final OverlayInfo ONE_DISABLED = createFakeOverlay("emulation.one", false);
- private static final OverlayInfo ONE_ENABLED = createFakeOverlay("emulation.one", true);
- private static final OverlayInfo TWO_DISABLED = createFakeOverlay("emulation.two", false);
- private static final OverlayInfo TWO_ENABLED = createFakeOverlay("emulation.two", true);
+ private static final OverlayInfo ONE_DISABLED = createFakeOverlay("emulation.one", false, 1);
+ private static final OverlayInfo ONE_ENABLED = createFakeOverlay("emulation.one", true, 1);
+ private static final OverlayInfo TWO_DISABLED = createFakeOverlay("emulation.two", false, 2);
+ private static final OverlayInfo TWO_ENABLED = createFakeOverlay("emulation.two", true, 2);
@Mock
private Context mContext;
@@ -128,6 +131,16 @@
}
@Test
+ public void ordered_by_priority() throws Exception {
+ mockCurrentOverlays(TWO_DISABLED, ONE_DISABLED);
+
+ mController.updateState(null);
+
+ verify(mPreference).setEntryValues(
+ aryEq(new String[]{"", ONE_DISABLED.packageName, TWO_DISABLED.packageName}));
+ }
+
+ @Test
public void onDeveloperOptionsSwitchDisabled() throws Exception {
mockCurrentOverlays(ONE_ENABLED, TWO_DISABLED);
final PreferenceScreen screen = mock(PreferenceScreen.class);
@@ -145,7 +158,8 @@
mOverlayManager);
}
- private static OverlayInfo createFakeOverlay(String pkg, boolean enabled) {
- return new OverlayInfo(pkg, DisplayCutout.EMULATION_OVERLAY_CATEGORY, enabled);
+ private static OverlayInfo createFakeOverlay(String pkg, boolean enabled, int priority) {
+ return new OverlayInfo(pkg, DisplayCutout.EMULATION_OVERLAY_CATEGORY, enabled,
+ priority);
}
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPersistentTest.java b/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPersistentTest.java
new file mode 100644
index 0000000..c9f452d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPersistentTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2018 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.featureflags;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.settings.development.featureflags.FeatureFlagPersistent;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.util.FeatureFlagUtils;
+import android.util.Log;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class FeatureFlagPersistentTest {
+
+ private static final String TEST_FEATURE_NAME = "test_feature";
+
+ private static final String PERSISTENT_FALSE_NAME = "false_persistent";
+ private static final String PERSISTENT_TRUE_NAME = "true_persistent";
+ private static final String VOLATILE_FALSE_NAME = "volatile_false_volatile";
+ private static final String VOLATILE_TRUE_NAME = "volatile_true_volatile";
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+
+ FeatureFlagPersistent.getAllPersistentFlags().add(TEST_FEATURE_NAME);
+ FeatureFlagUtils.getAllFeatureFlags().put(TEST_FEATURE_NAME, "false");
+
+ FeatureFlagUtils.getAllFeatureFlags().put(VOLATILE_FALSE_NAME, "false");
+ FeatureFlagUtils.getAllFeatureFlags().put(VOLATILE_TRUE_NAME, "true");
+
+ FeatureFlagPersistent.getAllPersistentFlags().add(PERSISTENT_FALSE_NAME);
+ FeatureFlagUtils.getAllFeatureFlags().put(PERSISTENT_FALSE_NAME, "false");
+
+ FeatureFlagPersistent.getAllPersistentFlags().add(PERSISTENT_TRUE_NAME);
+ FeatureFlagUtils.getAllFeatureFlags().put(PERSISTENT_TRUE_NAME, "true");
+ }
+
+ @After
+ public void tearDown() {
+ cleanup(PERSISTENT_FALSE_NAME);
+ cleanup(PERSISTENT_TRUE_NAME);
+ cleanup(VOLATILE_FALSE_NAME);
+ cleanup(VOLATILE_TRUE_NAME);
+ cleanup(TEST_FEATURE_NAME);
+ }
+
+ private void cleanup(String flagName) {
+ Settings.Global.putString(mContext.getContentResolver(), flagName, "");
+ SystemProperties.set(FeatureFlagUtils.FFLAG_PREFIX + flagName, "");
+ SystemProperties.set(FeatureFlagUtils.FFLAG_OVERRIDE_PREFIX + flagName, "");
+ SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + flagName, "");
+ }
+
+ /**
+ * Test to verify a non-persistent flag is indeed not persistent.
+ */
+ @Test
+ public void isPersistent_notPersistent_shouldReturnFalse() {
+ assertThat(FeatureFlagPersistent.isPersistent(VOLATILE_FALSE_NAME)).isFalse();
+ }
+
+ /**
+ * Test to verify a persistent flag is indeed persistent.
+ */
+ @Test
+ public void isPersistent_persistent_shouldReturnTrue() {
+ assertThat(FeatureFlagPersistent.isPersistent(PERSISTENT_TRUE_NAME)).isTrue();
+ }
+
+ /**
+ * Test to verify a persistent flag that is enabled should return true.
+ */
+ @Test
+ public void isEnabled_enabled_shouldReturnTrue() {
+ assertThat(FeatureFlagPersistent.isEnabled(mContext, PERSISTENT_TRUE_NAME)).isTrue();
+ }
+
+ /**
+ * Test to verify a persistent flag that is disabled should return false.
+ */
+ @Test
+ public void isEnabled_disabled_shouldReturnFalse() {
+ assertThat(FeatureFlagPersistent.isEnabled(mContext, PERSISTENT_FALSE_NAME)).isFalse();
+ }
+
+ /**
+ * Test to verify a persistent flag that has an enabled in system property should return true.
+ */
+ @Test
+ public void isEnabled_sysPropEnabled_shouldReturnTrue() {
+ SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME, "true");
+ FeatureFlagUtils.setEnabled(mContext, TEST_FEATURE_NAME, false);
+
+ assertThat(FeatureFlagPersistent.isEnabled(mContext, TEST_FEATURE_NAME)).isTrue();
+ }
+
+ /**
+ * Test to verify a persistent flag that is disabled in system property should return false.
+ */
+ @Test
+ public void isEnabled_sysPropDisabled_shouldReturnFalse() {
+ SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME, "false");
+ FeatureFlagUtils.setEnabled(mContext, TEST_FEATURE_NAME, true);
+
+ assertThat(FeatureFlagPersistent.isEnabled(mContext, TEST_FEATURE_NAME)).isFalse();
+ }
+
+ /**
+ * Test to verify setting persistent flag to enable works.
+ */
+ @Test
+ public void setEnabled_sysPropTrue_shouldSetValues() {
+ SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME, "");
+
+ FeatureFlagPersistent.setEnabled(mContext, TEST_FEATURE_NAME, true);
+
+ assertThat(SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME)).isEqualTo("true");
+ assertThat(FeatureFlagUtils.isEnabled(mContext, TEST_FEATURE_NAME)).isTrue();
+ }
+
+ /**
+ * Test to verify setting persistent flag to disable works.
+ */
+ @Test
+ public void setEnabled_sysPropFalse_shouldSetValues() {
+ SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME, "");
+
+ FeatureFlagPersistent.setEnabled(mContext, TEST_FEATURE_NAME, false);
+
+ assertThat(SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME)).isEqualTo("false");
+ assertThat(FeatureFlagUtils.isEnabled(mContext, TEST_FEATURE_NAME)).isFalse();
+ }
+}
+
diff --git a/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java
index b758531..6932d6d 100644
--- a/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java
@@ -82,6 +82,12 @@
}
@Test
+ public void isInVrMode_noVrManager_shouldAlwaysReturnFalse() {
+ doReturn(null).when(mController).safeGetVrManager();
+ assertThat(mController.isInVrMode()).isFalse();
+ }
+
+ @Test
public void onStart_shouldRegisterObserver() {
BrightnessLevelPreferenceController controller =
new BrightnessLevelPreferenceController(mContext, null);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
index d5f3e2b..9ca61a4 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
@@ -17,6 +17,7 @@
package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
@@ -89,6 +90,7 @@
mShadowContext = RuntimeEnvironment.application;
FakeFeatureFactory.setupForTest();
+ when(mContext.getApplicationContext()).thenReturn(mContext);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
@@ -118,7 +120,7 @@
@Test
public void testHandlePreferenceTreeClick_restrictApp_showDialog() {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
- .checkOpNoThrow(anyInt(), anyInt(), anyString());
+ .checkOpNoThrow(anyInt(), anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference);
@@ -128,7 +130,7 @@
@Test
public void testHandlePreferenceTreeClick_unRestrictApp_showDialog() {
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
- .checkOpNoThrow(anyInt(), anyInt(), anyString());
+ .checkOpNoThrow(anyInt(), anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference);
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
new file mode 100644
index 0000000..7a14896
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 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.password;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.provider.Settings.Global;
+
+import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ChooseLockGenericTest {
+
+ @After
+ public void tearDown() {
+ Global.putInt(RuntimeEnvironment.application.getContentResolver(),
+ Global.DEVICE_PROVISIONED, 1);
+ }
+
+ @Test
+ @Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
+ public void onCreate_deviceNotProvisioned_shouldFinishActivity() {
+ final Context context = RuntimeEnvironment.application;
+ Global.putInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
+ final Activity activity = mock(Activity.class);
+ when(activity.getContentResolver()).thenReturn(context.getContentResolver());
+ when(activity.getTheme()).thenReturn(context.getTheme());
+
+ final ChooseLockGenericFragment fragment = spy(new ChooseLockGenericFragment());
+ when(fragment.getActivity()).thenReturn(activity);
+ when(fragment.getArguments()).thenReturn(Bundle.EMPTY);
+
+ fragment.onCreate(Bundle.EMPTY);
+ verify(activity).finish();
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java b/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
index 7ff4acc..9900df2 100644
--- a/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
+++ b/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
@@ -17,11 +17,14 @@
package com.android.settings.search.actionbar;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import android.content.Context;
import android.os.Bundle;
+import android.provider.Settings.Global;
import android.view.Menu;
import android.view.MenuItem;
@@ -35,6 +38,7 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
@RunWith(SettingsRobolectricTestRunner.class)
public class SearchMenuControllerTest {
@@ -43,12 +47,16 @@
private Menu mMenu;
private TestPreferenceFragment mPreferenceHost;
private ObservableFragment mHost;
+ private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mHost = new ObservableFragment();
+ mContext = RuntimeEnvironment.application;
+ mHost = spy(new ObservableFragment());
+ when(mHost.getContext()).thenReturn(mContext);
mPreferenceHost = new TestPreferenceFragment();
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
when(mMenu.add(Menu.NONE, Menu.NONE, 0 /* order */, R.string.search_menu))
.thenReturn(mock(MenuItem.class));
@@ -81,9 +89,23 @@
verifyZeroInteractions(mMenu);
}
+ @Test
+ public void init_deviceNotProvisioned_shouldNotAddMenu() {
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
+ SearchMenuController.init(mHost);
+ mHost.getLifecycle().onCreateOptionsMenu(mMenu, null /* inflater */);
+
+ verifyZeroInteractions(mMenu);
+ }
+
private static class TestPreferenceFragment extends ObservablePreferenceFragment {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
}
+
+ @Override
+ public Context getContext() {
+ return RuntimeEnvironment.application;
+ }
}
}
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
index 25f0d0c..f8172e8 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
@@ -159,8 +159,12 @@
assertThat(fakeToggleController.isChecked()).isFalse();
- final Uri expectedUri = SliceBuilderUtils.getUri(
- SettingsSlicesContract.PATH_SETTING_ACTION + "/" + key, false);
+ final Uri expectedUri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
verify(resolver).notifyChange(eq(expectedUri), eq(null));
}
diff --git a/tests/robotests/src/com/android/settings/slices/SliceRelayReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceRelayReceiverTest.java
new file mode 100644
index 0000000..3388a16
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/slices/SliceRelayReceiverTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 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.slices;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.ContentResolver;
+import android.content.Context;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.SettingsSlicesContract;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.SliceBroadcastRelay;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class SliceRelayReceiverTest {
+
+ private Context mContext;
+ private SliceRelayReceiver mSliceRelayReceiver;
+
+ @Before
+ public void setUp() {
+ mContext = spy(RuntimeEnvironment.application);
+ mSliceRelayReceiver = new SliceRelayReceiver();
+ }
+
+
+ @Test
+ public void onReceive_extraUri_notifiesChangeOnUri() {
+ // Monitor the ContentResolver
+ final ContentResolver resolver = spy(mContext.getContentResolver());
+ doReturn(resolver).when(mContext).getContentResolver();
+
+ final Uri uri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSlicesContract.AUTHORITY)
+ .appendPath("path")
+ .build();
+
+ final Intent intent = new Intent();
+ intent.putExtra(SliceBroadcastRelay.EXTRA_URI, uri.toString());
+
+ mSliceRelayReceiver.onReceive(mContext, intent);
+
+ verify(resolver).notifyChange(eq(uri), any());
+
+ }
+}