Snap for 5563067 from e575fc44f5 to qt-release

Change-Id: If67461673682a9ca59a6b049e6cdaa5065c90829
This commit is contained in:
android-build-team Robot
2019-05-14 03:00:56 +00:00
75 changed files with 1535 additions and 1506 deletions

View File

@@ -164,7 +164,8 @@
</receiver>
<activity android:name=".SubSettings"
android:parentActivityName="Settings" />
android:parentActivityName="Settings"
android:theme="@style/Theme.SubSettings"/>
<activity android:name=".Settings$CreateShortcutActivity"
android:label="@string/settings_shortcut">
@@ -2705,10 +2706,8 @@
</intent-filter>
</activity>
<activity
<receiver
android:name=".wifi.slice.ConnectToWifiHandler"
android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true"
android:exported="false" />
<activity

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -19,6 +19,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<Toolbar
android:id="@+id/action_bar"
@@ -30,6 +31,5 @@
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="?android:attr/windowBackground" />
android:layout_height="match_parent"/>
</LinearLayout>

View File

@@ -43,21 +43,18 @@
android:layout_marginBottom="8dp"
style="?android:attr/progressBarStyleHorizontal"/>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextureView
android:id="@+id/preview_view"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"/>
android:layout_height="@dimen/qrcode_preview_size"/>
<com.android.settings.wifi.qrcode.QrDecorateView
android:id="@+id/decorate_view"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"/>
</androidx.constraintlayout.widget.ConstraintLayout>
android:layout_height="@dimen/qrcode_preview_size"/>
</FrameLayout>
<TextView
android:id="@+id/error_message"

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -3847,6 +3847,13 @@
<!-- Ask user to connect to the internet [CHAR_ LIMIT=50]-->
<string name="mobile_connect_to_internet" translatable="true">Please connect to the internet</string>
<!-- Location settings screen, sub category for recent location requests [CHAR LIMIT=42] -->
<string name="location_category_recent_location_requests">Recent location requests</string>
<!-- Location settings screen, displayed when there're more than three recent location requests [CHAR LIMIT=30] -->
<string name="location_recent_location_requests_see_all">See all</string>
<!-- Location settings screen, sub category for location services [CHAR LIMIT=30] -->
<string name="location_category_location_services">Location services</string>
<!-- Security & location settings screen, section header for settings relating to location -->
<string name="location_title">My Location</string>
<!-- [CHAR LIMIT=30] Title for managed profile location switch -->
@@ -7059,6 +7066,18 @@
<string name="mms_message_title">MMS messages</string>
<!-- Summary of multimedia messaging service settings. [CHAR LIMIT=100] -->
<string name="mms_message_summary">Send &amp; receive when mobile data is off</string>
<!-- Title of a preference for whether to allow data during calls that is shown when mobile
data is turned off. This is needed for some multi-SIM scenarios, because the SIM that is
default for data might not be available during a phone call. [CHAR LIMIT=60] -->
<string name="data_during_calls_title">Data during calls</string>
<!-- Title of a preference for whether to allow data during calls that is shown when mobile
data is turned off. This is needed for some multi-SIM scenarios, because the SIM that is
default for data might not be available during a phone call. [CHAR LIMIT=NONE] -->
<string name="data_during_calls_summary">
Allow this SIM to be used for mobile data only during calls
</string>
<!-- Work SIM title. [CHAR LIMIT=50] -->
<string name="work_sim_title">Work SIM</string>
@@ -7891,8 +7910,8 @@
<!-- Configure Notifications: Title for the notification bubbles option. [CHAR LIMIT=60] -->
<string name="notification_bubbles_title">Bubbles</string>
<!-- Configure Notifications: Summary for the notification bubbles option. [CHAR LIMIT=NONE] -->
<string name="notification_bubbles_summary">Quickly access app content from anywhere using floating shortcuts</string>
<!-- Developer setting summary for bubbles [CHAR LIMIT=NONE] -->
<string name="notification_bubbles_developer_setting_summary">Some notifications can appear as bubbles on the screen</string>
<!-- Feature education for bubbles. [CHAR LIMIT=NONE] -->
<string name="bubbles_feature_education">Some notifications and other content can appear as bubbles on the screen. To open a bubble, tap it. To dismiss it, drag it down the screen.</string>
<!-- Title for the toggle shown on the app-level bubbles page [CHAR LIMIT=60] -->
@@ -10134,11 +10153,11 @@
<!-- Title for settings suggestion for double twist for camera [CHAR LIMIT=60] -->
<string name="double_twist_for_camera_suggestion_title">Take selfies faster</string>
<!-- Title text for system navigation [CHAR LIMIT=60] [DO NOT TRANSLATE] -->
<string name="system_navigation_title" translatable="false">System navigation</string>
<!-- Title text for system navigation [CHAR LIMIT=60] -->
<string name="system_navigation_title">System navigation</string>
<!-- Title text for swipe up to switch apps [CHAR LIMIT=60] [DO NOT TRANSLATE] -->
<string name="swipe_up_to_switch_apps_title" translatable="false">2-button navigation</string>
<!-- Title text for swipe up to switch apps [CHAR LIMIT=60] -->
<string name="swipe_up_to_switch_apps_title">2-button navigation</string>
<!-- Summary text for swipe up to switch apps [CHAR LIMIT=250] -->
<string name="swipe_up_to_switch_apps_summary">To switch apps, swipe up on the Home button. Swipe up again to see all apps. Works from any screen. Youll no longer have an Overview button on the bottom right of your screen.</string>
<!-- Title for settings suggestion for swipe up to switch apps [CHAR LIMIT=60] -->
@@ -10146,15 +10165,18 @@
<!-- Summary for settings suggestion for swipe up to switch apps [CHAR LIMIT=60] -->
<string name="swipe_up_to_switch_apps_suggestion_summary">Turn on the new gesture to switch apps</string>
<!-- Title text for edge to edge navigation [CHAR LIMIT=60] [DO NOT TRANSLATE] -->
<string name="edge_to_edge_navigation_title" translatable="false">Fully gestural navigation</string>
<!-- Summary text for edge to edge navigation [CHAR LIMIT=None] [DO NOT TRANSLATE] -->
<string name="edge_to_edge_navigation_summary" translatable="false">To go Home, swipe up from the bottom of the screen. To go Back, swipe from either the left or right edge of the screen. To switch apps, start swiping up from the bottom of the screen and hold before releasing.</string>
<!-- Title text for edge to edge navigation [CHAR LIMIT=60] -->
<string name="edge_to_edge_navigation_title">Gesture navigation</string>
<!-- Summary text for edge to edge navigation [CHAR LIMIT=NONE] -->
<string name="edge_to_edge_navigation_summary">To go Home, swipe up from the bottom of the screen. To go Back, swipe from either the left or right edge of the screen. To switch apps, start swiping up from the bottom of the screen and hold before releasing.</string>
<!-- Title text for 3-button navigation [CHAR LIMIT=60] [DO NOT TRANSLATE] -->
<string name="legacy_navigation_title" translatable="false">3-button navigation</string>
<!-- Summary text for 3-button navigation [CHAR LIMIT=250] [DO NOT TRANSLATE] -->
<string name="legacy_navigation_summary" translatable="false">Classic Android navigation mode where going Home, switching apps, and going Back are accessible via buttons.</string>
<!-- Title text for 3-button navigation [CHAR LIMIT=60] -->
<string name="legacy_navigation_title">3-button navigation</string>
<!-- Summary text for 3-button navigation [CHAR LIMIT=NONE] -->
<string name="legacy_navigation_summary">Classic Android navigation mode where going Home, switching apps, and going Back are accessible via buttons.</string>
<!-- Search keywords for System Navigation settings. [CHAR_LIMIT=NONE]-->
<string name="keywords_system_navigation">system navigation, 2 button navigation, 3 button navigation, gesture navigation</string>
<!-- Preference and settings suggestion title text for ambient display double tap (phone) [CHAR LIMIT=60]-->
<string name="ambient_display_title" product="default">Double-tap to check phone</string>
@@ -10542,9 +10564,9 @@
<!-- Note displayed when certain features are not available on low ram devices. [CHAR LIMIT=NONE] -->
<string name="disabled_low_ram_device">This feature is not available on this device</string>
<!-- Note displayed when certain features are not available. [CHAR LIMIT=NONE] -->
<!-- Title of a message for an empty state screen. A user will see this message if they try to use a certain feature, but the feature was turned off so it won't slow down their phone. [CHAR LIMIT=NONE] -->
<string name="disabled_feature">Feature not available</string>
<!-- Note displayed to explain that a feature is not available because it will slow down the phone. [CHAR LIMIT=NONE] -->
<!-- Part of a message for an empty state screen. A user will see this message if they try to use a certain feature, but the feature was turned off so it won't slow down their phone. [CHAR LIMIT=NONE] -->
<string name="disabled_feature_reason_slow_down_phone">This feature has been turned off because it slows down your phone</string>
<!-- UI debug setting: preference title - enforce full raw GNSS satellite measurements [CHAR LIMIT=60] -->

View File

@@ -27,8 +27,11 @@
<style name="Theme.Settings" parent="Theme.SettingsBase">
<item name="preferenceTheme">@style/PreferenceTheme</item>
<item name="android:clipToPadding">false</item>
<item name="android:clipChildren">false</item>
<item name="android:listPreferredItemHeight">72dip</item>
<item name="android:homeAsUpIndicator">@drawable/ic_arrow_back</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
<item name="face_layout_theme">@style/FaceLayoutTheme</item>

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/bubbles_app_toggle_title"
android:key="bubble_notification_settings">
<com.android.settings.widget.VideoPreference
android:key="bubbles_illustration"
android:title="@string/summary_placeholder"
settings:animation="@raw/bubbles"
settings:controller="com.android.settings.widget.VideoPreferenceController"
android:persistent="false" />
<!-- Notification bubbles -->
<SwitchPreference
android:key="global_notification_bubbles"
android:title="@string/notification_bubbles_title"
android:summary="@string/notification_bubbles_summary"
settings:controller="com.android.settings.notification.BubbleNotificationPreferenceController"/>
<com.android.settingslib.widget.FooterPreference
android:key="notification_bubbles_footer"
android:title="@string/bubbles_feature_education"
android:selectable="false" />
</PreferenceScreen>

View File

@@ -74,13 +74,6 @@
android:title="@string/notification_badging_title"
settings:controller="com.android.settings.notification.BadgingNotificationPreferenceController"/>
<!-- Notification bubbles -->
<Preference
android:key="notification_bubbles"
android:title="@string/notification_bubbles_title"
settings:controller="com.android.settings.notification.BubbleSummaryNotificationPreferenceController"
android:fragment="com.android.settings.notification.BubbleNotificationSettings"/>
<!-- Pulse notification light -->
<SwitchPreference
android:key="notification_pulse"

View File

@@ -560,6 +560,12 @@
android:key="device_identifier_access_restrictions"
android:title="@string/device_identifier_access_restrictions_title"
android:summary="@string/device_identifier_access_restrictions_summary" />
<SwitchPreference
android:key="notification_bubbles"
android:title="@string/notification_bubbles_title"
android:summary="@string/notification_bubbles_developer_setting_summary"/>
</PreferenceCategory>
<com.android.settings.development.autofill.AutofillPreferenceCategory

View File

@@ -49,7 +49,7 @@
android:key="gesture_system_navigation_input_summary"
android:title="@string/system_navigation_title"
android:fragment="com.android.settings.gestures.SystemNavigationGestureSettings"
settings:controller="com.android.settings.gestures.SystemNavigationLegacyPreferenceController" />
settings:controller="com.android.settings.gestures.SystemNavigationPreferenceController" />
<Preference
android:key="gesture_tap_screen_input_summary"

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/location_category_recent_location_requests"
android:key="recent_location_requests_see_all">
<PreferenceCategory
android:key="all_recent_location_requests"/>
</PreferenceScreen>

View File

@@ -20,11 +20,16 @@
android:title="@string/location_settings_title"
settings:keywords="@string/keywords_location">
<com.android.settingslib.widget.LayoutPreference
android:key="apps_dashboard"
android:layout="@layout/app_entities_header"
android:selectable="false"
settings:allowDividerBelow="true" />
<PreferenceCategory
android:key="recent_location_requests"
android:title="@string/location_category_recent_location_requests"/>
<Preference
android:key="recent_location_requests_see_all_button"
android:title="@string/location_recent_location_requests_see_all"
android:icon="@drawable/ic_chevron_right_24dp"
android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
settings:searchable="false"/>
<PreferenceCategory
android:key="location_advanced_settings"

View File

@@ -17,35 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="gesture_system_navigation_screen"
android:title="@string/system_navigation_title">
<com.android.settings.widget.VideoPreference
android:key="gesture_swipe_up_video"
app:animation="@raw/gesture_swipe_up"
app:preview="@drawable/gesture_swipe_up" />
<com.android.settings.widget.RadioButtonPreference
android:key="gesture_edge_to_edge"
android:title="@string/edge_to_edge_navigation_title"
android:summary="@string/edge_to_edge_navigation_summary"
app:keywords="@string/keywords_gesture"
app:controller="com.android.settings.gestures.SystemNavigationEdgeToEdgePreferenceController"
app:allowDividerAbove="true" />
<com.android.settings.widget.RadioButtonPreference
android:key="gesture_swipe_up"
android:title="@string/swipe_up_to_switch_apps_title"
android:summary="@string/swipe_up_to_switch_apps_summary"
app:keywords="@string/keywords_gesture"
app:controller="com.android.settings.gestures.SystemNavigationSwipeUpPreferenceController" />
<com.android.settings.widget.RadioButtonPreference
android:key="gesture_legacy"
android:title="@string/legacy_navigation_title"
android:summary="@string/legacy_navigation_summary"
app:keywords="@string/keywords_gesture"
app:controller="com.android.settings.gestures.SystemNavigationLegacyPreferenceController" />
</PreferenceScreen>
android:title="@string/system_navigation_title"
settings:keywords="@string/keywords_system_navigation"/>

View File

@@ -35,7 +35,6 @@ import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.Nullable;
@@ -51,7 +50,6 @@ import androidx.preference.PreferenceManager;
import com.android.internal.util.ArrayUtils;
import com.android.settings.Settings.WifiSettingsActivity;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.backup.BackupSettingsHelper;
import com.android.settings.backup.UserBackupSettingsActivity;
import com.android.settings.core.OnActivityResultListener;
import com.android.settings.core.SettingsBaseActivity;
@@ -166,8 +164,6 @@ public class SettingsActivity extends SettingsBaseActivity
private Button mNextButton;
private ViewGroup mContent;
// Categories
private ArrayList<DashboardCategory> mCategories = new ArrayList<>();
@@ -250,8 +246,6 @@ public class SettingsActivity extends SettingsBaseActivity
setContentView(R.layout.settings_main_prefs);
mContent = findViewById(R.id.main_content);
getSupportFragmentManager().addOnBackStackChangedListener(this);
if (savedState != null) {

View File

@@ -48,8 +48,8 @@ public class FaceEnrollEducation extends BiometricEnrollBase {
private static final String TAG = "FaceEducation";
private static final int ON = 1;
private static final int OFF = 0;
// 10 seconds.
private static final long FACE_ENROLL_EDUCATION_DELAY = 16000;
// 8 seconds.
private static final long FACE_ENROLL_EDUCATION_DELAY = 8000;
private FaceManager mFaceManager;
private FaceEnrollAccessibilityToggle mSwitchDiversity;
@@ -84,15 +84,6 @@ public class FaceEnrollEducation extends BiometricEnrollBase {
mHandler = new Handler();
mFaceManager = Utils.getFaceManagerOrNull(this);
final Button accessibilityButton = findViewById(R.id.accessibility_button);
accessibilityButton.setOnClickListener(view -> {
mSwitchDiversity.setChecked(true);
accessibilityButton.setVisibility(View.GONE);
mSwitchDiversity.setVisibility(View.VISIBLE);
});
mSwitchDiversity = findViewById(R.id.toggle_diversity);
mSwitchDiversity.setListener(mSwitchDiversityListener);
mIllustrationNormal = findViewById(R.id.illustration_normal);
mIllustrationAccessibility = findViewById(R.id.illustration_accessibility);
@@ -126,6 +117,17 @@ public class FaceEnrollEducation extends BiometricEnrollBase {
footerButton.setEnabled(true);
}, FACE_ENROLL_EDUCATION_DELAY);
}
final Button accessibilityButton = findViewById(R.id.accessibility_button);
accessibilityButton.setOnClickListener(view -> {
footerButton.setEnabled(true);
mSwitchDiversity.setChecked(true);
accessibilityButton.setVisibility(View.GONE);
mSwitchDiversity.setVisibility(View.VISIBLE);
});
mSwitchDiversity = findViewById(R.id.toggle_diversity);
mSwitchDiversity.setListener(mSwitchDiversityListener);
}
@Override

View File

@@ -66,7 +66,12 @@ public class SettingsBaseActivity extends FragmentActivity {
requestWindowFeature(Window.FEATURE_NO_TITLE);
}
super.setContentView(R.layout.settings_base_layout);
final View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
decorView.getSystemUiVisibility()
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
final Toolbar toolbar = findViewById(R.id.action_bar);
if (theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) {
toolbar.setVisibility(View.GONE);

View File

@@ -104,7 +104,6 @@ import com.android.settings.nfc.AndroidBeam;
import com.android.settings.nfc.PaymentSettings;
import com.android.settings.notification.AppBubbleNotificationSettings;
import com.android.settings.notification.AppNotificationSettings;
import com.android.settings.notification.BubbleNotificationSettings;
import com.android.settings.notification.ChannelGroupNotificationSettings;
import com.android.settings.notification.ChannelNotificationSettings;
import com.android.settings.notification.ConfigureNotificationSettings;
@@ -216,7 +215,6 @@ public class SettingsGateway {
DreamSettings.class.getName(),
UserSettings.class.getName(),
NotificationAccessSettings.class.getName(),
BubbleNotificationSettings.class.getName(),
AppBubbleNotificationSettings.class.getName(),
ZenAccessSettings.class.getName(),
ZenAccessDetails.class.getName(),

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.development;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import android.content.Context;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
public class BubbleGlobalPreferenceController extends DeveloperOptionsPreferenceController
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
@VisibleForTesting
static final int ON = 1;
@VisibleForTesting
static final int OFF = 0;
public BubbleGlobalPreferenceController(Context context) {
super(context);
}
@Override
public String getPreferenceKey() {
return NOTIFICATION_BUBBLES;
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
writeSetting((boolean) newValue);
return true;
}
@Override
public void updateState(Preference preference) {
((SwitchPreference) mPreference).setChecked(isEnabled());
}
@Override
protected void onDeveloperOptionsSwitchDisabled() {
super.onDeveloperOptionsSwitchDisabled();
writeSetting(false /* isEnabled */);
updateState(mPreference);
}
private boolean isEnabled() {
return Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, OFF) == ON;
}
private void writeSetting(boolean isEnabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, isEnabled ? ON : OFF);
}
}

View File

@@ -482,6 +482,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
controllers.add(new DesktopModePreferenceController(context));
controllers.add(new DeviceIdentifierAccessRestrictionsPreferenceController(context));
controllers.add(new ShortcutManagerThrottlingPreferenceController(context));
controllers.add(new BubbleGlobalPreferenceController(context));
controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context));
controllers.add(new DefaultLaunchPreferenceController(context, "running_apps"));
controllers.add(new DefaultLaunchPreferenceController(context, "demo_mode"));

View File

@@ -1,55 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.gestures;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
import android.content.Context;
import android.content.om.IOverlayManager;
import android.os.ServiceManager;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import com.android.settings.widget.RadioButtonPreference;
public class SystemNavigationEdgeToEdgePreferenceController extends
SystemNavigationPreferenceController {
static final String PREF_KEY_EDGE_TO_EDGE = "gesture_edge_to_edge";
public SystemNavigationEdgeToEdgePreferenceController(Context context, String key) {
this(context, IOverlayManager.Stub.asInterface(ServiceManager.getService(
Context.OVERLAY_SERVICE)), key);
}
@VisibleForTesting
public SystemNavigationEdgeToEdgePreferenceController(Context context,
IOverlayManager overlayManager, String key) {
super(context, overlayManager, key, NAV_BAR_MODE_GESTURAL_OVERLAY);
}
@Override
public void onRadioButtonClicked(RadioButtonPreference preference) {
setNavBarInteractionMode(mOverlayManager, NAV_BAR_MODE_GESTURAL_OVERLAY);
selectRadioButtonInGroup(PREF_KEY_EDGE_TO_EDGE, mPreferenceScreen);
}
@Override
public boolean isChecked() {
return isEdgeToEdgeEnabled(mContext);
}
}

View File

@@ -16,29 +16,58 @@
package com.android.settings.gestures;
import static android.os.UserHandle.USER_CURRENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.om.IOverlayManager;
import android.graphics.drawable.Drawable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.SearchIndexableResource;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.RadioButtonPickerFragment;
import com.android.settings.widget.RadioButtonPreference;
import com.android.settings.widget.VideoPreference;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.CandidateInfo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SearchIndexable
public class SystemNavigationGestureSettings extends DashboardFragment {
public class SystemNavigationGestureSettings extends RadioButtonPickerFragment {
private static final String TAG = "SystemNavigationGesture";
@VisibleForTesting
static final String KEY_SYSTEM_NAV_3BUTTONS = "system_nav_3buttons";
@VisibleForTesting
static final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons";
@VisibleForTesting
static final String KEY_SYSTEM_NAV_GESTURAL = "system_nav_gestural";
public static final String PREF_KEY_SUGGESTION_COMPLETE =
"pref_system_navigation_suggestion_complete";
private IOverlayManager mOverlayManager;
private VideoPreference mVideoPreference;
@Override
public void onAttach(Context context) {
super.onAttach(context);
@@ -46,6 +75,12 @@ public class SystemNavigationGestureSettings extends DashboardFragment {
.getSuggestionFeatureProvider(context);
SharedPreferences prefs = suggestionFeatureProvider.getSharedPrefs(context);
prefs.edit().putBoolean(PREF_KEY_SUGGESTION_COMPLETE, true).apply();
mOverlayManager = IOverlayManager.Stub.asInterface(
ServiceManager.getService(Context.OVERLAY_SERVICE));
mVideoPreference = new VideoPreference(context);
setIllustrationVideo(mVideoPreference, getDefaultKey());
}
@Override
@@ -53,17 +88,154 @@ public class SystemNavigationGestureSettings extends DashboardFragment {
return SettingsEnums.SETTINGS_GESTURE_SWIPE_UP;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.system_navigation_gesture_settings;
}
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
@Override
protected void addStaticPreferences(PreferenceScreen screen) {
screen.addPreference(mVideoPreference);
}
@Override
protected List<? extends CandidateInfo> getCandidates() {
final Context c = getContext();
List<NavModeCandidateInfo> candidates = new ArrayList<>();
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
NAV_BAR_MODE_GESTURAL_OVERLAY)) {
candidates.add(new NavModeCandidateInfo(
c.getText(R.string.edge_to_edge_navigation_title),
c.getText(R.string.edge_to_edge_navigation_summary),
KEY_SYSTEM_NAV_GESTURAL, true /* enabled */));
}
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
NAV_BAR_MODE_2BUTTON_OVERLAY)) {
candidates.add(new NavModeCandidateInfo(
c.getText(R.string.swipe_up_to_switch_apps_title),
c.getText(R.string.swipe_up_to_switch_apps_summary),
KEY_SYSTEM_NAV_2BUTTONS, true /* enabled */));
}
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
NAV_BAR_MODE_3BUTTON_OVERLAY)) {
candidates.add(new NavModeCandidateInfo(
c.getText(R.string.legacy_navigation_title),
c.getText(R.string.legacy_navigation_summary),
KEY_SYSTEM_NAV_3BUTTONS, true /* enabled */));
}
return candidates;
}
@Override
protected String getDefaultKey() {
return getCurrentSystemNavigationMode(getContext());
}
@Override
protected boolean setDefaultKey(String key) {
setCurrentSystemNavigationMode(mOverlayManager, key);
setIllustrationVideo(mVideoPreference, key);
return true;
}
@VisibleForTesting
static String getCurrentSystemNavigationMode(Context context) {
if (SystemNavigationPreferenceController.isEdgeToEdgeEnabled(context)) {
return KEY_SYSTEM_NAV_GESTURAL;
} else if (SystemNavigationPreferenceController.isSwipeUpEnabled(context)) {
return KEY_SYSTEM_NAV_2BUTTONS;
} else {
return KEY_SYSTEM_NAV_3BUTTONS;
}
}
@VisibleForTesting
static void setCurrentSystemNavigationMode(IOverlayManager overlayManager, String key) {
switch (key) {
case KEY_SYSTEM_NAV_GESTURAL:
setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_GESTURAL_OVERLAY);
break;
case KEY_SYSTEM_NAV_2BUTTONS:
setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_2BUTTON_OVERLAY);
break;
case KEY_SYSTEM_NAV_3BUTTONS:
setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_3BUTTON_OVERLAY);
break;
}
}
/**
* Enables the specified overlay package.
*/
static void setNavBarInteractionMode(IOverlayManager overlayManager, String overlayPackage) {
try {
overlayManager.setEnabledExclusiveInCategory(overlayPackage, USER_CURRENT);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
static void setIllustrationVideo(VideoPreference videoPref, String systemNavKey) {
videoPref.setVideo(0, 0);
switch (systemNavKey) {
case KEY_SYSTEM_NAV_GESTURAL:
videoPref.setVideo(R.raw.system_nav_fully_gestural,
R.drawable.system_nav_fully_gestural);
break;
case KEY_SYSTEM_NAV_2BUTTONS:
videoPref.setVideo(R.raw.system_nav_2_button, R.drawable.system_nav_2_button);
break;
case KEY_SYSTEM_NAV_3BUTTONS:
videoPref.setVideo(R.raw.system_nav_3_button, R.drawable.system_nav_3_button);
break;
}
}
@Override
public void bindPreferenceExtra(RadioButtonPreference pref,
String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
if (info instanceof NavModeCandidateInfo) {
pref.setSummary(((NavModeCandidateInfo) info).loadSummary());
pref.setAppendixVisibility(View.GONE);
}
}
static class NavModeCandidateInfo extends CandidateInfo {
private final CharSequence mLabel;
private final CharSequence mSummary;
private final String mKey;
NavModeCandidateInfo(CharSequence label, CharSequence summary, String key,
boolean enabled) {
super(enabled);
mLabel = label;
mSummary = summary;
mKey = key;
}
@Override
public CharSequence loadLabel() {
return mLabel;
}
public CharSequence loadSummary() {
return mSummary;
}
@Override
public Drawable loadIcon() {
return null;
}
@Override
public String getKey() {
return mKey;
}
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(

View File

@@ -1,55 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.gestures;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
import android.content.Context;
import android.content.om.IOverlayManager;
import android.os.ServiceManager;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import com.android.settings.widget.RadioButtonPreference;
public class SystemNavigationLegacyPreferenceController extends
SystemNavigationPreferenceController {
static final String PREF_KEY_LEGACY = "gesture_legacy";
public SystemNavigationLegacyPreferenceController(Context context, String key) {
this(context, IOverlayManager.Stub.asInterface(ServiceManager.getService(
Context.OVERLAY_SERVICE)), key);
}
@VisibleForTesting
public SystemNavigationLegacyPreferenceController(Context context,
IOverlayManager overlayManager, String key) {
super(context, overlayManager, key, NAV_BAR_MODE_3BUTTON_OVERLAY);
}
@Override
public void onRadioButtonClicked(RadioButtonPreference preference) {
setNavBarInteractionMode(mOverlayManager, NAV_BAR_MODE_3BUTTON_OVERLAY);
selectRadioButtonInGroup(PREF_KEY_LEGACY, mPreferenceScreen);
}
@Override
public boolean isChecked() {
return !isEdgeToEdgeEnabled(mContext) && !isSwipeUpEnabled(mContext);
}
}

View File

@@ -16,79 +16,29 @@
package com.android.settings.gestures;
import static android.os.UserHandle.USER_CURRENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.om.IOverlayManager;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.text.TextUtils;
import android.view.View;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.widget.RadioButtonPreference;
import com.android.settings.core.BasePreferenceController;
public abstract class SystemNavigationPreferenceController extends GesturePreferenceController
implements RadioButtonPreference.OnClickListener {
public class SystemNavigationPreferenceController extends BasePreferenceController {
static final String PREF_KEY_SYSTEM_NAVIGATION = "gesture_system_navigation";
private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
private static final String PREF_KEY_VIDEO = "gesture_swipe_up_video";
private static final String[] RADIO_BUTTONS_IN_GROUP = {
SystemNavigationLegacyPreferenceController.PREF_KEY_LEGACY,
SystemNavigationSwipeUpPreferenceController.PREF_KEY_SWIPE_UP,
SystemNavigationEdgeToEdgePreferenceController.PREF_KEY_EDGE_TO_EDGE,
};
protected final IOverlayManager mOverlayManager;
protected PreferenceScreen mPreferenceScreen;
private final String mOverlayPackage;
public SystemNavigationPreferenceController(Context context, IOverlayManager overlayManager,
String key, String overlayPackage) {
public SystemNavigationPreferenceController(Context context, String key) {
super(context, key);
mOverlayManager = overlayManager;
mOverlayPackage = overlayPackage;
}
@Override
public int getAvailabilityStatus() {
return isGestureAvailable(mContext, mOverlayPackage) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreferenceScreen = screen;
Preference preference = screen.findPreference(getPreferenceKey());
if (preference != null && preference instanceof RadioButtonPreference) {
RadioButtonPreference radioPreference = (RadioButtonPreference) preference;
radioPreference.setOnClickListener(this);
radioPreference.setAppendixVisibility(View.GONE);
}
}
@Override
public boolean setChecked(boolean isChecked) {
if (!isChecked || mPreferenceScreen == null) {
return false;
}
Preference preference = mPreferenceScreen.findPreference(getPreferenceKey());
if (preference != null && preference instanceof RadioButtonPreference) {
onRadioButtonClicked((RadioButtonPreference) preference);
}
return true;
return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -102,17 +52,7 @@ public abstract class SystemNavigationPreferenceController extends GesturePrefer
}
}
@Override
protected String getVideoPrefKey() {
return PREF_KEY_VIDEO;
}
static boolean isGestureAvailable(Context context) {
return isGestureAvailable(context, null /* overlayPackage */);
}
static boolean isGestureAvailable(Context context, String overlayPackage) {
// Skip if the swipe up settings are not available
if (!context.getResources().getBoolean(
com.android.internal.R.bool.config_swipe_up_gesture_setting_available)) {
@@ -127,44 +67,22 @@ public abstract class SystemNavigationPreferenceController extends GesturePrefer
}
// Skip if the overview proxy service exists
final PackageManager pm = context.getPackageManager();
final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
.setPackage(recentsComponentName.getPackageName());
if (pm.resolveService(quickStepIntent, PackageManager.MATCH_SYSTEM_ONLY) == null) {
if (context.getPackageManager().resolveService(quickStepIntent,
PackageManager.MATCH_SYSTEM_ONLY) == null) {
return false;
}
// Skip if the required overlay package is defined but doesn't exist
if (overlayPackage != null) {
try {
return pm.getPackageInfo(overlayPackage, 0 /* flags */) != null;
} catch (PackageManager.NameNotFoundException e) {
// Not found, just return unavailable
return false;
}
}
return true;
}
static void selectRadioButtonInGroup(String preferenceKey, PreferenceScreen screen) {
if (screen == null) {
return;
}
for (String key : RADIO_BUTTONS_IN_GROUP) {
((RadioButtonPreference) screen.findPreference(key)).setChecked(
TextUtils.equals(key, preferenceKey));
}
}
/**
* Enables the specified overlay package.
*/
static void setNavBarInteractionMode(IOverlayManager overlayManager, String overlayPackage) {
static boolean isOverlayPackageAvailable(Context context, String overlayPackage) {
try {
overlayManager.setEnabledExclusiveInCategory(overlayPackage, USER_CURRENT);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
return context.getPackageManager().getPackageInfo(overlayPackage, 0) != null;
} catch (PackageManager.NameNotFoundException e) {
// Not found, just return unavailable
return false;
}
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.gestures;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
import android.content.Context;
import android.content.om.IOverlayManager;
import android.os.ServiceManager;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import com.android.settings.widget.RadioButtonPreference;
public class SystemNavigationSwipeUpPreferenceController extends
SystemNavigationPreferenceController {
static final String PREF_KEY_SWIPE_UP = "gesture_swipe_up";
public SystemNavigationSwipeUpPreferenceController(Context context, String key) {
this(context, IOverlayManager.Stub.asInterface(ServiceManager.getService(
Context.OVERLAY_SERVICE)), key);
}
@VisibleForTesting
public SystemNavigationSwipeUpPreferenceController(Context context,
IOverlayManager overlayManager, String key) {
super(context, overlayManager, key, NAV_BAR_MODE_2BUTTON_OVERLAY);
}
@Override
public void onRadioButtonClicked(RadioButtonPreference preference) {
setNavBarInteractionMode(mOverlayManager, NAV_BAR_MODE_2BUTTON_OVERLAY);
selectRadioButtonInGroup(PREF_KEY_SWIPE_UP, mPreferenceScreen);
}
@Override
public boolean isChecked() {
return isSwipeUpEnabled(mContext);
}
}

View File

@@ -27,16 +27,16 @@ import android.widget.Toolbar;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.android.settings.R;
import com.android.settings.accounts.AvatarViewMixin;
import com.android.settings.core.SettingsBaseActivity;
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
import com.android.settings.overlay.FeatureFactory;
public class SettingsHomepageActivity extends SettingsBaseActivity {
public class SettingsHomepageActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {

View File

@@ -33,12 +33,11 @@ import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.homepage.contextualcards.slices.SwipeDismissalDelegate;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.slice.ContextualWifiScanWorker;
public class ContextualCardsFragment extends InstrumentedFragment implements
FocusRecyclerView.FocusListener {
private static final String TAG = "ContextualCardsFragment";
private FocusRecyclerView mCardsContainer;
private GridLayoutManager mLayoutManager;
private ContextualCardsAdapter mContextualCardsAdapter;
@@ -60,6 +59,7 @@ public class ContextualCardsFragment extends InstrumentedFragment implements
@Override
public void onStart() {
super.onStart();
ContextualWifiScanWorker.newVisibleUiSession();
mContextualCardManager.loadContextualCards(LoaderManager.getInstance(this));
}

View File

@@ -33,7 +33,7 @@ import com.android.settings.search.Indexable;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.location.RecentLocationAccesses;
import com.android.settingslib.location.RecentLocationApps;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
@@ -50,7 +50,7 @@ import java.util.List;
* <li>In switch bar: location master switch. Used to toggle location on and off.
* </li>
* </ul>
* <li>Recent location requests: automatically populated by {@link RecentLocationAccesses}</li>
* <li>Recent location requests: automatically populated by {@link RecentLocationApps}</li>
* <li>Location services: multi-app settings provided from outside the Android framework. Each
* is injected by a system-partition app via the {@link SettingInjectorService} API.</li>
* </ul>
@@ -118,7 +118,7 @@ public class LocationSettings extends DashboardFragment {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new AppLocationPermissionPreferenceController(context, lifecycle));
controllers.add(new LocationForWorkPreferenceController(context, lifecycle));
controllers.add(new RecentLocationAccessPreferenceController(context));
controllers.add(new RecentLocationRequestPreferenceController(context, fragment, lifecycle));
controllers.add(new LocationScanningPreferenceController(context));
controllers.add(new LocationServicePreferenceController(context, fragment, lifecycle));
controllers.add(new LocationFooterPreferenceController(context, lifecycle));

View File

@@ -0,0 +1,145 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.android.settings.location;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.location.RecentLocationApps;
import com.android.settingslib.widget.apppreference.AppPreference;
import java.util.List;
public class RecentLocationRequestPreferenceController extends LocationBasePreferenceController {
/** Key for preference category "Recent location requests" */
private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests";
@VisibleForTesting
static final String KEY_SEE_ALL_BUTTON = "recent_location_requests_see_all_button";
private final LocationSettings mFragment;
private final RecentLocationApps mRecentLocationApps;
private PreferenceCategory mCategoryRecentLocationRequests;
/** Used in this class and {@link RecentLocationRequestSeeAllPreferenceController} */
static class PackageEntryClickedListener implements Preference.OnPreferenceClickListener {
private final DashboardFragment mFragment;
private final String mPackage;
private final UserHandle mUserHandle;
public PackageEntryClickedListener(DashboardFragment fragment, String packageName,
UserHandle userHandle) {
mFragment = fragment;
mPackage = packageName;
mUserHandle = userHandle;
}
@Override
public boolean onPreferenceClick(Preference preference) {
// start new fragment to display extended information
final Bundle args = new Bundle();
args.putString(AppInfoDashboardFragment.ARG_PACKAGE_NAME, mPackage);
new SubSettingLauncher(mFragment.getContext())
.setDestination(AppInfoDashboardFragment.class.getName())
.setArguments(args)
.setTitleRes(R.string.application_info_label)
.setUserHandle(mUserHandle)
.setSourceMetricsCategory(mFragment.getMetricsCategory())
.launch();
return true;
}
}
public RecentLocationRequestPreferenceController(Context context, LocationSettings fragment,
Lifecycle lifecycle) {
this(context, fragment, lifecycle, new RecentLocationApps(context));
}
@VisibleForTesting
RecentLocationRequestPreferenceController(Context context, LocationSettings fragment,
Lifecycle lifecycle, RecentLocationApps recentApps) {
super(context, lifecycle);
mFragment = fragment;
mRecentLocationApps = recentApps;
}
@Override
public String getPreferenceKey() {
return KEY_RECENT_LOCATION_REQUESTS;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mCategoryRecentLocationRequests =
(PreferenceCategory) screen.findPreference(KEY_RECENT_LOCATION_REQUESTS);
}
@Override
public void updateState(Preference preference) {
mCategoryRecentLocationRequests.removeAll();
final Context prefContext = preference.getContext();
final List<RecentLocationApps.Request> recentLocationRequests =
mRecentLocationApps.getAppListSorted(false);
if (recentLocationRequests.size() > 3) {
// Display the top 3 preferences to container in original order.
for (int i = 0; i < 3; i++) {
mCategoryRecentLocationRequests.addPreference(
createAppPreference(prefContext, recentLocationRequests.get(i)));
}
} else if (recentLocationRequests.size() > 0) {
// Add preferences to container in original order (already sorted by recency).
for (RecentLocationApps.Request request : recentLocationRequests) {
mCategoryRecentLocationRequests.addPreference(
createAppPreference(prefContext, request));
}
} else {
// If there's no item to display, add a "No recent apps" item.
final Preference banner = createAppPreference(prefContext);
banner.setTitle(R.string.location_no_recent_apps);
banner.setSelectable(false);
mCategoryRecentLocationRequests.addPreference(banner);
}
}
@Override
public void onLocationModeChanged(int mode, boolean restricted) {
mCategoryRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode));
}
@VisibleForTesting
AppPreference createAppPreference(Context prefContext) {
return new AppPreference(prefContext);
}
@VisibleForTesting
AppPreference createAppPreference(Context prefContext, RecentLocationApps.Request request) {
final AppPreference pref = createAppPreference(prefContext);
pref.setSummary(request.contentDescription);
pref.setIcon(request.icon);
pref.setTitle(request.label);
pref.setOnPreferenceClickListener(new PackageEntryClickedListener(
mFragment, request.packageName, request.userHandle));
return pref;
}
}

View File

@@ -0,0 +1,135 @@
/*
* Copyright 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.location;
import android.content.Context;
import android.provider.SearchIndexableResource;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** Dashboard Fragment to display all recent location requests, sorted by recency. */
@SearchIndexable
public class RecentLocationRequestSeeAllFragment extends DashboardFragment {
private static final String TAG = "RecentLocationReqAll";
public static final String PATH =
"com.android.settings.location.RecentLocationRequestSeeAllFragment";
private static final int MENU_SHOW_SYSTEM = Menu.FIRST + 1;
private static final int MENU_HIDE_SYSTEM = Menu.FIRST + 2;
private boolean mShowSystem = false;
private MenuItem mShowSystemMenu;
private MenuItem mHideSystemMenu;
private RecentLocationRequestSeeAllPreferenceController mController;
@Override
public int getMetricsCategory() {
return MetricsEvent.RECENT_LOCATION_REQUESTS_ALL;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.location_recent_requests_see_all;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle(), this);
}
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case MENU_SHOW_SYSTEM:
case MENU_HIDE_SYSTEM:
mShowSystem = menuItem.getItemId() == MENU_SHOW_SYSTEM;
updateMenu();
if (mController != null) {
mController.setShowSystem(mShowSystem);
}
return true;
default:
return super.onOptionsItemSelected(menuItem);
}
}
private void updateMenu() {
mShowSystemMenu.setVisible(!mShowSystem);
mHideSystemMenu.setVisible(mShowSystem);
}
private static List<AbstractPreferenceController> buildPreferenceControllers(
Context context, Lifecycle lifecycle, RecentLocationRequestSeeAllFragment fragment) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
final RecentLocationRequestSeeAllPreferenceController controller =
new RecentLocationRequestSeeAllPreferenceController(context, lifecycle, fragment);
controllers.add(controller);
if (fragment != null) {
fragment.mController = controller;
}
return controllers;
}
/**
* For Search.
*/
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.location_recent_requests_see_all;
return Arrays.asList(sir);
}
@Override
public List<AbstractPreferenceController> getPreferenceControllers(Context
context) {
return buildPreferenceControllers(
context, /* lifecycle = */ null, /* fragment = */ null);
}
};
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
mShowSystemMenu = menu.add(Menu.NONE, MENU_SHOW_SYSTEM, Menu.NONE,
R.string.menu_show_system);
mHideSystemMenu = menu.add(Menu.NONE, MENU_HIDE_SYSTEM, Menu.NONE,
R.string.menu_hide_system);
updateMenu();
}
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright 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.location;
import android.content.Context;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.location.RecentLocationApps;
import com.android.settingslib.widget.apppreference.AppPreference;
import java.util.List;
import com.android.settings.R;
/** Preference controller for preference category displaying all recent location requests. */
public class RecentLocationRequestSeeAllPreferenceController
extends LocationBasePreferenceController {
/** Key for preference category "All recent location requests" */
private static final String KEY_ALL_RECENT_LOCATION_REQUESTS = "all_recent_location_requests";
private final RecentLocationRequestSeeAllFragment mFragment;
private PreferenceCategory mCategoryAllRecentLocationRequests;
private RecentLocationApps mRecentLocationApps;
private boolean mShowSystem = false;
private Preference mPreference;
public RecentLocationRequestSeeAllPreferenceController(
Context context, Lifecycle lifecycle, RecentLocationRequestSeeAllFragment fragment) {
this(context, lifecycle, fragment, new RecentLocationApps(context));
}
@VisibleForTesting
RecentLocationRequestSeeAllPreferenceController(
Context context,
Lifecycle lifecycle,
RecentLocationRequestSeeAllFragment fragment,
RecentLocationApps recentLocationApps) {
super(context, lifecycle);
mFragment = fragment;
mRecentLocationApps = recentLocationApps;
}
@Override
public String getPreferenceKey() {
return KEY_ALL_RECENT_LOCATION_REQUESTS;
}
@Override
public void onLocationModeChanged(int mode, boolean restricted) {
mCategoryAllRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode));
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mCategoryAllRecentLocationRequests =
(PreferenceCategory) screen.findPreference(KEY_ALL_RECENT_LOCATION_REQUESTS);
}
@Override
public void updateState(Preference preference) {
mCategoryAllRecentLocationRequests.removeAll();
mPreference = preference;
List<RecentLocationApps.Request> requests = mRecentLocationApps.getAppListSorted(
mShowSystem);
if (requests.isEmpty()) {
// If there's no item to display, add a "No recent apps" item.
final Preference banner = new AppPreference(mContext);
banner.setTitle(R.string.location_no_recent_apps);
banner.setSelectable(false);
mCategoryAllRecentLocationRequests.addPreference(banner);
} else {
for (RecentLocationApps.Request request : requests) {
Preference appPreference = createAppPreference(preference.getContext(), request);
mCategoryAllRecentLocationRequests.addPreference(appPreference);
}
}
}
@VisibleForTesting
AppPreference createAppPreference(
Context prefContext, RecentLocationApps.Request request) {
final AppPreference pref = new AppPreference(prefContext);
pref.setSummary(request.contentDescription);
pref.setIcon(request.icon);
pref.setTitle(request.label);
pref.setOnPreferenceClickListener(
new RecentLocationRequestPreferenceController.PackageEntryClickedListener(
mFragment, request.packageName, request.userHandle));
return pref;
}
public void setShowSystem(boolean showSystem) {
mShowSystem = showSystem;
if (mPreference != null) {
updateState(mPreference);
}
}
}

View File

@@ -24,6 +24,7 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.core.graphics.drawable.IconCompat;
@@ -113,9 +114,14 @@ public class MediaOutputIndicatorSlice implements CustomSliceable {
private boolean isVisible() {
// To decide Slice's visibility.
// return true if device is connected or previously connected, false for other cases.
return !CollectionUtils.isEmpty(getConnectedA2dpDevices())
|| !CollectionUtils.isEmpty(getConnectedHearingAidDevices());
// Return true if
// 1. phone is not in ongoing call mode
// 2. Bluetooth device is connected
final TelephonyManager telephonyManager =
(TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
return telephonyManager.getCallState() == TelephonyManager.CALL_STATE_IDLE
&& (!CollectionUtils.isEmpty(getConnectedA2dpDevices())
|| !CollectionUtils.isEmpty(getConnectedHearingAidDevices()));
}
private List<BluetoothDevice> getConnectedA2dpDevices() {

View File

@@ -78,4 +78,9 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements
notifySliceChange();
}
}
@Override
public void onAudioModeChanged() {
notifySliceChange();
}
}

View File

@@ -65,8 +65,11 @@ public class ApnPreferenceController extends TelephonyBasePreferenceController i
final boolean isGsmApn = MobileNetworkUtils.isGsmOptions(mContext, subId)
&& carrierConfig != null
&& carrierConfig.getBoolean(CarrierConfigManager.KEY_APN_EXPAND_BOOL);
final boolean hideCarrierNetwork = carrierConfig == null
|| carrierConfig.getBoolean(
CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL);
return isCdmaApn || isGsmApn
return !hideCarrierNetwork && (isCdmaApn || isGsmApn)
? AVAILABLE
: CONDITIONALLY_UNAVAILABLE;
}

View File

@@ -355,6 +355,8 @@ public class MobileNetworkUtils {
|| carrierConfig == null
|| !carrierConfig.getBoolean(
CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL)
|| carrierConfig.getBoolean(
CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)
|| (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL)
&& !telephonyManager.isManualNetworkSelectionAllowed())) {
return false;

View File

@@ -52,7 +52,6 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
private static final long MINIMUM_DIALOG_TIME_MILLIS = TimeUnit.SECONDS.toMillis(1);
private final Handler mUiHandler;
private int mSubId;
private TelephonyManager mTelephonyManager;
private boolean mOnlyAutoSelectInHome;
private List<OnNetworkSelectModeListener> mListeners;

View File

@@ -42,7 +42,6 @@ public class OpenNetworkSelectPagePreferenceController extends
TelephonyBasePreferenceController implements
AutoSelectPreferenceController.OnNetworkSelectModeListener {
private int mSubId;
private TelephonyManager mTelephonyManager;
private Preference mPreference;

View File

@@ -1,124 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
public class BubbleNotificationPreferenceController extends TogglePreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
LifecycleObserver, OnResume, OnPause {
private static final String TAG = "BubbleNotifPrefContr";
@VisibleForTesting
static final int ON = 1;
@VisibleForTesting
static final int OFF = 0;
private SettingObserver mSettingObserver;
public BubbleNotificationPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
Preference preference = screen.findPreference(getPreferenceKey());
if (preference != null) {
mSettingObserver = new SettingObserver(preference);
}
}
@Override
public void onResume() {
if (mSettingObserver != null) {
mSettingObserver.register(mContext.getContentResolver(), true /* register */);
}
}
@Override
public void onPause() {
if (mSettingObserver != null) {
mSettingObserver.register(mContext.getContentResolver(), false /* register */);
}
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public boolean isChecked() {
return Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, ON) == ON;
}
@Override
public boolean setChecked(boolean isChecked) {
return Settings.Secure.putInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, isChecked ? ON : OFF);
}
class SettingObserver extends ContentObserver {
private final Uri NOTIFICATION_BUBBLES_URI =
Settings.Secure.getUriFor(NOTIFICATION_BUBBLES);
private final Preference mPreference;
public SettingObserver(Preference preference) {
super(new Handler());
mPreference = preference;
}
public void register(ContentResolver cr, boolean register) {
if (register) {
cr.registerContentObserver(NOTIFICATION_BUBBLES_URI, false, this);
} else {
cr.unregisterContentObserver(this);
}
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (NOTIFICATION_BUBBLES_URI.equals(uri)) {
updateState(mPreference);
}
}
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.provider.SearchIndexableResource;
import com.android.settings.R;
import com.android.settings.core.OnActivityResultListener;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
import java.util.Arrays;
import java.util.List;
@SearchIndexable
public class BubbleNotificationSettings extends DashboardFragment implements
OnActivityResultListener {
private static final String TAG = "BubbleNotiSettings";
@Override
public int getMetricsCategory() {
return SettingsEnums.BUBBLE_SETTINGS;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.bubble_notification_settings;
}
/**
* For Search.
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.bubble_notification_settings;
return Arrays.asList(sir);
}
};
}

View File

@@ -25,6 +25,7 @@ import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.RestrictedSwitchPreference;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
@@ -33,8 +34,10 @@ public class BubblePreferenceController extends NotificationPreferenceController
private static final String TAG = "BubblePrefContr";
private static final String KEY = "bubble_pref";
private static final int SYSTEM_WIDE_ON = 1;
private static final int SYSTEM_WIDE_OFF = 0;
@VisibleForTesting
static final int SYSTEM_WIDE_ON = 1;
@VisibleForTesting
static final int SYSTEM_WIDE_OFF = 0;
private FragmentManager mFragmentManager;
@@ -58,18 +61,14 @@ public class BubblePreferenceController extends NotificationPreferenceController
if (!super.isAvailable()) {
return false;
}
if (mAppRow == null && mChannel == null) {
if (!isGloballyEnabled()) {
return false;
}
if (mChannel != null) {
if (Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_OFF) {
return false;
}
if (isDefaultChannel()) {
return true;
} else {
return mAppRow == null ? false : mAppRow.allowBubbles;
return mAppRow != null && mAppRow.allowBubbles;
}
}
return true;
@@ -80,12 +79,10 @@ public class BubblePreferenceController extends NotificationPreferenceController
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
pref.setDisabledByAdmin(mAdmin);
if (mChannel != null) {
pref.setChecked(mChannel.canBubble());
pref.setChecked(mChannel.canBubble() && isGloballyEnabled());
pref.setEnabled(!pref.isDisabledByAdmin());
} else {
pref.setChecked(mAppRow.allowBubbles
&& Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_ON);
pref.setChecked(mAppRow.allowBubbles && isGloballyEnabled());
pref.setSummary(mContext.getString(
R.string.bubbles_app_toggle_summary, mAppRow.label));
}
@@ -94,7 +91,7 @@ public class BubblePreferenceController extends NotificationPreferenceController
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean value = (Boolean) newValue;
final boolean value = (Boolean) newValue && isGloballyEnabled();
if (mChannel != null) {
mChannel.setAllowBubbles(value);
saveChannel();
@@ -103,9 +100,7 @@ public class BubblePreferenceController extends NotificationPreferenceController
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
// if the global setting is off, toggling app level permission requires extra
// confirmation
if (Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_OFF
&& !pref.isChecked()) {
if (!isGloballyEnabled() && !pref.isChecked()) {
new BubbleWarningDialogFragment()
.setPkgInfo(mAppRow.pkg, mAppRow.uid)
.show(mFragmentManager, "dialog");
@@ -118,6 +113,11 @@ public class BubblePreferenceController extends NotificationPreferenceController
return true;
}
private boolean isGloballyEnabled() {
return Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF) == SYSTEM_WIDE_ON;
}
// Used in app level prompt that confirms the user is ok with turning on bubbles
// globally. If they aren't, undo what
public static void revertBubblesApproval(Context mContext, String pkg, int uid) {

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import androidx.annotation.VisibleForTesting;
public class BubbleSummaryNotificationPreferenceController extends BasePreferenceController {
@VisibleForTesting
static final int ON = 1;
public BubbleSummaryNotificationPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public CharSequence getSummary() {
return mContext.getString(
areBubblesEnabled() ? R.string.switch_on_text : R.string.switch_off_text);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
private boolean areBubblesEnabled() {
return Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, ON) == ON;
}
}

View File

@@ -27,13 +27,16 @@ import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.core.SubSettingLauncher;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
public class BubbleSummaryPreferenceController extends NotificationPreferenceController {
private static final String KEY = "bubble_link_pref";
private static final int SYSTEM_WIDE_ON = 1;
private static final int SYSTEM_WIDE_OFF = 0;
@VisibleForTesting
static final int SYSTEM_WIDE_ON = 1;
@VisibleForTesting
static final int SYSTEM_WIDE_OFF = 0;
public BubbleSummaryPreferenceController(Context context, NotificationBackend backend) {
super(context, backend);
@@ -53,17 +56,16 @@ public class BubbleSummaryPreferenceController extends NotificationPreferenceCon
return false;
}
if (mChannel != null) {
if (Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_OFF) {
if (!isGloballyEnabled()) {
return false;
}
if (isDefaultChannel()) {
return true;
} else {
return mAppRow == null ? false : mAppRow.allowBubbles;
return mAppRow != null && mAppRow.allowBubbles;
}
}
return true;
return isGloballyEnabled();
}
@Override
@@ -89,13 +91,16 @@ public class BubbleSummaryPreferenceController extends NotificationPreferenceCon
boolean canBubble = false;
if (mAppRow != null) {
if (mChannel != null) {
canBubble |= mChannel.canBubble();
canBubble |= mChannel.canBubble() && isGloballyEnabled();
} else {
canBubble |= mAppRow.allowBubbles
&& (Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_ON);
canBubble |= mAppRow.allowBubbles && isGloballyEnabled();
}
}
return mContext.getString(canBubble ? R.string.switch_on_text : R.string.switch_off_text);
}
private boolean isGloballyEnabled() {
return Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF) == SYSTEM_WIDE_ON;
}
}

View File

@@ -18,13 +18,10 @@ package com.android.settings.panel;
import static com.android.settingslib.media.MediaOutputSliceConstants.EXTRA_PACKAGE_NAME;
import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
@@ -35,8 +32,6 @@ import androidx.fragment.app.FragmentManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.panel.PanelLoggingContract.PanelClosedKeys;
/**
* Dialog Activity to host Settings Slices.
@@ -66,17 +61,17 @@ public class SettingsPanelActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showOrUpdatePanel();
createOrUpdatePanel(true /* shouldForceCreation */);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
showOrUpdatePanel();
createOrUpdatePanel(false /* shouldForceCreation */);
}
private void showOrUpdatePanel() {
private void createOrUpdatePanel(boolean shouldForceCreation) {
final Intent callingIntent = getIntent();
if (callingIntent == null) {
Log.e(TAG, "Null intent, closing Panel Activity");
@@ -95,7 +90,7 @@ public class SettingsPanelActivity extends FragmentActivity {
final Fragment fragment = fragmentManager.findFragmentById(R.id.main_content);
// If fragment already exists, we will need to update panel with animation.
if (fragment != null && fragment instanceof PanelFragment) {
if (!shouldForceCreation && fragment != null && fragment instanceof PanelFragment) {
final PanelFragment panelFragment = (PanelFragment) fragment;
panelFragment.setArguments(mBundle);
((PanelFragment) fragment).updatePanelWithAnimation();

View File

@@ -18,9 +18,9 @@ public interface SlicesFeatureProvider {
/**
* Starts a new UI session for the purpose of using Slices.
*
* A UI session is defined as an duration of time when user stays in a UI screen. Screen
* rotation does not break the continuation of session, going to a sub-page and coming out does
* not break the continuation either. Leaving the page and coming back breaks it.
* A UI session is defined as a duration of time when user stays in a UI screen. Screen rotation
* does not break the continuation of session, going to a sub-page and coming out does not break
* the continuation either. Leaving the page and coming back breaks it.
*/
void newUiSession();

View File

@@ -24,8 +24,6 @@ import com.android.settings.network.telephony.Enhanced4gLteSliceHelper;
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
import com.android.settingslib.utils.ThreadUtils;
import java.util.Random;
/**
* Manages Slices in Settings.
*/

View File

@@ -29,7 +29,7 @@ import com.android.settings.wifi.dpp.WifiDppUtils;
import com.android.settingslib.wifi.AccessPoint;
/**
* {@link AbstractPreferenceController} that launches Wi-Fi Easy Connect configurator flow
* {@link BasePreferenceController} that launches Wi-Fi Easy Connect configurator flow
*/
public class AddDevicePreferenceController extends BasePreferenceController {

View File

@@ -313,9 +313,6 @@ public class QrCamera extends Handler {
private void setTransformationMatrix(Size viewSize) {
// Check aspect ratio, can only handle square view.
final int viewRatio = (int)getRatio(viewSize.getWidth(), viewSize.getHeight());
if (viewRatio != 1) {
throw new IllegalArgumentException("Preview area should be square");
}
final boolean isPortrait = mContext.get().getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT ? true : false;

View File

@@ -16,7 +16,9 @@
package com.android.settings.wifi.slice;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.wifi.WifiManager;
@@ -30,35 +32,36 @@ import com.android.settings.wifi.WifiUtils;
import com.android.settingslib.wifi.AccessPoint;
/**
* This activity helps connect to the Wi-Fi network which is open or saved
* This receiver helps connect to Wi-Fi network
*/
public class ConnectToWifiHandler extends Activity {
public class ConnectToWifiHandler extends BroadcastReceiver {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
public void onReceive(Context context, Intent intent) {
if (context == null || intent == null) {
return;
}
final Network network = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
final Bundle accessPointState = getIntent().getBundleExtra(
final Network network = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
final Bundle accessPointState = intent.getBundleExtra(
WifiDialogActivity.KEY_ACCESS_POINT_STATE);
if (network != null) {
WifiScanWorker.clearClickedWifi();
final ConnectivityManager cm = getSystemService(ConnectivityManager.class);
final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
// start captive portal app to sign in to network
cm.startCaptivePortalApp(network);
} else if (accessPointState != null) {
connect(new AccessPoint(this, accessPointState));
connect(context, new AccessPoint(context, accessPointState));
}
finish();
}
@VisibleForTesting
void connect(AccessPoint accessPoint) {
void connect(Context context, AccessPoint accessPoint) {
ContextualWifiScanWorker.saveSession();
WifiScanWorker.saveClickedWifi(accessPoint);
final WifiConnectListener connectListener = new WifiConnectListener(this);
final WifiConnectListener connectListener = new WifiConnectListener(context);
switch (WifiUtils.getConnectingType(accessPoint)) {
case WifiUtils.CONNECT_TYPE_OSU_PROVISION:
accessPoint.startOsuProvisioning(connectListener);
@@ -68,7 +71,7 @@ public class ConnectToWifiHandler extends Activity {
accessPoint.generateOpenNetworkConfig();
case WifiUtils.CONNECT_TYPE_SAVED_NETWORK:
final WifiManager wifiManager = getSystemService(WifiManager.class);
final WifiManager wifiManager = context.getSystemService(WifiManager.class);
wifiManager.connect(accessPoint.getConfig(), connectListener);
break;
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.settings.wifi.slice;
import android.content.Context;
import android.net.Uri;
import android.os.SystemClock;
import com.android.settings.slices.SliceBackgroundWorker;
/**
* {@link SliceBackgroundWorker} for Wi-Fi, used by {@link ContextualWifiSlice}.
*/
public class ContextualWifiScanWorker extends WifiScanWorker {
private static long sVisibleUiSessionToken;
private static long sActiveSession;
public ContextualWifiScanWorker(Context context, Uri uri) {
super(context, uri);
}
/**
* Starts a new visible UI session for the purpose of automatically starting captive portal.
*
* A visible UI session is defined as a duration of time when a UI screen is visible to user.
* Going to a sub-page and coming out breaks the continuation, leaving the page and coming back
* breaks it too.
*/
public static void newVisibleUiSession() {
sVisibleUiSessionToken = SystemClock.elapsedRealtime();
}
static void saveSession() {
sActiveSession = sVisibleUiSessionToken;
}
@Override
protected void clearClickedWifiOnSliceUnpinned() {
// Do nothing for contextual Wi-Fi slice
}
@Override
protected boolean isSessionValid() {
if (sVisibleUiSessionToken != sActiveSession) {
clearClickedWifi();
return false;
}
return true;
}
}

View File

@@ -90,4 +90,9 @@ public class ContextualWifiSlice extends WifiSlice {
&& !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY)
&& nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
@Override
public Class getBackgroundWorkerClass() {
return ContextualWifiScanWorker.class;
}
}

View File

@@ -50,7 +50,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* {@link SliceBackgroundWorker} for Wi-Fi, used by WifiSlice.
* {@link SliceBackgroundWorker} for Wi-Fi, used by {@link WifiSlice}.
*/
public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implements
WifiTracker.WifiListener {
@@ -84,7 +84,7 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implement
protected void onSliceUnpinned() {
mWifiTracker.onStop();
unregisterNetworkCallback();
clearClickedWifi();
clearClickedWifiOnSliceUnpinned();
}
@Override
@@ -157,6 +157,14 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implement
return !TextUtils.isEmpty(ssid) && TextUtils.equals(ssid, sClickedWifiSsid);
}
protected void clearClickedWifiOnSliceUnpinned() {
clearClickedWifi();
}
protected boolean isSessionValid() {
return true;
}
public void registerNetworkCallback(Network wifiNetwork) {
if (wifiNetwork == null) {
return;
@@ -224,12 +232,13 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implement
// Automatically start captive portal
if (!prevIsCaptivePortal && mIsCaptivePortal
&& isWifiClicked(mWifiTracker.getManager().getConnectionInfo())) {
&& isWifiClicked(mWifiTracker.getManager().getConnectionInfo())
&& isSessionValid()) {
final Intent intent = new Intent(mContext, ConnectToWifiHandler.class)
.putExtra(ConnectivityManager.EXTRA_NETWORK, network)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Starting activity in the system process needs to specify a user
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
// Sending a broadcast in the system process needs to specify a user
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
}
}

View File

@@ -94,6 +94,7 @@ public class WifiSlice implements CustomSliceable {
final boolean isWifiEnabled = isWifiEnabled();
ListBuilder listBuilder = getHeaderRow(isWifiEnabled);
if (!isWifiEnabled) {
WifiScanWorker.clearClickedWifi();
return listBuilder.build();
}
@@ -133,6 +134,17 @@ public class WifiSlice implements CustomSliceable {
return listBuilder.build();
}
private void handleNetworkCallback(WifiScanWorker worker, boolean isFirstApActive) {
if (worker == null) {
return;
}
if (isFirstApActive) {
worker.registerNetworkCallback(mWifiManager.getCurrentNetwork());
} else {
worker.unregisterNetworkCallback();
}
}
private ListBuilder getHeaderRow(boolean isWifiEnabled) {
final IconCompat icon = IconCompat.createWithResource(mContext,
R.drawable.ic_settings_wireless);
@@ -155,17 +167,6 @@ public class WifiSlice implements CustomSliceable {
.setPrimaryAction(primarySliceAction));
}
private void handleNetworkCallback(WifiScanWorker worker, boolean isFirstApActive) {
if (worker == null) {
return;
}
if (isFirstApActive) {
worker.registerNetworkCallback(mWifiManager.getCurrentNetwork());
} else {
worker.unregisterNetworkCallback();
}
}
private ListBuilder.RowBuilder getAccessPointRow(AccessPoint accessPoint) {
final boolean isCaptivePortal = accessPoint.isActive() && isCaptivePortal();
final CharSequence title = accessPoint.getTitle();
@@ -175,9 +176,8 @@ public class WifiSlice implements CustomSliceable {
.setTitleItem(levelIcon, ListBuilder.ICON_IMAGE)
.setTitle(title)
.setSubtitle(summary)
.setPrimaryAction(SliceAction.createDeeplink(
getAccessPointAction(accessPoint, isCaptivePortal), levelIcon,
ListBuilder.ICON_IMAGE, title));
.setPrimaryAction(getAccessPointAction(accessPoint, isCaptivePortal, levelIcon,
title));
if (isCaptivePortal) {
rowBuilder.addEndItem(getCaptivePortalEndAction(accessPoint, title));
@@ -203,7 +203,7 @@ public class WifiSlice implements CustomSliceable {
final Drawable d = mContext.getDrawable(
com.android.settingslib.Utils.getWifiIconResource(accessPoint.getLevel()));
@ColorInt int color;
final @ColorInt int color;
if (accessPoint.isActive()) {
final NetworkInfo.State state = accessPoint.getNetworkInfo().getState();
if (state == NetworkInfo.State.CONNECTED) {
@@ -232,36 +232,54 @@ public class WifiSlice implements CustomSliceable {
}
private SliceAction getCaptivePortalEndAction(AccessPoint accessPoint, CharSequence title) {
return SliceAction.createDeeplink(
getAccessPointAction(accessPoint, false /* isCaptivePortal */),
IconCompat.createWithResource(mContext, R.drawable.ic_settings_accent),
ListBuilder.ICON_IMAGE, title);
return getAccessPointAction(accessPoint, false /* isCaptivePortal */,
IconCompat.createWithResource(mContext, R.drawable.ic_settings_accent), title);
}
private PendingIntent getAccessPointAction(AccessPoint accessPoint, boolean isCaptivePortal) {
private SliceAction getAccessPointAction(AccessPoint accessPoint, boolean isCaptivePortal,
IconCompat icon, CharSequence title) {
final int requestCode = accessPoint.hashCode();
if (isCaptivePortal) {
final Intent intent = new Intent(mContext, ConnectToWifiHandler.class)
.putExtra(ConnectivityManager.EXTRA_NETWORK, mWifiManager.getCurrentNetwork());
return getBroadcastAction(requestCode, intent, icon, title);
}
final Bundle extras = new Bundle();
accessPoint.saveWifiState(extras);
Intent intent;
if (isCaptivePortal) {
intent = new Intent(mContext, ConnectToWifiHandler.class);
intent.putExtra(ConnectivityManager.EXTRA_NETWORK, mWifiManager.getCurrentNetwork());
} else if (accessPoint.isActive()) {
intent = new SubSettingLauncher(mContext)
if (accessPoint.isActive()) {
final Intent intent = new SubSettingLauncher(mContext)
.setTitleRes(R.string.pref_title_network_details)
.setDestination(WifiNetworkDetailsFragment.class.getName())
.setArguments(extras)
.setSourceMetricsCategory(SettingsEnums.WIFI)
.toIntent();
return getActivityAction(requestCode, intent, icon, title);
} else if (WifiUtils.getConnectingType(accessPoint) != WifiUtils.CONNECT_TYPE_OTHERS) {
intent = new Intent(mContext, ConnectToWifiHandler.class);
intent.putExtra(WifiDialogActivity.KEY_ACCESS_POINT_STATE, extras);
final Intent intent = new Intent(mContext, ConnectToWifiHandler.class)
.putExtra(WifiDialogActivity.KEY_ACCESS_POINT_STATE, extras);
return getBroadcastAction(requestCode, intent, icon, title);
} else {
intent = new Intent(mContext, WifiDialogActivity.class);
intent.putExtra(WifiDialogActivity.KEY_ACCESS_POINT_STATE, extras);
final Intent intent = new Intent(mContext, WifiDialogActivity.class)
.putExtra(WifiDialogActivity.KEY_ACCESS_POINT_STATE, extras);
return getActivityAction(requestCode, intent, icon, title);
}
return PendingIntent.getActivity(mContext, accessPoint.hashCode() /* requestCode */,
intent, 0 /* flags */);
}
private SliceAction getActivityAction(int requestCode, Intent intent, IconCompat icon,
CharSequence title) {
final PendingIntent pi = PendingIntent.getActivity(mContext, requestCode, intent,
0 /* flags */);
return SliceAction.createDeeplink(pi, icon, ListBuilder.ICON_IMAGE, title);
}
private SliceAction getBroadcastAction(int requestCode, Intent intent, IconCompat icon,
CharSequence title) {
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
final PendingIntent pi = PendingIntent.getBroadcast(mContext, requestCode, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
return SliceAction.create(pi, icon, ListBuilder.ICON_IMAGE, title);
}
private ListBuilder.RowBuilder getLoadingRow(CharSequence placeholder) {
@@ -277,7 +295,7 @@ public class WifiSlice implements CustomSliceable {
.setSubtitle(title);
}
protected boolean isCaptivePortal() {
private boolean isCaptivePortal() {
final NetworkCapabilities nc = mConnectivityManager.getNetworkCapabilities(
mWifiManager.getCurrentNetwork());
return WifiUtils.canSignIntoNetwork(nc);

View File

@@ -27,7 +27,6 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
@@ -46,15 +45,16 @@ import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowSubscriptionManager;
import org.robolectric.shadows.ShadowTelephonyManager;
@Config(shadows = {
ShadowUtils.class,
@@ -71,7 +71,6 @@ public class DataUsageSummaryTest {
private NetworkPolicyManager mNetworkPolicyManager;
@Mock
private NetworkStatsManager mNetworkStatsManager;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private TelephonyManager mTelephonyManager;
private Context mContext;
private FragmentActivity mActivity;
@@ -90,8 +89,11 @@ public class DataUsageSummaryTest {
shadowContext.setSystemService(Context.NETWORK_POLICY_SERVICE, mNetworkPolicyManager);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
final ShadowTelephonyManager shadowTelephonyManager = Shadows.shadowOf(mTelephonyManager);
shadowTelephonyManager.setTelephonyManagerForSubscriptionId(
SubscriptionManager.INVALID_SUBSCRIPTION_ID, mTelephonyManager);
shadowTelephonyManager.setTelephonyManagerForSubscriptionId(1, mTelephonyManager);
mActivity = spy(Robolectric.buildActivity(FragmentActivity.class).get());
doReturn(mNetworkStatsManager).when(mActivity).getSystemService(NetworkStatsManager.class);
@@ -188,7 +190,7 @@ public class DataUsageSummaryTest {
ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true;
ShadowDataUsageUtils.HAS_SIM = false;
ShadowSubscriptionManager.setDefaultDataSubscriptionId(
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary());
doReturn(mContext).when(dataUsageSummary).getContext();

View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.development;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import static com.android.settings.development.BubbleGlobalPreferenceController.OFF;
import static com.android.settings.development.BubbleGlobalPreferenceController.ON;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class BubbleGlobalPreferenceControllerTest {
private Context mContext;
@Mock
private SwitchPreference mPreference;
@Mock
private PreferenceScreen mPreferenceScreen;
private BubbleGlobalPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new BubbleGlobalPreferenceController(mContext);
when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
.thenReturn(mPreference);
mController.displayPreference(mPreferenceScreen);
}
@Test
public void onPreferenceChange_settingEnabled_allowBubbles_shouldBeOn() {
mController.onPreferenceChange(mPreference, true /* new value */);
assertThat(isSettingEnabled()).isTrue();
}
@Test
public void onPreferenceChange_settingDisabled_allowBubbles_shouldBeOff() {
mController.onPreferenceChange(mPreference, false /* new value */);
assertThat(isSettingEnabled()).isFalse();
}
@Test
public void updateState_settingEnabled_preferenceShouldBeChecked() {
Settings.Secure.putInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, 1 /* enabled */);
mController.updateState(mPreference);
verify(mPreference).setChecked(true);
}
@Test
public void updateState_settingReset_defaultDisabled_preferenceShouldNotBeChecked() {
Settings.Secure.putInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, 0 /* enabled */);
mController.updateState(mPreference);
verify(mPreference).setChecked(false);
}
@Test
public void onDeveloperOptionsSwitchDisabled_shouldDisable() {
mController.onDeveloperOptionsSwitchDisabled();
verify(mPreference).setChecked(false);
verify(mPreference).setEnabled(false);
assertThat(isSettingEnabled()).isFalse();
}
private boolean isSettingEnabled() {
return Settings.Secure.getInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES,
OFF /* default off */) == ON;
}
}

View File

@@ -1,199 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.gestures;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.settings.gestures.SystemNavigationEdgeToEdgePreferenceController.PREF_KEY_EDGE_TO_EDGE;
import static com.android.settings.gestures.SystemNavigationLegacyPreferenceController.PREF_KEY_LEGACY;
import static com.android.settings.gestures.SystemNavigationSwipeUpPreferenceController.PREF_KEY_SWIPE_UP;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.om.IOverlayManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import androidx.preference.PreferenceScreen;
import com.android.internal.R;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.widget.RadioButtonPreference;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowPackageManager;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = SettingsShadowResources.class)
public class SystemNavigationEdgeToEdgePreferenceControllerTest {
private Context mContext;
private ShadowPackageManager mPackageManager;
@Mock
private IOverlayManager mOverlayManager;
private SystemNavigationEdgeToEdgePreferenceController mController;
private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_setting_available,
true);
mContext = RuntimeEnvironment.application;
mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
mController = new SystemNavigationEdgeToEdgePreferenceController(mContext, mOverlayManager,
PREF_KEY_EDGE_TO_EDGE);
}
@After
public void tearDown() {
SettingsShadowResources.reset();
}
@Test
public void testIsGestureAvailable_matchingServiceExists_shouldReturnTrue() {
final ComponentName recentsComponentName = ComponentName.unflattenFromString(
mContext.getString(com.android.internal.R.string.config_recentsComponentName));
final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
.setPackage(recentsComponentName.getPackageName());
final ResolveInfo info = new ResolveInfo();
info.serviceInfo = new ServiceInfo();
info.resolvePackageName = recentsComponentName.getPackageName();
info.serviceInfo.packageName = info.resolvePackageName;
info.serviceInfo.name = recentsComponentName.getClassName();
info.serviceInfo.applicationInfo = new ApplicationInfo();
info.serviceInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
mPackageManager.addResolveInfoForIntent(quickStepIntent, info);
assertThat(SystemNavigationEdgeToEdgePreferenceController.isGestureAvailable(mContext))
.isTrue();
}
@Test
public void testIsGestureAvailable_overlayDisabled_matchingServiceExists_shouldReturnFalse() {
SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_setting_available,
false);
final ComponentName recentsComponentName = ComponentName.unflattenFromString(
mContext.getString(com.android.internal.R.string.config_recentsComponentName));
final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
.setPackage(recentsComponentName.getPackageName());
mPackageManager.addResolveInfoForIntent(quickStepIntent, new ResolveInfo());
assertThat(SystemNavigationEdgeToEdgePreferenceController.isGestureAvailable(mContext))
.isFalse();
}
@Test
public void testIsGestureAvailable_noMatchingServiceExists_shouldReturnFalse() {
assertThat(SystemNavigationEdgeToEdgePreferenceController.isGestureAvailable(mContext))
.isFalse();
}
@Test
public void testIsGestureAvailable_noOverlayPackage_shouldReturnFalse() {
assertThat(SystemNavigationEdgeToEdgePreferenceController.isGestureAvailable(mContext,
"com.package.fake")).isFalse();
}
@Test
public void testIsChecked_defaultIsEdgeToEdge_shouldReturnTrue() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_GESTURAL);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void testIsChecked_defaultIsLegacy_shouldReturnFalse() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_3BUTTON);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void testIsChecked_defaultIsSwipeUp_shouldReturnFalse() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_2BUTTON);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void testIsChecked_radioButtonClicked_shouldReturnTrue() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_GESTURAL);
// Set the setting to be enabled.
mController.onRadioButtonClicked(null);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void testOnRadioButtonClicked_setsCorrectRadioButtonChecked() {
RadioButtonPreference radioLegacy = mock(RadioButtonPreference.class);
RadioButtonPreference radioSwipeUp = mock(RadioButtonPreference.class);
RadioButtonPreference radioEdgeToEdge = mock(RadioButtonPreference.class);
PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(PREF_KEY_LEGACY)).thenReturn(radioLegacy);
when(screen.findPreference(PREF_KEY_SWIPE_UP)).thenReturn(radioSwipeUp);
when(screen.findPreference(PREF_KEY_EDGE_TO_EDGE)).thenReturn(radioEdgeToEdge);
mController.displayPreference(screen);
mController.onRadioButtonClicked(radioEdgeToEdge);
verify(radioLegacy, times(1)).setChecked(false);
verify(radioSwipeUp, times(1)).setChecked(false);
verify(radioEdgeToEdge, times(1)).setChecked(true);
}
@Test
public void isSliceable_returnsFalse() {
assertThat(mController.isSliceable()).isFalse();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final SystemNavigationEdgeToEdgePreferenceController controller =
new SystemNavigationEdgeToEdgePreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.settings.gestures;
import static android.os.UserHandle.USER_CURRENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
import static com.android.settings.gestures.SystemNavigationGestureSettings.KEY_SYSTEM_NAV_2BUTTONS;
import static com.android.settings.gestures.SystemNavigationGestureSettings.KEY_SYSTEM_NAV_3BUTTONS;
import static com.android.settings.gestures.SystemNavigationGestureSettings.KEY_SYSTEM_NAV_GESTURAL;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.om.IOverlayManager;
import android.os.ServiceManager;
import android.provider.SearchIndexableResource;
import android.text.TextUtils;
import com.android.internal.R;
import com.android.settings.testutils.shadow.SettingsShadowResources;
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 java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = SettingsShadowResources.class)
public class SystemNavigationGestureSettingsTest {
private Context mContext;
private IOverlayManager mOverlayManager;
private SystemNavigationGestureSettings mSettings;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mOverlayManager = mock(IOverlayManager.class);
mSettings = new SystemNavigationGestureSettings();
}
@Test
public void testSearchIndexProvider_shouldIndexResource() {
final List<SearchIndexableResource> indexRes =
SystemNavigationGestureSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
RuntimeEnvironment.application, true /* enabled */);
assertThat(indexRes).isNotNull();
assertThat(indexRes.get(0).xmlResId).isEqualTo(mSettings.getPreferenceScreenResId());
}
@Test
public void testGetCurrentSystemNavigationMode() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_GESTURAL);
assertThat(TextUtils.equals(mSettings.getCurrentSystemNavigationMode(mContext),
KEY_SYSTEM_NAV_GESTURAL)).isTrue();
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_3BUTTON);
assertThat(TextUtils.equals(mSettings.getCurrentSystemNavigationMode(mContext),
KEY_SYSTEM_NAV_3BUTTONS)).isTrue();
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_2BUTTON);
assertThat(TextUtils.equals(mSettings.getCurrentSystemNavigationMode(mContext),
KEY_SYSTEM_NAV_2BUTTONS)).isTrue();
}
@Test
public void testSetCurrentSystemNavigationMode() throws Exception {
mSettings.setCurrentSystemNavigationMode(mOverlayManager, KEY_SYSTEM_NAV_GESTURAL);
verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
NAV_BAR_MODE_GESTURAL_OVERLAY, USER_CURRENT);
mSettings.setCurrentSystemNavigationMode(mOverlayManager, KEY_SYSTEM_NAV_2BUTTONS);
verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
NAV_BAR_MODE_2BUTTON_OVERLAY, USER_CURRENT);
mSettings.setCurrentSystemNavigationMode(mOverlayManager, KEY_SYSTEM_NAV_3BUTTONS);
verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
}
}

View File

@@ -1,201 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.gestures;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.settings.gestures.SystemNavigationEdgeToEdgePreferenceController.PREF_KEY_EDGE_TO_EDGE;
import static com.android.settings.gestures.SystemNavigationLegacyPreferenceController.PREF_KEY_LEGACY;
import static com.android.settings.gestures.SystemNavigationSwipeUpPreferenceController.PREF_KEY_SWIPE_UP;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.om.IOverlayManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import androidx.preference.PreferenceScreen;
import com.android.internal.R;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.widget.RadioButtonPreference;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowPackageManager;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = SettingsShadowResources.class)
public class SystemNavigationLegacyPreferenceControllerTest {
private Context mContext;
private ShadowPackageManager mPackageManager;
@Mock
private IOverlayManager mOverlayManager;
private SystemNavigationLegacyPreferenceController mController;
private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_setting_available,
true);
mContext = RuntimeEnvironment.application;
mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
mController = new SystemNavigationLegacyPreferenceController(mContext, mOverlayManager,
PREF_KEY_LEGACY);
}
@After
public void tearDown() {
SettingsShadowResources.reset();
}
@Test
public void testIsGestureAvailable_matchingServiceExists_shouldReturnTrue() {
final ComponentName recentsComponentName = ComponentName.unflattenFromString(
mContext.getString(com.android.internal.R.string.config_recentsComponentName));
final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
.setPackage(recentsComponentName.getPackageName());
final ResolveInfo info = new ResolveInfo();
info.serviceInfo = new ServiceInfo();
info.resolvePackageName = recentsComponentName.getPackageName();
info.serviceInfo.packageName = info.resolvePackageName;
info.serviceInfo.name = recentsComponentName.getClassName();
info.serviceInfo.applicationInfo = new ApplicationInfo();
info.serviceInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
mPackageManager.addResolveInfoForIntent(quickStepIntent, info);
assertThat(SystemNavigationLegacyPreferenceController.isGestureAvailable(mContext))
.isTrue();
}
@Test
public void testIsGestureAvailable_overlayDisabled_matchingServiceExists_shouldReturnFalse() {
SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_setting_available,
false);
final ComponentName recentsComponentName = ComponentName.unflattenFromString(
mContext.getString(com.android.internal.R.string.config_recentsComponentName));
final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
.setPackage(recentsComponentName.getPackageName());
mPackageManager.addResolveInfoForIntent(quickStepIntent, new ResolveInfo());
assertThat(
SystemNavigationLegacyPreferenceController.isGestureAvailable(mContext)).isFalse();
}
@Test
public void testIsGestureAvailable_noMatchingServiceExists_shouldReturnFalse() {
assertThat(
SystemNavigationLegacyPreferenceController.isGestureAvailable(mContext)).isFalse();
}
@Test
public void testIsGestureAvailable_noOverlayPackage_shouldReturnFalse() {
assertThat(SystemNavigationLegacyPreferenceController.isGestureAvailable(mContext,
"com.package.fake")).isFalse();
}
@Test
public void testIsChecked_defaultIsLegacy_shouldReturnTrue() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_3BUTTON);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void testIsChecked_defaultIsSwipeUp_shouldReturnFalse() {
// Turn on the Swipe Up mode (2-buttons)
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_2BUTTON);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void testIsChecked_defaultIsEdgeToEdge_shouldReturnFalse() {
// Turn on the Edge to Edge
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_GESTURAL);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void testIsChecked_radioButtonClicked_shouldReturnTrue() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_3BUTTON);
// Set the setting to be enabled.
mController.onRadioButtonClicked(null);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void testOnRadioButtonClicked_setsCorrectRadioButtonChecked() {
RadioButtonPreference radioLegacy = mock(RadioButtonPreference.class);
RadioButtonPreference radioSwipeUp = mock(RadioButtonPreference.class);
RadioButtonPreference radioEdgeToEdge = mock(RadioButtonPreference.class);
PreferenceScreen screen = mock(PreferenceScreen.class);
when(screen.findPreference(PREF_KEY_LEGACY)).thenReturn(radioLegacy);
when(screen.findPreference(PREF_KEY_SWIPE_UP)).thenReturn(radioSwipeUp);
when(screen.findPreference(PREF_KEY_EDGE_TO_EDGE)).thenReturn(radioEdgeToEdge);
mController.displayPreference(screen);
mController.onRadioButtonClicked(radioLegacy);
verify(radioLegacy, times(1)).setChecked(true);
verify(radioSwipeUp, times(1)).setChecked(false);
verify(radioEdgeToEdge, times(1)).setChecked(false);
}
@Test
public void isSliceable_returnsFalse() {
assertThat(mController.isSliceable()).isFalse();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final SystemNavigationLegacyPreferenceController controller =
new SystemNavigationLegacyPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
}

View File

@@ -11,7 +11,7 @@
* 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.
* limitations under the License
*/
package com.android.settings.gestures;
@@ -20,36 +20,25 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.settings.gestures.SystemNavigationEdgeToEdgePreferenceController.PREF_KEY_EDGE_TO_EDGE;
import static com.android.settings.gestures.SystemNavigationLegacyPreferenceController.PREF_KEY_LEGACY;
import static com.android.settings.gestures.SystemNavigationSwipeUpPreferenceController.PREF_KEY_SWIPE_UP;
import static com.android.settings.gestures.SystemNavigationPreferenceController.PREF_KEY_SYSTEM_NAVIGATION;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.om.IOverlayManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import androidx.preference.PreferenceScreen;
import android.text.TextUtils;
import com.android.internal.R;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.widget.RadioButtonPreference;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -59,15 +48,12 @@ import org.robolectric.shadows.ShadowPackageManager;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = SettingsShadowResources.class)
public class SystemNavigationSwipeUpPreferenceControllerTest {
public class SystemNavigationPreferenceControllerTest {
private Context mContext;
private ShadowPackageManager mPackageManager;
@Mock
private IOverlayManager mOverlayManager;
private SystemNavigationSwipeUpPreferenceController mController;
private SystemNavigationPreferenceController mController;
private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
@@ -81,8 +67,8 @@ public class SystemNavigationSwipeUpPreferenceControllerTest {
mContext = RuntimeEnvironment.application;
mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
mController = new SystemNavigationSwipeUpPreferenceController(mContext, mOverlayManager,
PREF_KEY_SWIPE_UP);
mController = new SystemNavigationPreferenceController(mContext,
PREF_KEY_SYSTEM_NAVIGATION);
}
@After
@@ -105,8 +91,7 @@ public class SystemNavigationSwipeUpPreferenceControllerTest {
info.serviceInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
mPackageManager.addResolveInfoForIntent(quickStepIntent, info);
assertThat(SystemNavigationSwipeUpPreferenceController.isGestureAvailable(mContext))
.isTrue();
assertThat(SystemNavigationPreferenceController.isGestureAvailable(mContext)).isTrue();
}
@Test
@@ -120,80 +105,65 @@ public class SystemNavigationSwipeUpPreferenceControllerTest {
.setPackage(recentsComponentName.getPackageName());
mPackageManager.addResolveInfoForIntent(quickStepIntent, new ResolveInfo());
assertThat(SystemNavigationSwipeUpPreferenceController.isGestureAvailable(mContext))
.isFalse();
assertThat(SystemNavigationPreferenceController.isGestureAvailable(mContext)).isFalse();
}
@Test
public void testIsGestureAvailable_noMatchingServiceExists_shouldReturnFalse() {
assertThat(SystemNavigationSwipeUpPreferenceController.isGestureAvailable(mContext))
.isFalse();
assertThat(SystemNavigationPreferenceController.isGestureAvailable(mContext)).isFalse();
}
@Test
public void testIsGestureAvailable_noOverlayPackage_shouldReturnFalse() {
assertThat(SystemNavigationSwipeUpPreferenceController.isGestureAvailable(mContext,
public void testIsOverlayPackageAvailable_noOverlayPackage_shouldReturnFalse() {
assertThat(SystemNavigationPreferenceController.isOverlayPackageAvailable(mContext,
"com.package.fake")).isFalse();
}
@Test
public void testIsChecked_defaultIsSwipeUp_shouldReturnTrue() {
public void testIsSwipeUpEnabled() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_2BUTTON);
assertThat(mController.isChecked()).isTrue();
}
assertThat(SystemNavigationPreferenceController.isSwipeUpEnabled(mContext)).isTrue();
@Test
public void testIsChecked_defaultIsLegacy_shouldReturnFalse() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_3BUTTON);
assertThat(mController.isChecked()).isFalse();
}
assertThat(SystemNavigationPreferenceController.isSwipeUpEnabled(mContext)).isFalse();
@Test
public void testIsChecked_defaultIsEdgeToEdge_shouldReturnFalse() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_GESTURAL);
assertThat(mController.isChecked()).isFalse();
assertThat(SystemNavigationPreferenceController.isSwipeUpEnabled(mContext)).isFalse();
}
@Test
public void testIsChecked_radioButtonClicked_shouldReturnTrue() {
public void testIsEdgeToEdgeEnabled() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_GESTURAL);
assertThat(SystemNavigationPreferenceController.isEdgeToEdgeEnabled(mContext)).isTrue();
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_3BUTTON);
assertThat(SystemNavigationPreferenceController.isEdgeToEdgeEnabled(mContext)).isFalse();
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_2BUTTON);
// Set the setting to be enabled.
mController.onRadioButtonClicked(null);
assertThat(mController.isChecked()).isTrue();
assertThat(SystemNavigationPreferenceController.isEdgeToEdgeEnabled(mContext)).isFalse();
}
@Test
public void testOnRadioButtonClicked_setsCorrectRadioButtonChecked() {
RadioButtonPreference radioLegacy = mock(RadioButtonPreference.class);
RadioButtonPreference radioSwipeUp = mock(RadioButtonPreference.class);
RadioButtonPreference radioEdgeToEdge = mock(RadioButtonPreference.class);
PreferenceScreen screen = mock(PreferenceScreen.class);
public void testGetSummary() {
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_GESTURAL);
assertThat(TextUtils.equals(mController.getSummary(), mContext.getText(
com.android.settings.R.string.edge_to_edge_navigation_title))).isTrue();
when(screen.findPreference(PREF_KEY_LEGACY)).thenReturn(radioLegacy);
when(screen.findPreference(PREF_KEY_SWIPE_UP)).thenReturn(radioSwipeUp);
when(screen.findPreference(PREF_KEY_EDGE_TO_EDGE)).thenReturn(radioEdgeToEdge);
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_3BUTTON);
assertThat(TextUtils.equals(mController.getSummary(),
mContext.getText(com.android.settings.R.string.legacy_navigation_title))).isTrue();
mController.displayPreference(screen);
mController.onRadioButtonClicked(radioSwipeUp);
verify(radioLegacy, times(1)).setChecked(false);
verify(radioSwipeUp, times(1)).setChecked(true);
verify(radioEdgeToEdge, times(1)).setChecked(false);
SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_2BUTTON);
assertThat(TextUtils.equals(mController.getSummary(), mContext.getText(
com.android.settings.R.string.swipe_up_to_switch_apps_title))).isTrue();
}
@Test
public void isSliceable_returnsFalse() {
assertThat(mController.isSliceable()).isFalse();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final SystemNavigationSwipeUpPreferenceController controller =
new SystemNavigationSwipeUpPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
}
}

View File

@@ -17,13 +17,13 @@
package com.android.settings.homepage.contextualcards.deviceinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import android.content.Context;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.SliceItem;
@@ -31,19 +31,18 @@ import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
import com.android.settings.testutils.SliceTester;
import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import java.util.List;
import org.robolectric.shadows.ShadowTelephonyManager;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowDataUsageUtils.class)
@@ -62,6 +61,11 @@ public class DataUsageSliceTest {
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
mDataUsageSlice = spy(new DataUsageSlice(mContext));
final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
final ShadowTelephonyManager shadowTelephonyManager = Shadows.shadowOf(telephonyManager);
shadowTelephonyManager.setTelephonyManagerForSubscriptionId(
SubscriptionManager.INVALID_SUBSCRIPTION_ID, telephonyManager);
}
@Test

View File

@@ -26,6 +26,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.telephony.TelephonyManager;
import androidx.slice.Slice;
import androidx.slice.SliceMetadata;
@@ -47,12 +48,15 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowTelephonyManager;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothUtils.class})
@Config(shadows = {ShadowBluetoothUtils.class,
ShadowTelephonyManager.class})
public class MediaOutputIndicatorSliceTest {
private static final String TEST_A2DP_DEVICE_NAME = "Test_A2DP_BT_Device_NAME";
@@ -76,11 +80,14 @@ public class MediaOutputIndicatorSliceTest {
private Context mContext;
private List<BluetoothDevice> mDevicesList;
private MediaOutputIndicatorSlice mMediaOutputIndicatorSlice;
private ShadowTelephonyManager mShadowTelephonyManager;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mShadowTelephonyManager = Shadow.extract(mContext.getSystemService(
Context.TELEPHONY_SERVICE));
// Set-up specs for SliceMetadata.
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
@@ -151,4 +158,31 @@ public class MediaOutputIndicatorSliceTest {
assertThat(metadata.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title));
assertThat(metadata.getSubtitle()).isEqualTo(TEST_HAP_DEVICE_NAME);
}
@Test
public void getSlice_callStateIdle_available() {
mDevicesList.add(mA2dpDevice);
when(mA2dpProfile.getConnectedDevices()).thenReturn(mDevicesList);
mShadowTelephonyManager.setCallState(TelephonyManager.CALL_STATE_IDLE);
assertThat(mMediaOutputIndicatorSlice.getSlice()).isNotNull();
}
@Test
public void getSlice_callStateRinging_returnNull() {
mDevicesList.add(mA2dpDevice);
when(mA2dpProfile.getConnectedDevices()).thenReturn(mDevicesList);
mShadowTelephonyManager.setCallState(TelephonyManager.CALL_STATE_RINGING);
assertThat(mMediaOutputIndicatorSlice.getSlice()).isNull();
}
@Test
public void getSlice_callStateOffHook_returnNull() {
mDevicesList.add(mA2dpDevice);
when(mA2dpProfile.getConnectedDevices()).thenReturn(mDevicesList);
mShadowTelephonyManager.setCallState(TelephonyManager.CALL_STATE_OFFHOOK);
assertThat(mMediaOutputIndicatorSlice.getSlice()).isNull();
}
}

View File

@@ -123,6 +123,18 @@ public class ApnPreferenceControllerTest {
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_hideCarrierNetworkSettings_returnUnavailable() {
doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mTelephonyManager).getPhoneType();
final PersistableBundle bundle = new PersistableBundle();
bundle.putBoolean(CarrierConfigManager.KEY_APN_EXPAND_BOOL, true);
bundle.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, true);
doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void handPreferenceTreeClick_fireIntent() {
ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);

View File

@@ -17,7 +17,6 @@
package com.android.settings.network.telephony;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -30,12 +29,9 @@ import android.net.TrafficStats;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.preference.SwitchPreference;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.net.DataUsageController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -44,14 +40,14 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowTelephonyManager;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class DataUsagePreferenceControllerTest {
private static final int SUB_ID = 2;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private NetworkStatsManager mNetworkStatsManager;
private DataUsagePreferenceController mController;
@@ -63,8 +59,13 @@ public class DataUsagePreferenceControllerTest {
MockitoAnnotations.initMocks(this);
mContext = spy(Robolectric.setupActivity(Activity.class));
doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
final ShadowTelephonyManager shadowTelephonyManager = Shadows.shadowOf(telephonyManager);
shadowTelephonyManager.setTelephonyManagerForSubscriptionId(SUB_ID, telephonyManager);
shadowTelephonyManager.setTelephonyManagerForSubscriptionId(
SubscriptionManager.INVALID_SUBSCRIPTION_ID, telephonyManager);
doReturn(mNetworkStatsManager).when(mContext).getSystemService(NetworkStatsManager.class);
mPreference = new SwitchPreference(mContext);

View File

@@ -198,4 +198,25 @@ public class MobileNetworkUtilsTest {
assertThat(MobileNetworkUtils.getSearchableSubscriptionId(mContext))
.isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
}
@Test
public void shouldDisplayNetworkSelectOptions_HideCarrierNetwork_returnFalse() {
mCarrierConfig.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
true);
assertThat(MobileNetworkUtils.shouldDisplayNetworkSelectOptions(mContext, SUB_ID_1))
.isFalse();
}
@Test
public void shouldDisplayNetworkSelectOptions_allCheckPass_returnTrue() {
mCarrierConfig.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
false);
mCarrierConfig.putBoolean(CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL, true);
mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL, false);
when(mTelephonyManager.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
assertThat(MobileNetworkUtils.shouldDisplayNetworkSelectOptions(mContext, SUB_ID_1))
.isTrue();
}
}

View File

@@ -1,136 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import static com.android.settings.notification.BadgingNotificationPreferenceController.OFF;
import static com.android.settings.notification.BadgingNotificationPreferenceController.ON;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.TwoStatePreference;
@RunWith(RobolectricTestRunner.class)
public class BubbleNotificationPreferenceControllerTest {
private Context mContext;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
private BubbleNotificationPreferenceController mController;
private Preference mPreference;
private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles";
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new BubbleNotificationPreferenceController(mContext,
KEY_NOTIFICATION_BUBBLES);
mPreference = new Preference(RuntimeEnvironment.application);
mPreference.setKey(mController.getPreferenceKey());
when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
}
@Test
public void display_shouldDisplay() {
assertThat(mPreference.isVisible()).isTrue();
}
@Test
public void updateState_preferenceSetCheckedWhenSettingIsOn() {
final TwoStatePreference preference = mock(TwoStatePreference.class);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON);
mController.updateState(preference);
verify(preference).setChecked(true);
}
@Test
public void updateState_preferenceSetUncheckedWhenSettingIsOff() {
final TwoStatePreference preference = mock(TwoStatePreference.class);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, ON)).isEqualTo(OFF);
mController.updateState(preference);
verify(preference).setChecked(false);
}
@Test
public void isChecked_settingIsOff_shouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_settingIsOn_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setChecked_setFalse_disablesSetting() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON);
mController.setChecked(false);
int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, -1);
assertThat(updatedValue).isEqualTo(OFF);
}
@Test
public void setChecked_setTrue_enablesSetting() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF);
mController.setChecked(true);
int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, -1);
assertThat(updatedValue).isEqualTo(ON);
}
@Test
public void isSliceable_returnsFalse() {
assertThat(mController.isSliceable()).isFalse();
}
}

View File

@@ -22,6 +22,9 @@ import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import static com.android.settings.notification.BubblePreferenceController.SYSTEM_WIDE_OFF;
import static com.android.settings.notification.BubblePreferenceController.SYSTEM_WIDE_ON;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -96,6 +99,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testIsAvailable_notIfAppBlocked() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, mock(NotificationChannel.class), null, null);
@@ -104,6 +108,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testIsAvailable_notIfChannelBlocked() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
@@ -113,6 +118,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testIsAvailable_channel_notIfAppOff() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.allowBubbles = false;
NotificationChannel channel = mock(NotificationChannel.class);
@@ -123,12 +129,13 @@ public class BubblePreferenceControllerTest {
}
@Test
public void testIsAvailable_ifOffGlobally_app() {
public void testIsNotAvailable_ifOffGlobally_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0);
Settings.Secure.putInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF);
assertTrue(mController.isAvailable());
assertFalse(mController.isAvailable());
}
@Test
@@ -137,7 +144,8 @@ public class BubblePreferenceControllerTest {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0);
Settings.Secure.putInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF);
assertFalse(mController.isAvailable());
}
@@ -146,7 +154,7 @@ public class BubblePreferenceControllerTest {
public void testIsAvailable_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
assertTrue(mController.isAvailable());
}
@@ -159,7 +167,7 @@ public class BubblePreferenceControllerTest {
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
mController.onResume(appRow, channel, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
assertTrue(mController.isAvailable());
}
@@ -171,7 +179,7 @@ public class BubblePreferenceControllerTest {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
assertTrue(mController.isAvailable());
}
@@ -183,7 +191,7 @@ public class BubblePreferenceControllerTest {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
assertFalse(mController.isAvailable());
}
@@ -203,6 +211,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testUpdateState_channelNotBlockable() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true);
@@ -216,6 +225,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testUpdateState_channel() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.canBubble()).thenReturn(true);
@@ -235,6 +245,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testUpdateState_app() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.label = "App!";
appRow.allowBubbles = true;
@@ -256,7 +267,8 @@ public class BubblePreferenceControllerTest {
@Test
public void testUpdateState_app_offGlobally() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0);
Settings.Secure.putInt(mContext.getContentResolver(),
NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.label = "App!";
appRow.allowBubbles = true;
@@ -269,6 +281,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testOnPreferenceChange_on_channel() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.allowBubbles = true;
NotificationChannel channel =
@@ -288,6 +301,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testOnPreferenceChange_off_channel() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.allowBubbles = true;
NotificationChannel channel =
@@ -307,6 +321,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testOnPreferenceChange_on_app() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.allowBubbles = false;
mController.onResume(appRow, null, null, null);
@@ -324,6 +339,7 @@ public class BubblePreferenceControllerTest {
@Test
public void testOnPreferenceChange_off_app() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.allowBubbles = true;
mController.onResume(appRow, null, null, null);
@@ -341,7 +357,8 @@ public class BubblePreferenceControllerTest {
@Test
public void testOnPreferenceChange_on_app_offGlobally() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES,
SYSTEM_WIDE_OFF);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.allowBubbles = false;
mController.onResume(appRow, null, null, null);

View File

@@ -1,70 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import static com.android.settings.notification.BadgingNotificationPreferenceController.OFF;
import static com.android.settings.notification.BadgingNotificationPreferenceController.ON;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import androidx.preference.Preference;
@RunWith(RobolectricTestRunner.class)
public class BubbleSummaryNotificationPreferenceControllerTest {
private Context mContext;
private BubbleSummaryNotificationPreferenceController mController;
private Preference mPreference;
private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles";
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new BubbleSummaryNotificationPreferenceController(mContext,
KEY_NOTIFICATION_BUBBLES);
mPreference = new Preference(RuntimeEnvironment.application);
}
@Test
public void display_shouldDisplay() {
assertThat(mPreference.isVisible()).isTrue();
}
@Test
public void getSummary() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF);
assertThat(mController.getSummary()).isEqualTo("Off");
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON);
assertThat(mController.getSummary()).isEqualTo("On");
}
}

View File

@@ -22,6 +22,9 @@ import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import static com.android.settings.notification.BubbleSummaryPreferenceController.SYSTEM_WIDE_OFF;
import static com.android.settings.notification.BubbleSummaryPreferenceController.SYSTEM_WIDE_ON;
import static junit.framework.TestCase.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -95,7 +98,8 @@ public class BubbleSummaryPreferenceControllerTest {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES,
SYSTEM_WIDE_OFF);
assertFalse(mController.isAvailable());
}
@@ -104,18 +108,19 @@ public class BubbleSummaryPreferenceControllerTest {
public void testIsAvailable_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
assertTrue(mController.isAvailable());
}
@Test
public void testIsAvailable_app_globalOff() {
public void testIsNotAvailable_app_globalOff() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES,
SYSTEM_WIDE_OFF);
assertTrue(mController.isAvailable());
assertFalse(mController.isAvailable());
}
@Test
@@ -126,7 +131,7 @@ public class BubbleSummaryPreferenceControllerTest {
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
mController.onResume(appRow, channel, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
assertTrue(mController.isAvailable());
}
@@ -144,16 +149,18 @@ public class BubbleSummaryPreferenceControllerTest {
@Test
public void testGetSummary() {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.allowBubbles = true;
mController.onResume(appRow, null, null, null);
assertEquals("On", mController.getSummary());
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES,
SYSTEM_WIDE_OFF);
assertEquals("Off", mController.getSummary());
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
appRow.allowBubbles = false;
mController.onResume(appRow, null, null, null);

View File

@@ -23,6 +23,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import android.net.wifi.WifiManager;
@@ -35,8 +36,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@@ -44,6 +45,7 @@ import org.robolectric.annotation.Config;
public class ConnectToWifiHandlerTest {
private static final String AP_SSID = "\"ap\"";
private Context mContext;
private ConnectToWifiHandler mHandler;
private WifiConfiguration mWifiConfig;
@Mock
@@ -53,7 +55,8 @@ public class ConnectToWifiHandlerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mHandler = Robolectric.setupActivity(ConnectToWifiHandler.class);
mContext = RuntimeEnvironment.application;
mHandler = new ConnectToWifiHandler();
mWifiConfig = new WifiConfiguration();
mWifiConfig.SSID = AP_SSID;
doReturn(mWifiConfig).when(mAccessPoint).getConfig();
@@ -64,7 +67,7 @@ public class ConnectToWifiHandlerTest {
when(mAccessPoint.isSaved()).thenReturn(false);
when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_NONE);
mHandler.connect(mAccessPoint);
mHandler.connect(mContext, mAccessPoint);
assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
}
@@ -74,7 +77,7 @@ public class ConnectToWifiHandlerTest {
when(mAccessPoint.isSaved()).thenReturn(false);
when(mAccessPoint.isOsuProvider()).thenReturn(true);
mHandler.connect(mAccessPoint);
mHandler.connect(mContext, mAccessPoint);
verify(mAccessPoint).startOsuProvisioning(any(WifiManager.ActionListener.class));
}
@@ -85,7 +88,7 @@ public class ConnectToWifiHandlerTest {
when(mAccessPoint.isSaved()).thenReturn(false);
when(mAccessPoint.isPasspoint()).thenReturn(true);
mHandler.connect(mAccessPoint);
mHandler.connect(mContext, mAccessPoint);
assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
}
@@ -98,7 +101,7 @@ public class ConnectToWifiHandlerTest {
status.setHasEverConnected(true);
mWifiConfig.setNetworkSelectionStatus(status);
mHandler.connect(mAccessPoint);
mHandler.connect(mContext, mAccessPoint);
assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
}
@@ -108,7 +111,7 @@ public class ConnectToWifiHandlerTest {
when(mAccessPoint.isSaved()).thenReturn(false);
when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_PSK);
mHandler.connect(mAccessPoint);
mHandler.connect(mContext, mAccessPoint);
assertThat(ShadowWifiManager.get().savedWifiConfig).isNull();
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.settings.wifi.slice;
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.Network;
import android.net.wifi.WifiManager;
import android.os.UserHandle;
import com.android.settings.testutils.shadow.ShadowWifiManager;
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;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
ShadowWifiManager.class,
WifiScanWorkerTest.ShadowWifiTracker.class,
})
public class ContextualWifiScanWorkerTest {
private Context mContext;
private WifiManager mWifiManager;
private ConnectivityManager mConnectivityManager;
private ContextualWifiScanWorker mWifiScanWorker;
private ConnectToWifiHandler mConnectToWifiHandler;
@Before
public void setUp() {
mContext = spy(RuntimeEnvironment.application);
mWifiManager = mContext.getSystemService(WifiManager.class);
mWifiManager.setWifiEnabled(true);
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
mWifiScanWorker = new ContextualWifiScanWorker(mContext, CONTEXTUAL_WIFI_SLICE_URI);
mConnectToWifiHandler = new ConnectToWifiHandler();
}
@After
public void tearDown() {
mWifiScanWorker.clearClickedWifi();
}
@Test
public void NetworkCallback_onCapabilitiesChanged_sliceIsUnpinned_shouldSendBroadcast() {
final Intent intent = WifiScanWorkerTest.getIntentWithAccessPoint("ap1");
WifiScanWorkerTest.setConnectionInfoSSID("ap1");
final Network network = mConnectivityManager.getActiveNetwork();
mWifiScanWorker.registerNetworkCallback(network);
final NetworkCallback callback = mWifiScanWorker.mNetworkCallback;
mWifiScanWorker.onSlicePinned();
mConnectToWifiHandler.onReceive(mContext, intent);
mWifiScanWorker.onSliceUnpinned();
callback.onCapabilitiesChanged(network,
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
}
@Test
public void NetworkCallback_onCapabilitiesChanged_newSession_shouldNotSendBroadcast() {
final Intent intent = WifiScanWorkerTest.getIntentWithAccessPoint("ap1");
WifiScanWorkerTest.setConnectionInfoSSID("ap1");
final Network network = mConnectivityManager.getActiveNetwork();
mWifiScanWorker.registerNetworkCallback(network);
mConnectToWifiHandler.onReceive(mContext, intent);
ContextualWifiScanWorker.newVisibleUiSession();
mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
}
}

View File

@@ -17,6 +17,7 @@
package com.android.settings.wifi.slice;
import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;
import static com.android.settings.wifi.WifiDialogActivity.KEY_ACCESS_POINT_STATE;
import static com.google.common.truth.Truth.assertThat;
@@ -42,9 +43,6 @@ import android.net.wifi.WifiSsid;
import android.os.Bundle;
import android.os.UserHandle;
import androidx.slice.SliceProvider;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.testutils.shadow.ShadowWifiManager;
import com.android.settingslib.wifi.AccessPoint;
import com.android.settingslib.wifi.WifiTracker;
@@ -57,7 +55,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@@ -85,14 +82,11 @@ public class WifiScanWorkerTest {
mResolver = mock(ContentResolver.class);
doReturn(mResolver).when(mContext).getContentResolver();
mWifiManager = mContext.getSystemService(WifiManager.class);
// Set-up specs for SliceMetadata.
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
mWifiManager.setWifiEnabled(true);
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI);
mConnectToWifiHandler = Robolectric.setupActivity(ConnectToWifiHandler.class);
mConnectToWifiHandler = new ConnectToWifiHandler();
}
@After
@@ -147,42 +141,36 @@ public class WifiScanWorkerTest {
verify(mResolver).notifyChange(WIFI_SLICE_URI, null);
}
private void setConnectionInfoSSID(String ssid) {
final WifiInfo wifiInfo = new WifiInfo();
wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(ssid));
ShadowWifiManager.get().setConnectionInfo(wifiInfo);
}
@Test
public void NetworkCallback_onCapabilitiesChanged_isClickedWifi_shouldStartActivity() {
final AccessPoint accessPoint = createAccessPoint("ap1");
public void NetworkCallback_onCapabilitiesChanged_isClickedWifi_shouldSendBroadcast() {
final Intent intent = getIntentWithAccessPoint("ap1");
setConnectionInfoSSID("ap1");
final Network network = mConnectivityManager.getActiveNetwork();
mWifiScanWorker.registerNetworkCallback(network);
mConnectToWifiHandler.connect(accessPoint);
mConnectToWifiHandler.onReceive(mContext, intent);
mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
verify(mContext).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
}
@Test
public void NetworkCallback_onCapabilitiesChanged_isNotClickedWifi_shouldNotStartActivity() {
final AccessPoint accessPoint = createAccessPoint("ap1");
public void NetworkCallback_onCapabilitiesChanged_isNotClickedWifi_shouldNotSendBroadcast() {
final Intent intent = getIntentWithAccessPoint("ap1");
setConnectionInfoSSID("ap2");
final Network network = mConnectivityManager.getActiveNetwork();
mWifiScanWorker.registerNetworkCallback(network);
mConnectToWifiHandler.connect(accessPoint);
mConnectToWifiHandler.onReceive(mContext, intent);
mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
}
@Test
public void NetworkCallback_onCapabilitiesChanged_neverClickWifi_shouldNotStartActivity() {
public void NetworkCallback_onCapabilitiesChanged_neverClickWifi_shouldNotSendBroadcast() {
setConnectionInfoSSID("ap1");
final Network network = mConnectivityManager.getActiveNetwork();
mWifiScanWorker.registerNetworkCallback(network);
@@ -190,24 +178,36 @@ public class WifiScanWorkerTest {
mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
}
@Test
public void NetworkCallback_onCapabilitiesChanged_sliceIsUnpinned_shouldNotStartActivity() {
final AccessPoint accessPoint = createAccessPoint("ap1");
public void NetworkCallback_onCapabilitiesChanged_sliceIsUnpinned_shouldNotSendBroadcast() {
final Intent intent = getIntentWithAccessPoint("ap1");
setConnectionInfoSSID("ap1");
final Network network = mConnectivityManager.getActiveNetwork();
mWifiScanWorker.registerNetworkCallback(network);
final NetworkCallback callback = mWifiScanWorker.mNetworkCallback;
mWifiScanWorker.onSlicePinned();
mConnectToWifiHandler.connect(accessPoint);
mConnectToWifiHandler.onReceive(mContext, intent);
mWifiScanWorker.onSliceUnpinned();
callback.onCapabilitiesChanged(network,
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
}
static Intent getIntentWithAccessPoint(String ssid) {
final Bundle savedState = new Bundle();
savedState.putString("key_ssid", ssid);
return new Intent().putExtra(KEY_ACCESS_POINT_STATE, savedState);
}
static void setConnectionInfoSSID(String ssid) {
final WifiInfo wifiInfo = new WifiInfo();
wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(ssid));
ShadowWifiManager.get().setConnectionInfo(wifiInfo);
}
private AccessPoint createAccessPoint(String ssid, DetailedState detailedState) {
@@ -223,10 +223,6 @@ public class WifiScanWorkerTest {
return createAccessPoint("ap", detailedState);
}
private AccessPoint createAccessPoint(String ssid) {
return createAccessPoint(ssid, DetailedState.DISCONNECTED);
}
@Implements(WifiTracker.class)
public static class ShadowWifiTracker {
@Implementation