Snap for 4969112 from 48bbd85bd1 to qt-release

Change-Id: Id82113c1dd4f301d214243c9f7e57074699bffff
This commit is contained in:
android-build-team Robot
2018-08-22 03:06:28 +00:00
118 changed files with 575 additions and 3217 deletions

View File

@@ -9392,13 +9392,13 @@
<string name="notification_log_details_ranking_none">Ranking object doesn\'t contain this key.</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which turns on emulation of a display cutout. -->
<string name="display_cutout_emulation">Simulate a display with a cutout</string>
<string name="display_cutout_emulation">Display cutout</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Search keywords for the setting which turns on emulation of a display cutout. -->
<string name="display_cutout_emulation_keywords">display cutout, notch</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Label for the option that turns off display cutout emulation. -->
<string name="display_cutout_emulation_none">None</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Label for the option that turns off display cutout emulation, (i.e. on devices whose screen actually has a cutout, selecting this option will show that cutout).-->
<string name="display_cutout_emulation_device_default">Device default</string>
<!-- [CHAR_LIMIT=60] Label for special access screen -->
<string name="special_access">Special app access</string>

View File

@@ -13,10 +13,12 @@
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:key="magnification_preference_screen_title"
android:title="@string/accessibility_screen_magnification_title">
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="magnification_preference_screen_title"
android:title="@string/accessibility_screen_magnification_title"
settings:searchable="false">
<Preference
android:fragment="com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment"
android:key="screen_magnification_gestures_preference_screen"

View File

@@ -38,7 +38,8 @@
<Preference
android:key="tts_settings_preference"
android:fragment="com.android.settings.tts.TextToSpeechSettings"
android:title="@string/tts_settings_title"/>
android:title="@string/tts_settings_title"
settings:searchable="false"/>
</PreferenceCategory>
<PreferenceCategory
@@ -48,12 +49,14 @@
<Preference
android:fragment="com.android.settings.accessibility.ToggleFontSizePreferenceFragment"
android:key="font_size_preference_screen"
android:title="@string/title_font_size" />
android:title="@string/title_font_size"
settings:searchable="false"/>
<com.android.settings.display.ScreenZoomPreference
android:key="accessibility_settings_screen_zoom"
android:fragment="com.android.settings.display.ScreenZoomSettings"
android:title="@string/screen_zoom_title" />
android:title="@string/screen_zoom_title"
settings:searchable="false"/>
<Preference
android:fragment="com.android.settings.accessibility.MagnificationPreferenceFragment"
@@ -77,7 +80,8 @@
<Preference
android:fragment="com.android.settings.accessibility.ToggleAutoclickPreferenceFragment"
android:key="autoclick_preference"
android:title="@string/accessibility_autoclick_preference_title"/>
android:title="@string/accessibility_autoclick_preference_title"
settings:searchable="false"/>
<SwitchPreference
android:key="toggle_power_button_ends_call_preference"
@@ -136,7 +140,8 @@
android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
android:key="daltonizer_preference"
android:title="@string/accessibility_display_daltonizer_preference_title"
android:icon="@drawable/ic_daltonizer"/>
android:icon="@drawable/ic_daltonizer"
settings:searchable="false"/>
<SwitchPreference
android:key="toggle_inversion_preference"

View File

@@ -23,7 +23,8 @@
<com.android.settings.RestrictedListPreference
android:key="lock_screen_notifications"
android:title="@string/lock_screen_notifications_title"
android:summary="@string/summary_placeholder"/>
android:summary="@string/summary_placeholder"
settings:searchable="false"/>
<!-- Notification badging -->
<SwitchPreference
@@ -35,7 +36,7 @@
<SwitchPreference
android:key="notification_pulse"
android:title="@string/notification_pulse_title"
settings:controller="com.android.settings.notification.PulseNotificationPreferenceController" />
settings:controller="com.android.settings.notification.PulseNotificationPreferenceController"/>
<!-- Default notification ringtone -->
<com.android.settings.DefaultRingtonePreference
@@ -43,13 +44,13 @@
android:title="@string/notification_ringtone_title"
android:dialogTitle="@string/notification_ringtone_title"
android:summary="@string/summary_placeholder"
android:ringtoneType="notification" />
android:ringtoneType="notification"/>
<Preference
android:key="gesture_swipe_down_fingerprint_notifications"
android:title="@string/fingerprint_swipe_for_notifications_title"
android:fragment="com.android.settings.gestures.SwipeToNotificationSettings"
settings:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController" />
settings:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController"/>
<com.android.settingslib.RestrictedPreference
android:key="zen_mode_notifications"
@@ -57,7 +58,7 @@
settings:useAdminDisabledSummary="true"
android:fragment="com.android.settings.notification.ZenModeSettings"
settings:controller="com.android.settings.notification.ZenModePreferenceController"
settings:allowDividerAbove="false" />
settings:allowDividerAbove="false"/>
<!-- Empty category to draw divider -->
<PreferenceCategory
@@ -79,7 +80,7 @@
android:order="22">
<extra
android:name="classname"
android:value="com.android.settings.Settings$NotificationAppListActivity" />
android:value="com.android.settings.Settings$NotificationAppListActivity"/>
</Preference>
</PreferenceCategory>
@@ -88,13 +89,15 @@
<PreferenceCategory
android:key="lock_screen_notifications_profile_header"
android:title="@string/profile_section_header"
android:order="23">
android:order="23"
settings:searchable="false">
<com.android.settings.RestrictedListPreference
android:key="lock_screen_notifications_profile"
android:title="@string/locked_work_profile_notification_title"
android:summary="@string/summary_placeholder"
android:order="24"/>
android:order="24"
settings:searchable="false"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -25,7 +25,8 @@
android:key="bluetooth_settings"
android:title="@string/bluetooth_settings_title"
android:icon="@drawable/ic_settings_bluetooth"
android:order="-9"/>
android:order="-9"
settings:searchable="false"/>
<SwitchPreference
android:key="toggle_nfc"
@@ -57,7 +58,8 @@
android:summary="@string/summary_placeholder"
android:icon="@drawable/ic_settings_print"
android:fragment="com.android.settings.print.PrintSettingsFragment"
android:order="-3"/>
android:order="-3"
settings:searchable="false"/>
<Preference
android:key="bt_received_files"

View File

@@ -37,20 +37,22 @@
android:fragment="com.android.settings.display.NightDisplaySettings"
android:widgetLayout="@null"
settings:widgetLayout="@null"
settings:keywords="@string/keywords_display_night_display" />
settings:searchable="false" />
<Preference
android:key="auto_brightness_entry"
android:title="@string/auto_brightness_title"
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.display.AutoBrightnessSettings"
settings:searchable="false"
settings:controller="com.android.settings.display.AutoBrightnessPreferenceController" />
<com.android.settingslib.RestrictedPreference
android:key="wallpaper"
android:title="@string/wallpaper_settings_title"
settings:keywords="@string/keywords_display_wallpaper"
settings:useAdminDisabledSummary="true">
settings:useAdminDisabledSummary="true"
settings:searchable="false">
<intent
android:targetPackage="@string/config_wallpaper_picker_package"
android:targetClass="@string/config_wallpaper_picker_class" />
@@ -88,7 +90,7 @@
android:key="display_settings_screen_zoom"
android:title="@string/screen_zoom_title"
android:fragment="com.android.settings.display.ScreenZoomSettings"
settings:keywords="@string/screen_zoom_keywords" />
settings:searchable="false"/>
<SwitchPreference
android:key="show_operator_name"
@@ -99,7 +101,7 @@
android:key="screensaver"
android:title="@string/screensaver_settings_title"
android:fragment="com.android.settings.dream.DreamSettings"
settings:controller="com.android.settings.dream.DreamEntryPreferenceController" />
settings:searchable="false" />
<com.android.settingslib.RestrictedPreference
android:key="lockscreen_from_display_settings"

View File

@@ -39,7 +39,8 @@
android:key="physical_keyboard_pref"
android:title="@string/physical_keyboard_title"
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.inputmethod.PhysicalKeyboardFragment" />
android:fragment="com.android.settings.inputmethod.PhysicalKeyboardFragment"
settings:searchable="false"/>
</PreferenceCategory>
<PreferenceCategory
@@ -80,7 +81,8 @@
<Preference
android:key="tts_settings_summary"
android:title="@string/tts_settings_title"
android:fragment="com.android.settings.tts.TextToSpeechSettings" />
android:fragment="com.android.settings.tts.TextToSpeechSettings"
settings:searchable="false"/>
</PreferenceCategory>

View File

@@ -29,7 +29,8 @@
android:title="@string/location_recent_location_requests_see_all"
android:icon="@drawable/ic_chevron_right_24dp"
android:selectable="true"
android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"/>
android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
settings:searchable="false"/>
<PreferenceCategory
android:key="location_advanced_settings"

View File

@@ -61,7 +61,8 @@
android:order="5"
android:title="@string/legal_information"
android:fragment="com.android.settings.LegalSettings"
settings:allowDividerAbove="true"/>
settings:allowDividerAbove="true"
settings:searchable="false"/>
<!-- Regulatory labels -->
<Preference

View File

@@ -17,8 +17,10 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="security_settings_password_sub_screen"
android:title="@string/unlock_set_unlock_launch_picker_title">
android:title="@string/unlock_set_unlock_launch_picker_title"
settings:searchable="false">
<!-- available in pattern -->
<SwitchPreference

View File

@@ -83,12 +83,14 @@
<PreferenceCategory
android:key="security_setting_lock_screen_notif_work_header"
android:title="@string/profile_section_header"
android:order="1001">
android:order="1001"
settings:searchable="false">
<com.android.settings.RestrictedListPreference
android:key="security_setting_lock_screen_notif_work"
android:title="@string/locked_work_profile_notification_title"
android:summary="@string/summary_placeholder" />
android:summary="@string/summary_placeholder"
settings:searchable="false"/>
</PreferenceCategory>

View File

@@ -16,6 +16,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="tts_settings_screen"
android:title="@string/tts_settings_title">
@@ -24,7 +25,8 @@
<com.android.settings.widget.GearPreference
android:key="tts_engine_preference"
android:title="@string/tts_engine_preference_title"
android:fragment="com.android.settings.tts.TtsEnginePreferenceFragment"/>
android:fragment="com.android.settings.tts.TtsEnginePreferenceFragment"
settings:searchable="false"/>
<ListPreference
android:key="tts_default_lang"

View File

@@ -15,11 +15,13 @@
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="virtual_keyboard_category"
android:title="@string/virtual_keyboard_category">
<!-- Enabled input method list will be populated programmatically here. -->
<Preference
android:key="add_virtual_keyboard_screen"
android:title="@string/add_virtual_keyboard"
android:fragment="com.android.settings.inputmethod.AvailableVirtualKeyboardFragment" />
android:fragment="com.android.settings.inputmethod.AvailableVirtualKeyboardFragment"
settings:searchable="false"/>
</PreferenceScreen>

View File

@@ -20,31 +20,32 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="wifi_tether_settings_screen"
android:title="@string/wifi_hotspot_checkbox_text"
settings:searchable="false"
settings:initialExpandedChildrenCount="3">
<com.android.settings.widget.ValidatedEditTextPreference
android:key="wifi_tether_network_name"
android:title="@string/wifi_hotspot_name_title"
android:summary="@string/summary_placeholder" />
android:summary="@string/summary_placeholder"/>
<ListPreference
android:key="wifi_tether_security"
android:title="@string/wifi_security"
android:summary="@string/summary_placeholder"
android:entries="@array/wifi_tether_security"
android:entryValues="@array/wifi_tether_security_values" />
android:entryValues="@array/wifi_tether_security_values"/>
<com.android.settings.widget.ValidatedEditTextPreference
android:key="wifi_tether_network_password"
android:persistent="false"
android:title="@string/wifi_hotspot_password_title" />
android:title="@string/wifi_hotspot_password_title"/>
<SwitchPreference
android:key="wifi_tether_auto_turn_off"
android:title="@string/wifi_hotspot_auto_off_title"
android:summary="@string/wifi_hotspot_auto_off_summary" />
android:summary="@string/wifi_hotspot_auto_off_summary"/>
<ListPreference
android:key="wifi_tether_network_ap_band"
android:title="@string/wifi_hotspot_ap_band_title" />
android:title="@string/wifi_hotspot_ap_band_title"/>
</PreferenceScreen>

View File

@@ -46,11 +46,7 @@ import java.util.List;
public class DisplaySettings extends DashboardFragment {
private static final String TAG = "DisplaySettings";
public static final String KEY_DISPLAY_SIZE = "display_settings_screen_zoom";
private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
private static final String KEY_AUTO_BRIGHTNESS = "auto_brightness_entry";
private static final String KEY_NIGHT_DISPLAY = "night_display";
@Override
public int getMetricsCategory() {
@@ -108,16 +104,6 @@ public class DisplaySettings extends DashboardFragment {
return result;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
keys.add(KEY_DISPLAY_SIZE);
keys.add(WallpaperPreferenceController.KEY_WALLPAPER);
keys.add(KEY_NIGHT_DISPLAY);
keys.add(KEY_AUTO_BRIGHTNESS);
return keys;
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {

View File

@@ -118,8 +118,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
"magnification_preference_screen";
private static final String FONT_SIZE_PREFERENCE_SCREEN =
"font_size_preference_screen";
private static final String TTS_SETTINGS_PREFERENCE =
"tts_settings_preference";
private static final String AUTOCLICK_PREFERENCE_SCREEN =
"autoclick_preference";
private static final String VIBRATION_PREFERENCE_SCREEN =
@@ -887,8 +885,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
public static final String KEY_DISPLAY_SIZE = "accessibility_settings_screen_zoom";
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
@@ -898,21 +894,5 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
indexables.add(indexable);
return indexables;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
// Duplicates in Display
keys.add(FONT_SIZE_PREFERENCE_SCREEN);
keys.add(KEY_DISPLAY_SIZE);
// Duplicates in Language & Input
keys.add(TTS_SETTINGS_PREFERENCE);
// Duplicates in child page
keys.add(DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
keys.add(AUTOCLICK_PREFERENCE_SCREEN);
return keys;
}
};
}

View File

@@ -27,6 +27,9 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -39,9 +42,6 @@ import com.android.settingslib.search.SearchIndexable;
import java.util.Arrays;
import java.util.List;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@SearchIndexable
public final class MagnificationPreferenceFragment extends DashboardFragment {
@VisibleForTesting
@@ -172,12 +172,5 @@ public final class MagnificationPreferenceFragment extends DashboardFragment {
protected boolean isPageSearchEnabled(Context context) {
return isApplicable(context.getResources());
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
keys.add(PREFERENCE_TITLE_KEY);
return keys;
}
};
}

View File

@@ -26,13 +26,12 @@ import com.android.settings.core.BasePreferenceController;
public class BackupSettingsActivityPreferenceController extends BasePreferenceController {
private static final String TAG = "BackupSettingActivityPC";
private static final String KEY_BACKUP_SETTINGS = "backup_settings";
private final UserManager mUm;
private final BackupManager mBackupManager;
public BackupSettingsActivityPreferenceController(Context context) {
super(context, KEY_BACKUP_SETTINGS);
public BackupSettingsActivityPreferenceController(Context context, String key) {
super(context, key);
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
mBackupManager = new BackupManager(context);
}

View File

@@ -108,9 +108,6 @@ public class AdvancedConnectedDeviceDashboardFragment extends DashboardFragment
keys.add(AndroidBeamPreferenceController.KEY_ANDROID_BEAM_SETTINGS);
}
// Parent duplicate
keys.add(KEY_BLUETOOTH);
return keys;
}

View File

@@ -95,7 +95,7 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle
@Override
public int getAvailabilityStatus() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
? AVAILABLE
? AVAILABLE_UNSEARCHABLE
: UNSUPPORTED_ON_DEVICE;
}

View File

@@ -19,6 +19,8 @@ import android.app.Activity;
import android.content.Context;
import android.provider.SearchIndexableResource;
import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -32,8 +34,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import androidx.annotation.VisibleForTesting;
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class ConnectedDeviceDashboardFragment extends DashboardFragment {
@@ -139,14 +139,5 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
context) {
return buildPreferenceControllers(context, null /* lifecycle */);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
// Disable because they show dynamic data
keys.add(KEY_AVAILABLE_DEVICES);
keys.add(KEY_CONNECTED_DEVICES);
return keys;
}
};
}

View File

@@ -89,7 +89,7 @@ public class ConnectedDeviceGroupController extends BasePreferenceController
@Override
public int getAvailabilityStatus() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
? AVAILABLE
? AVAILABLE_UNSEARCHABLE
: UNSUPPORTED_ON_DEVICE;
}

View File

@@ -113,11 +113,6 @@ public class UsbDetailsFragment extends DashboardFragment {
return Lists.newArrayList(res);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
return super.getNonIndexableKeys(context);
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {

View File

@@ -25,5 +25,4 @@ public class FeatureFlags {
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
public static final String DYNAMIC_HOMEPAGE = "settings_dynamic_homepage";
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
public static final String CONDITION_MANAGER_V2 = "settings_condition_manager_v2";
}

View File

@@ -51,25 +51,19 @@ public class CategoryManager {
private final Map<String, DashboardCategory> mCategoryByKeyMap;
private List<DashboardCategory> mCategories;
private String mExtraAction;
public static CategoryManager get(Context context) {
return get(context, null);
}
public static CategoryManager get(Context context, String action) {
if (sInstance == null) {
sInstance = new CategoryManager(context, action);
sInstance = new CategoryManager(context);
}
return sInstance;
}
CategoryManager(Context context, String action) {
CategoryManager(Context context) {
mTileByComponentCache = new ArrayMap<>();
mCategoryByKeyMap = new ArrayMap<>();
mInterestingConfigChanges = new InterestingConfigChanges();
mInterestingConfigChanges.applyNewConfig(context.getResources());
mExtraAction = action;
}
public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey) {
@@ -117,7 +111,7 @@ public class CategoryManager {
mTileByComponentCache.clear();
}
mCategoryByKeyMap.clear();
mCategories = TileUtils.getCategories(context, mTileByComponentCache, mExtraAction);
mCategories = TileUtils.getCategories(context, mTileByComponentCache);
for (DashboardCategory category : mCategories) {
mCategoryByKeyMap.put(category.key, category);
}

View File

@@ -40,10 +40,9 @@ import com.android.settings.R;
import com.android.settings.R.id;
import com.android.settings.dashboard.DashboardData.ConditionHeaderData;
import com.android.settings.dashboard.suggestions.SuggestionAdapter;
import com.android.settings.homepage.conditional.Condition;
import com.android.settings.homepage.conditional.ConditionAdapter;
import com.android.settings.homepage.conditional.v2.ConditionManager;
import com.android.settings.homepage.conditional.v2.ConditionalCard;
import com.android.settings.homepage.conditional.ConditionManager;
import com.android.settings.homepage.conditional.ConditionalCard;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.RoundedHomepageIcon;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -88,7 +87,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
};
public DashboardAdapter(Context context, Bundle savedInstanceState,
List<Condition> conditions, ConditionManager conditionManager,
ConditionManager conditionManager,
SuggestionControllerMixinCompat suggestionControllerMixin, Lifecycle lifecycle) {
DashboardCategory category = null;
@@ -116,8 +115,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
}
mDashboardData = new DashboardData.Builder()
.setConditions(conditions)
.setConditionsV2(
.setConditions(
conditionManager == null ? null : conditionManager.getDisplayableCards())
.setSuggestions(mSuggestionAdapter.getSuggestions())
.setCategory(category)
@@ -142,7 +140,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
notifyDashboardDataChanged(prevData);
}
public void setConditions(List<Condition> conditions) {
public void setConditions(List<ConditionalCard> conditions) {
final DashboardData prevData = mDashboardData;
Log.d(TAG, "adapter setConditions called");
mDashboardData = new DashboardData.Builder(prevData)
@@ -151,15 +149,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
notifyDashboardDataChanged(prevData);
}
public void setConditionsV2(List<ConditionalCard> conditions) {
final DashboardData prevData = mDashboardData;
Log.d(TAG, "adapter setConditions called");
mDashboardData = new DashboardData.Builder(prevData)
.setConditionsV2(conditions)
.build();
notifyDashboardDataChanged(prevData);
}
@Override
public void onSuggestionClosed(Suggestion suggestion) {
final List<Suggestion> list = mDashboardData.getSuggestions();
@@ -301,31 +290,12 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
@VisibleForTesting
void onBindCondition(final ConditionContainerHolder holder, int position) {
final List conditions = (List) mDashboardData.getItemEntityByPosition(position);
final List<Condition> conditionsV1;
final List<ConditionalCard> conditionsV2;
if (conditions == null || conditions.isEmpty()) {
conditionsV1 = null;
conditionsV2 = null;
} else if (conditions.get(0) instanceof Condition) {
conditionsV1 = conditions;
conditionsV2 = null;
} else {
conditionsV1 = null;
conditionsV2 = conditions;
}
if (conditionsV2 == null) {
final ConditionAdapter adapter = new ConditionAdapter(mContext,
conditionsV1, mDashboardData.isConditionExpanded());
adapter.addDismissHandling(holder.data);
holder.data.setAdapter(adapter);
} else {
final com.android.settings.homepage.conditional.v2.ConditionAdapter adapter =
new com.android.settings.homepage.conditional.v2.ConditionAdapter(
mContext, mConditionManager, conditionsV2,
mDashboardData.isConditionExpanded());
holder.data.setAdapter(adapter);
}
final List<ConditionalCard> conditions =
(List) mDashboardData.getItemEntityByPosition(position);
final ConditionAdapter adapter = new ConditionAdapter(
mContext, mConditionManager, conditions,
mDashboardData.isConditionExpanded());
holder.data.setAdapter(adapter);
holder.data.setLayoutManager(new LinearLayoutManager(mContext));
}
@@ -355,9 +325,10 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
mCache.updateIcon(tileIcon, icon);
}
holder.icon.setImageDrawable(icon);
holder.title.setText(tile.title);
if (!TextUtils.isEmpty(tile.summary)) {
holder.summary.setText(tile.summary);
holder.title.setText(tile.getTitle(mContext));
final CharSequence summary = tile.getSummary(mContext);
if (!TextUtils.isEmpty(summary)) {
holder.summary.setText(summary);
holder.summary.setVisibility(View.VISIBLE);
} else {
holder.summary.setVisibility(View.GONE);

View File

@@ -24,8 +24,7 @@ import androidx.annotation.VisibleForTesting;
import androidx.recyclerview.widget.DiffUtil;
import com.android.settings.R;
import com.android.settings.homepage.conditional.Condition;
import com.android.settings.homepage.conditional.v2.ConditionalCard;
import com.android.settings.homepage.conditional.ConditionalCard;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
@@ -33,7 +32,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Description about data list used in the DashboardAdapter. In the data list each item can be
@@ -58,15 +56,13 @@ public class DashboardData {
private final List<Item> mItems;
private final DashboardCategory mCategory;
private final List<Condition> mConditions;
private final List<ConditionalCard> mConditionsV2;
private final List<ConditionalCard> mConditions;
private final List<Suggestion> mSuggestions;
private final boolean mConditionExpanded;
private DashboardData(Builder builder) {
mCategory = builder.mCategory;
mConditions = builder.mConditions;
mConditionsV2 = builder.mConditionsV2;
mSuggestions = builder.mSuggestions;
mConditionExpanded = builder.mConditionExpanded;
mItems = new ArrayList<>();
@@ -107,7 +103,7 @@ public class DashboardData {
return mCategory;
}
public List<Condition> getConditions() {
public List<ConditionalCard> getConditions() {
return mConditions;
}
@@ -147,7 +143,7 @@ public class DashboardData {
* Find the position of the Tile object.
* <p>
* First, try to find the exact identical instance of the tile object, if not found,
* then try to find a tile has the same title.
* then try to find a tile has the same id.
*
* @param tile tile that need to be found
* @return position of the object, return INDEX_NOT_FOUND if object isn't in the list
@@ -158,7 +154,7 @@ public class DashboardData {
final Object entity = mItems.get(i).entity;
if (entity == tile) {
return i;
} else if (entity instanceof Tile && tile.title.equals(((Tile) entity).title)) {
} else if (entity instanceof Tile && tile.getId() == ((Tile) entity).getId()) {
return i;
}
}
@@ -169,7 +165,8 @@ public class DashboardData {
/**
* Add item into list when {@paramref add} is true.
*
* @param item maybe {@link Condition}, {@link Tile}, {@link DashboardCategory} or null
* @param item maybe {@link ConditionalCard}, {@link Tile}, {@link DashboardCategory}
* or null
* @param type type of the item, and value is the layout id
* @param stableId The stable id for this item
* @param add flag about whether to add item into list
@@ -185,11 +182,8 @@ public class DashboardData {
* and mIsShowingAll, mConditionExpanded flag.
*/
private void buildItemsData() {
final List<Condition> conditionsV1 = getConditionsToShow(mConditions);
final boolean hasConditionsV1 = sizeOf(conditionsV1) > 0;
final List<ConditionalCard> conditionsV2 = mConditionsV2;
final boolean hasConditionsV2 = sizeOf(conditionsV2) > 0;
final boolean hasConditions = hasConditionsV1 || hasConditionsV2;
final List<ConditionalCard> conditions = mConditions;
final boolean hasConditions = sizeOf(conditions) > 0;
final List<Suggestion> suggestions = getSuggestionsToShow(mSuggestions);
final boolean hasSuggestions = sizeOf(suggestions) > 0;
@@ -204,20 +198,14 @@ public class DashboardData {
STABLE_ID_SUGGESTION_CONDITION_DIVIDER, hasSuggestions && hasConditions);
/* Condition header. This will be present when there is condition and it is collapsed */
addToItemList(new ConditionHeaderData(conditionsV1, conditionsV2),
addToItemList(new ConditionHeaderData(conditions),
R.layout.condition_header,
STABLE_ID_CONDITION_HEADER, hasConditions && !mConditionExpanded);
/* Condition container. This is the card view that contains the list of conditions.
* This will be added whenever the condition list is not empty and expanded */
if (hasConditionsV1) {
addToItemList(conditionsV1, R.layout.condition_container,
STABLE_ID_CONDITION_CONTAINER, hasConditionsV1 && mConditionExpanded);
}
if (hasConditionsV2) {
addToItemList(conditionsV2, R.layout.condition_container,
STABLE_ID_CONDITION_CONTAINER, hasConditionsV2 && mConditionExpanded);
}
addToItemList(conditions, R.layout.condition_container,
STABLE_ID_CONDITION_CONTAINER, hasConditions && mConditionExpanded);
/* Condition footer. This will be present when there is condition and it is expanded */
addToItemList(null /* item */, R.layout.condition_footer,
@@ -227,7 +215,7 @@ public class DashboardData {
final List<Tile> tiles = mCategory.getTiles();
for (int i = 0; i < tiles.size(); i++) {
final Tile tile = tiles.get(i);
addToItemList(tile, R.layout.dashboard_tile, Objects.hash(tile.title),
addToItemList(tile, R.layout.dashboard_tile, tile.getId(),
true /* add */);
}
}
@@ -237,21 +225,6 @@ public class DashboardData {
return list == null ? 0 : list.size();
}
private List<Condition> getConditionsToShow(List<Condition> conditions) {
if (conditions == null) {
return null;
}
List<Condition> result = new ArrayList<>();
final int size = conditions == null ? 0 : conditions.size();
for (int i = 0; i < size; i++) {
final Condition condition = conditions.get(i);
if (condition.shouldShow()) {
result.add(condition);
}
}
return result;
}
private List<Suggestion> getSuggestionsToShow(List<Suggestion> suggestions) {
if (suggestions == null) {
return null;
@@ -271,8 +244,7 @@ public class DashboardData {
*/
public static class Builder {
private DashboardCategory mCategory;
private List<Condition> mConditions;
private List<ConditionalCard> mConditionsV2;
private List<ConditionalCard> mConditions;
private List<Suggestion> mSuggestions;
private boolean mConditionExpanded;
@@ -282,7 +254,6 @@ public class DashboardData {
public Builder(DashboardData dashboardData) {
mCategory = dashboardData.mCategory;
mConditions = dashboardData.mConditions;
mConditionsV2 = dashboardData.mConditionsV2;
mSuggestions = dashboardData.mSuggestions;
mConditionExpanded = dashboardData.mConditionExpanded;
}
@@ -292,16 +263,11 @@ public class DashboardData {
return this;
}
public Builder setConditions(List<Condition> conditions) {
public Builder setConditions(List<ConditionalCard> conditions) {
this.mConditions = conditions;
return this;
}
public Builder setConditionsV2(List<ConditionalCard> conditions) {
this.mConditionsV2 = conditions;
return this;
}
public Builder setSuggestions(List<Suggestion> suggestions) {
this.mSuggestions = suggestions;
return this;
@@ -375,7 +341,7 @@ public class DashboardData {
}
/**
* The main data object in item, usually is a {@link Tile}, {@link Condition}
* The main data object in item, usually is a {@link Tile}, {@link ConditionalCard}
* object. This object can also be null when the
* item is an divider line. Please refer to {@link #buildItemsData()} for
* detail usage of the Item.
@@ -425,9 +391,11 @@ public class DashboardData {
final Tile localTile = (Tile) entity;
final Tile targetTile = (Tile) targetItem.entity;
// Only check title and summary for dashboard tile
return TextUtils.equals(localTile.title, targetTile.title)
&& TextUtils.equals(localTile.summary, targetTile.summary);
// Only check id and summary for dashboard tile
return localTile.getId() == targetTile.getId()
&& TextUtils.equals(
localTile.getSummaryReference(),
targetTile.getSummaryReference());
case TYPE_SUGGESTION_CONTAINER:
case TYPE_CONDITION_CONTAINER:
// Fall through to default
@@ -447,22 +415,15 @@ public class DashboardData {
public final CharSequence title;
public final int conditionCount;
public ConditionHeaderData(List<Condition> conditions, List<ConditionalCard> conditionsV2) {
if (conditionsV2 == null) {
conditionCount = sizeOf(conditions);
title = conditionCount > 0 ? conditions.get(0).getTitle() : null;
conditionIcons = new ArrayList<>();
for (int i = 0; conditions != null && i < conditions.size(); i++) {
final Condition condition = conditions.get(i);
conditionIcons.add(condition.getIcon());
}
} else {
conditionCount = sizeOf(conditionsV2);
title = conditionCount > 0 ? conditionsV2.get(0).getTitle() : null;
conditionIcons = new ArrayList<>();
for (ConditionalCard card : conditionsV2) {
conditionIcons.add(card.getIcon());
}
public ConditionHeaderData(List<ConditionalCard> conditions) {
conditionCount = sizeOf(conditions);
title = conditionCount > 0 ? conditions.get(0).getTitle() : null;
conditionIcons = new ArrayList<>();
if (conditions == null) {
return;
}
for (ConditionalCard card : conditions) {
conditionIcons.add(card.getIcon());
}
}
}

View File

@@ -58,11 +58,6 @@ public interface DashboardFeatureProvider {
void bindPreferenceToTile(FragmentActivity activity, boolean forceRoundedIcon,
int sourceMetricsCategory, Preference pref, Tile tile, String key, int baseOrder);
/**
* Returns additional intent filter action for dashboard tiles
*/
String getExtraIntentAction();
/**
* Opens a tile to its destination intent.
*/

View File

@@ -71,7 +71,7 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
public DashboardFeatureProviderImpl(Context context) {
mContext = context.getApplicationContext();
mCategoryManager = CategoryManager.get(context, getExtraIntentAction());
mCategoryManager = CategoryManager.get(context);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mPackageManager = context.getPackageManager();
}
@@ -106,7 +106,7 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
if (pref == null) {
return;
}
pref.setTitle(tile.title);
pref.setTitle(tile.getTitle(activity.getApplicationContext()));
if (!TextUtils.isEmpty(key)) {
pref.setKey(key);
} else {
@@ -151,11 +151,6 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
}
}
@Override
public String getExtraIntentAction() {
return null;
}
@Override
public void openTileIntent(FragmentActivity activity, Tile tile) {
if (tile == null) {
@@ -172,8 +167,9 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
}
private void bindSummary(Preference preference, Tile tile) {
if (tile.summary != null) {
preference.setSummary(tile.summary);
final CharSequence summary = tile.getSummary(mContext);
if (summary != null) {
preference.setSummary(summary);
} else if (tile.getMetaData() != null
&& tile.getMetaData().containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
// Set a placeholder summary before starting to fetch real summary, this is necessary
@@ -183,9 +179,9 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
ThreadUtils.postOnBackgroundThread(() -> {
final Map<String, IContentProvider> providerMap = new ArrayMap<>();
final String uri = tile.getMetaData().getString(META_DATA_PREFERENCE_SUMMARY_URI);
final String summary = TileUtils.getTextFromUri(
final String summaryFromUri = TileUtils.getTextFromUri(
mContext, uri, providerMap, META_DATA_PREFERENCE_SUMMARY);
ThreadUtils.postOnMainThread(() -> preference.setSummary(summary));
ThreadUtils.postOnMainThread(() -> preference.setSummary(summaryFromUri));
});
} else {
preference.setSummary(R.string.summary_placeholder);

View File

@@ -156,12 +156,12 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
final Preference pref = getPreferenceScreen().findPreference(key);
if (pref == null) {
Log.d(getLogTag(),
String.format("Can't find pref by key %s, skipping update summary %s/%s",
key, tile.title, tile.summary));
Log.d(getLogTag(), String.format(
"Can't find pref by key %s, skipping update summary %s",
key, tile.getDescription()));
return;
}
pref.setSummary(tile.summary);
pref.setSummary(tile.getSummary(pref.getContext()));
}
@Override

View File

@@ -37,11 +37,10 @@ import com.android.settings.core.InstrumentedFragment;
import com.android.settings.core.SettingsBaseActivity;
import com.android.settings.core.SettingsBaseActivity.CategoryListener;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.homepage.conditional.Condition;
import com.android.settings.homepage.conditional.ConditionListener;
import com.android.settings.homepage.conditional.ConditionManager;
import com.android.settings.homepage.conditional.FocusRecyclerView;
import com.android.settings.homepage.conditional.FocusRecyclerView.FocusListener;
import com.android.settings.homepage.conditional.ConditionManager;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.ActionBarShadowController;
import com.android.settingslib.drawer.CategoryKey;
@@ -74,7 +73,6 @@ public class DashboardSummary extends InstrumentedFragment
private DashboardAdapter mAdapter;
private SummaryLoader mSummaryLoader;
private ConditionManager mConditionManager;
private com.android.settings.homepage.conditional.v2.ConditionManager mConditionManager2;
private LinearLayoutManager mLayoutManager;
private SuggestionControllerMixinCompat mSuggestionControllerMixin;
private DashboardFeatureProvider mDashboardFeatureProvider;
@@ -123,18 +121,9 @@ public class DashboardSummary extends InstrumentedFragment
mSummaryLoader = new SummaryLoader(activity, CategoryKey.CATEGORY_HOMEPAGE);
if (com.android.settings.homepage.conditional.v2.ConditionManager.isEnabled(activity)) {
mConditionManager = null;
mConditionManager2 =
new com.android.settings.homepage.conditional.v2.ConditionManager(
activity, this /* listener */);
} else {
mConditionManager = ConditionManager.get(activity, false);
mConditionManager2 = null;
}
if (mConditionManager2 == null) {
getSettingsLifecycle().addObserver(mConditionManager);
}
mConditionManager =
new ConditionManager(
activity, this /* listener */);
if (savedInstanceState != null) {
mIsOnCategoriesChangedCalled =
savedInstanceState.getBoolean(STATE_CATEGORIES_CHANGE_CALLED);
@@ -157,17 +146,7 @@ public class DashboardSummary extends InstrumentedFragment
((SettingsBaseActivity) getActivity()).addCategoryListener(this);
mSummaryLoader.setListening(true);
final int metricsCategory = getMetricsCategory();
if (mConditionManager2 == null) {
for (Condition c : mConditionManager.getConditions()) {
if (c.shouldShow()) {
mMetricsFeatureProvider.visible(getContext(), metricsCategory,
c.getMetricsConstant());
}
}
} else {
mConditionManager2.startMonitoringStateChange();
}
mConditionManager.startMonitoringStateChange();
if (DEBUG_TIMING) {
Log.d(TAG, "onResume took " + (System.currentTimeMillis() - startTime) + " ms");
}
@@ -179,42 +158,16 @@ public class DashboardSummary extends InstrumentedFragment
((SettingsBaseActivity) getActivity()).remCategoryListener(this);
mSummaryLoader.setListening(false);
if (mConditionManager2 == null) {
for (Condition c : mConditionManager.getConditions()) {
if (c.shouldShow()) {
mMetricsFeatureProvider.hidden(getContext(), c.getMetricsConstant());
}
}
}
// Unregister condition listeners.
if (mConditionManager != null) {
mConditionManager.remListener(this);
}
if (mConditionManager2 != null) {
mConditionManager2.stopMonitoringStateChange();
}
mConditionManager.stopMonitoringStateChange();
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
long startTime = System.currentTimeMillis();
if (mConditionManager2 == null) {
if (hasWindowFocus) {
Log.d(TAG, "Listening for condition changes");
mConditionManager.addListener(this);
Log.d(TAG, "conditions refreshed");
mConditionManager.refreshAll();
} else {
Log.d(TAG, "Stopped listening for condition changes");
mConditionManager.remListener(this);
}
if (hasWindowFocus) {
mConditionManager.startMonitoringStateChange();
} else {
// TODO(b/112485407): Register monitoring for condition manager v2.
if (hasWindowFocus) {
mConditionManager2.startMonitoringStateChange();
} else {
mConditionManager2.stopMonitoringStateChange();
}
mConditionManager.stopMonitoringStateChange();
}
if (DEBUG_TIMING) {
Log.d(TAG, "onWindowFocusChanged took "
@@ -248,8 +201,7 @@ public class DashboardSummary extends InstrumentedFragment
mDashboard.setListener(this);
mDashboard.setItemAnimator(new DashboardItemAnimator());
mAdapter = new DashboardAdapter(getContext(), bundle,
mConditionManager == null ? null : mConditionManager.getConditions(),
mConditionManager2,
mConditionManager,
mSuggestionControllerMixin,
getSettingsLifecycle());
mDashboard.setAdapter(mAdapter);
@@ -290,14 +242,10 @@ public class DashboardSummary extends InstrumentedFragment
// constructor when we create the view, the first handling is not necessary.
// But, on the subsequent calls we need to handle it because there might be real changes to
// conditions.
if (mOnConditionsChangedCalled || mConditionManager2 != null) {
if (mOnConditionsChangedCalled) {
final boolean scrollToTop =
mLayoutManager.findFirstCompletelyVisibleItemPosition() <= 1;
if (mConditionManager2 == null) {
mAdapter.setConditions(mConditionManager.getConditions());
} else {
mAdapter.setConditionsV2(mConditionManager2.getDisplayableCards());
}
mAdapter.setConditions(mConditionManager.getDisplayableCards());
if (scrollToTop) {
mDashboard.scrollToPosition(0);

View File

@@ -18,6 +18,7 @@ package com.android.settings.dashboard;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
@@ -96,29 +97,30 @@ public class SummaryLoader {
return;
}
if (DEBUG) {
Log.d(TAG, "setSummary " + tile.title + " - " + summary);
Log.d(TAG, "setSummary " + tile.getDescription() + " - " + summary);
}
updateSummaryIfNeeded(tile, summary);
updateSummaryIfNeeded(mActivity.getApplicationContext(), tile, summary);
});
}
@VisibleForTesting
void updateSummaryIfNeeded(Tile tile, CharSequence summary) {
if (TextUtils.equals(tile.summary, summary)) {
void updateSummaryIfNeeded(Context context, Tile tile, CharSequence summary) {
if (TextUtils.equals(tile.getSummary(context), summary)) {
if (DEBUG) {
Log.d(TAG, "Summary doesn't change, skipping summary update for " + tile.title);
Log.d(TAG, "Summary doesn't change, skipping summary update for "
+ tile.getDescription());
}
return;
}
mSummaryTextMap.put(mDashboardFeatureProvider.getDashboardKeyForTile(tile), summary);
tile.summary = summary;
tile.overrideSummary(summary);
if (mSummaryConsumer != null) {
mSummaryConsumer.notifySummaryChanged(tile);
} else {
if (DEBUG) {
Log.d(TAG, "SummaryConsumer is null, skipping summary update for "
+ tile.title);
+ tile.getDescription());
}
}
}
@@ -215,7 +217,7 @@ public class SummaryLoader {
for (Tile tile : category.getTiles()) {
final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
if (mSummaryTextMap.containsKey(key)) {
tile.summary = mSummaryTextMap.get(key);
tile.overrideSummary(mSummaryTextMap.get(key));
}
}
}

View File

@@ -31,6 +31,7 @@ import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
import java.util.Comparator;
import java.util.List;
import androidx.annotation.VisibleForTesting;
@@ -43,6 +44,8 @@ public class EmulateDisplayCutoutPreferenceController extends
PreferenceControllerMixin {
private static final String KEY = "display_cutout_emulation";
private static final Comparator<OverlayInfo> OVERLAY_INFO_COMPARATOR =
Comparator.comparingInt(a -> a.priority);
private final IOverlayManager mOverlayManager;
private final boolean mAvailable;
@@ -128,7 +131,7 @@ public class EmulateDisplayCutoutPreferenceController extends
int current = 0;
pkgs[0] = "";
labels[0] = mContext.getString(R.string.display_cutout_emulation_none);
labels[0] = mContext.getString(R.string.display_cutout_emulation_device_default);
for (int i = 0; i < overlays.length; i++) {
OverlayInfo o = overlays[i];
@@ -165,6 +168,7 @@ public class EmulateDisplayCutoutPreferenceController extends
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
overlayInfos.sort(OVERLAY_INFO_COMPARATOR);
return overlayInfos.toArray(new OverlayInfo[overlayInfos.size()]);
}

View File

@@ -65,7 +65,6 @@ public class MyDeviceInfoFragment extends DashboardFragment
private static final String LOG_TAG = "MyDeviceInfoFragment";
private static final String KEY_MY_DEVICE_INFO_HEADER = "my_device_info_header";
private static final String KEY_LEGAL_CONTAINER = "legal_container";
@Override
public int getMetricsCategory() {
@@ -223,13 +222,5 @@ public class MyDeviceInfoFragment extends DashboardFragment
return buildPreferenceControllers(context, null /*activity */,
null /* fragment */, null /* lifecycle */);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
// The legal container is duplicated, so we ignore it here.
keys.add(KEY_LEGAL_CONTAINER);
return keys;
}
};
}

View File

@@ -52,7 +52,7 @@ public class AutoBrightnessPreferenceController extends TogglePreferenceControll
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available)
? AVAILABLE
? AVAILABLE_UNSEARCHABLE
: UNSUPPORTED_ON_DEVICE;
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.dream;
import android.content.Context;
import com.android.settings.core.BasePreferenceController;
public class DreamEntryPreferenceController extends BasePreferenceController {
public DreamEntryPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE_UNSEARCHABLE;
}
}

View File

@@ -49,7 +49,7 @@ public class BatterySaverController extends BasePreferenceController
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
return AVAILABLE_UNSEARCHABLE;
}
@Override

View File

@@ -68,7 +68,6 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
private static final boolean DEBUG = false;
private static final String KEY_BATTERY_HEADER = "battery_header";
private static final String KEY_BATTERY_TIP = "battery_tip";
private static final String KEY_SCREEN_USAGE = "screen_usage";
private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge";
@@ -429,13 +428,6 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
sir.xmlResId = R.xml.power_usage_summary;
return Collections.singletonList(sir);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> niks = super.getNonIndexableKeys(context);
niks.add(KEY_BATTERY_SAVER_SUMMARY);
return niks;
}
};
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY

View File

@@ -22,13 +22,13 @@ import static android.provider.Settings.Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENA
import android.content.Context;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
public class AssistGestureSettingsPreferenceController extends GesturePreferenceController {
private static final String PREF_KEY_VIDEO = "gesture_assist_video";
@@ -38,7 +38,6 @@ public class AssistGestureSettingsPreferenceController extends GesturePreference
private static final int ON = 1;
private static final int OFF = 0;
private final String mAssistGesturePrefKey;
private final AssistGestureFeatureProvider mFeatureProvider;
private boolean mWasAvailable;
@@ -48,12 +47,10 @@ public class AssistGestureSettingsPreferenceController extends GesturePreference
@VisibleForTesting
boolean mAssistOnly;
public AssistGestureSettingsPreferenceController(Context context,
String key) {
public AssistGestureSettingsPreferenceController(Context context, String key) {
super(context, key);
mFeatureProvider = FeatureFactory.getFactory(context).getAssistGestureFeatureProvider();
mWasAvailable = isAvailable();
mAssistGesturePrefKey = key;
}
@Override

View File

@@ -1,84 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.homepage.conditional;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.provider.Settings;
import com.android.settings.R;
@Deprecated
public abstract class AbnormalRingerConditionBase extends Condition {
private final IntentFilter mFilter;
protected final AudioManager mAudioManager;
private final RingerModeChangeReceiver mReceiver;
AbnormalRingerConditionBase(ConditionManager manager) {
super(manager);
mAudioManager =
(AudioManager) mManager.getContext().getSystemService(Context.AUDIO_SERVICE);
mReceiver = new RingerModeChangeReceiver(this);
mFilter = new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
manager.getContext().registerReceiver(mReceiver, mFilter);
}
@Override
public CharSequence[] getActions() {
return new CharSequence[]{
mManager.getContext().getText(R.string.condition_device_muted_action_turn_on_sound)
};
}
@Override
public void onPrimaryClick() {
mManager.getContext().startActivity(
new Intent(Settings.ACTION_SOUND_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
@Override
public void onActionClick(int index) {
mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL);
mAudioManager.setStreamVolume(AudioManager.STREAM_RING, 1, 0 /* flags */);
refreshState();
}
static class RingerModeChangeReceiver extends BroadcastReceiver {
private final AbnormalRingerConditionBase mCondition;
public RingerModeChangeReceiver(AbnormalRingerConditionBase condition) {
mCondition = condition;
}
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
mCondition.refreshState();
}
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -23,8 +23,6 @@ import android.content.IntentFilter;
import android.media.AudioManager;
import android.provider.Settings;
import java.util.Objects;
public abstract class AbnormalRingerConditionController implements ConditionalCardController {
private static final IntentFilter FILTER =

View File

@@ -1,121 +0,0 @@
/*
* Copyright (C) 2015 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.homepage.conditional;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.provider.Settings;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settingslib.WirelessUtils;
/**
* @deprecated in favor of {@link AirplaneModeConditionCard}.
*/
@Deprecated
public class AirplaneModeCondition extends Condition {
public static String TAG = "APM_Condition";
private final Receiver mReceiver;
private static final IntentFilter AIRPLANE_MODE_FILTER =
new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
public AirplaneModeCondition(ConditionManager conditionManager) {
super(conditionManager);
mReceiver = new Receiver();
}
@Override
public void refreshState() {
Log.d(TAG, "APM condition refreshed");
setActive(WirelessUtils.isAirplaneModeOn(mManager.getContext()));
}
@Override
protected BroadcastReceiver getReceiver() {
return mReceiver;
}
@Override
protected IntentFilter getIntentFilter() {
return AIRPLANE_MODE_FILTER;
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_airplane);
}
@Override
protected void setActive(boolean active) {
super.setActive(active);
Log.d(TAG, "setActive was called with " + active);
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getString(R.string.condition_airplane_title);
}
@Override
public CharSequence getSummary() {
return mManager.getContext().getString(R.string.condition_airplane_summary);
}
@Override
public CharSequence[] getActions() {
return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
}
@Override
public void onPrimaryClick() {
mManager.getContext().startActivity(
new Intent(Settings.ACTION_WIRELESS_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
@Override
public void onActionClick(int index) {
if (index == 0) {
ConnectivityManager.from(mManager.getContext()).setAirplaneMode(false);
setActive(false);
} else {
throw new IllegalArgumentException("Unexpected index " + index);
}
}
@Override
public int getMetricsConstant() {
return MetricsEvent.SETTINGS_CONDITION_AIRPLANE_MODE;
}
public static class Receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) {
ConditionManager.get(context).getCondition(AirplaneModeCondition.class)
.refreshState();
}
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.BroadcastReceiver;
import android.content.Context;

View File

@@ -1,79 +0,0 @@
/*
* Copyright (C) 2015 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.homepage.conditional;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.NetworkPolicyManager;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Settings;
@Deprecated
public class BackgroundDataCondition extends Condition {
public BackgroundDataCondition(ConditionManager manager) {
super(manager);
}
@Override
public void refreshState() {
setActive(NetworkPolicyManager.from(mManager.getContext()).getRestrictBackground());
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_data_saver);
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getString(R.string.condition_bg_data_title);
}
@Override
public CharSequence getSummary() {
return mManager.getContext().getString(R.string.condition_bg_data_summary);
}
@Override
public CharSequence[] getActions() {
return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
}
@Override
public void onPrimaryClick() {
mManager.getContext().startActivity(new Intent(mManager.getContext(),
Settings.DataUsageSummaryActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
@Override
public int getMetricsConstant() {
return MetricsEvent.SETTINGS_CONDITION_BACKGROUND_DATA;
}
@Override
public void onActionClick(int index) {
if (index == 0) {
NetworkPolicyManager.from(mManager.getContext()).setRestrictBackground(false);
setActive(false);
} else {
throw new IllegalArgumentException("Unexpected index " + index);
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.content.Intent;

View File

@@ -1,117 +0,0 @@
/*
* Copyright (C) 2015 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.homepage.conditional;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.PowerManager;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.fuelgauge.BatterySaverReceiver;
import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
import com.android.settingslib.fuelgauge.BatterySaverUtils;
/**
* @deprecated in favor of {@link BatterySaverConditionCard}
*/
@Deprecated
public class BatterySaverCondition extends Condition implements
BatterySaverReceiver.BatterySaverListener {
private final BatterySaverReceiver mReceiver;
public BatterySaverCondition(ConditionManager manager) {
super(manager);
mReceiver = new BatterySaverReceiver(manager.getContext());
mReceiver.setBatterySaverListener(this);
}
@Override
public void refreshState() {
PowerManager powerManager = mManager.getContext().getSystemService(PowerManager.class);
setActive(powerManager.isPowerSaveMode());
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_battery_saver_accent_24dp);
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getString(R.string.condition_battery_title);
}
@Override
public CharSequence getSummary() {
return mManager.getContext().getString(R.string.condition_battery_summary);
}
@Override
public CharSequence[] getActions() {
return new CharSequence[]{mManager.getContext().getString(R.string.condition_turn_off)};
}
@Override
public void onPrimaryClick() {
new SubSettingLauncher(mManager.getContext())
.setDestination(BatterySaverSettings.class.getName())
.setSourceMetricsCategory(MetricsEvent.DASHBOARD_SUMMARY)
.setTitleRes(R.string.battery_saver)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.launch();
}
@Override
public void onActionClick(int index) {
if (index == 0) {
BatterySaverUtils.setPowerSaveMode(mManager.getContext(), false,
/*needFirstTimeWarning*/ false);
refreshState();
} else {
throw new IllegalArgumentException("Unexpected index " + index);
}
}
@Override
public int getMetricsConstant() {
return MetricsEvent.SETTINGS_CONDITION_BATTERY_SAVER;
}
@Override
public void onResume() {
mReceiver.setListening(true);
}
@Override
public void onPause() {
mReceiver.setListening(false);
}
@Override
public void onPowerSaveModeChanged() {
ConditionManager.get(mManager.getContext()).getCondition(BatterySaverCondition.class)
.refreshState();
}
@Override
public void onBatteryChanged(boolean pluggedIn) {
// do nothing
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.os.PowerManager;

View File

@@ -1,118 +0,0 @@
/*
* Copyright (C) 2015 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.homepage.conditional;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.telephony.TelephonyManager;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.TelephonyIntents;
import com.android.settings.R;
import com.android.settings.Settings;
@Deprecated
public class CellularDataCondition extends Condition {
private final Receiver mReceiver;
private static final IntentFilter DATA_CONNECTION_FILTER =
new IntentFilter(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
public CellularDataCondition(ConditionManager manager) {
super(manager);
mReceiver = new Receiver();
}
@Override
public void refreshState() {
ConnectivityManager connectivity = mManager.getContext().getSystemService(
ConnectivityManager.class);
TelephonyManager telephony = mManager.getContext().getSystemService(TelephonyManager.class);
if (!connectivity.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)
|| telephony.getSimState() != TelephonyManager.SIM_STATE_READY) {
setActive(false);
return;
}
setActive(!telephony.isDataEnabled());
}
@Override
protected BroadcastReceiver getReceiver() {
return mReceiver;
}
@Override
protected IntentFilter getIntentFilter() {
return DATA_CONNECTION_FILTER;
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_cellular_off);
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getString(R.string.condition_cellular_title);
}
@Override
public CharSequence getSummary() {
return mManager.getContext().getString(R.string.condition_cellular_summary);
}
@Override
public CharSequence[] getActions() {
return new CharSequence[] { mManager.getContext().getString(R.string.condition_turn_on) };
}
@Override
public void onPrimaryClick() {
mManager.getContext().startActivity(new Intent(mManager.getContext(),
Settings.DataUsageSummaryActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
@Override
public void onActionClick(int index) {
if (index == 0) {
TelephonyManager telephony = mManager.getContext().getSystemService(
TelephonyManager.class);
telephony.setDataEnabled(true);
setActive(false);
} else {
throw new IllegalArgumentException("Unexpected index " + index);
}
}
@Override
public int getMetricsConstant() {
return MetricsEvent.SETTINGS_CONDITION_CELLULAR_DATA;
}
public static class Receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED.equals(
intent.getAction())) {
CellularDataCondition condition = ConditionManager.get(context).getCondition(
CellularDataCondition.class);
if (condition != null) {
condition.refreshState();
}
}
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.BroadcastReceiver;
import android.content.Context;

View File

@@ -1,162 +0,0 @@
/*
* Copyright (C) 2015 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.homepage.conditional;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.os.PersistableBundle;
import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public abstract class Condition {
private static final String KEY_SILENCE = "silence";
private static final String KEY_ACTIVE = "active";
private static final String KEY_LAST_STATE = "last_state";
protected final ConditionManager mManager;
protected final MetricsFeatureProvider mMetricsFeatureProvider;
protected boolean mReceiverRegistered;
private boolean mIsSilenced;
private boolean mIsActive;
private long mLastStateChange;
// All conditions must live in this package.
Condition(ConditionManager manager) {
this(manager, FeatureFactory.getFactory(manager.getContext()).getMetricsFeatureProvider());
}
Condition(ConditionManager manager, MetricsFeatureProvider metricsFeatureProvider) {
mManager = manager;
mMetricsFeatureProvider = metricsFeatureProvider;
}
void restoreState(PersistableBundle bundle) {
mIsSilenced = bundle.getBoolean(KEY_SILENCE);
mIsActive = bundle.getBoolean(KEY_ACTIVE);
mLastStateChange = bundle.getLong(KEY_LAST_STATE);
}
boolean saveState(PersistableBundle bundle) {
if (mIsSilenced) {
bundle.putBoolean(KEY_SILENCE, mIsSilenced);
}
if (mIsActive) {
bundle.putBoolean(KEY_ACTIVE, mIsActive);
bundle.putLong(KEY_LAST_STATE, mLastStateChange);
}
return mIsSilenced || mIsActive;
}
protected void notifyChanged() {
mManager.notifyChanged(this);
}
public boolean isSilenced() {
return mIsSilenced;
}
public boolean isActive() {
return mIsActive;
}
protected void setActive(boolean active) {
if (mIsActive == active) {
return;
}
mIsActive = active;
mLastStateChange = System.currentTimeMillis();
if (mIsSilenced && !active) {
mIsSilenced = false;
onSilenceChanged(mIsSilenced);
}
notifyChanged();
}
public void silence() {
if (!mIsSilenced) {
mIsSilenced = true;
Context context = mManager.getContext();
mMetricsFeatureProvider.action(context, MetricsEvent.ACTION_SETTINGS_CONDITION_DISMISS,
getMetricsConstant());
onSilenceChanged(mIsSilenced);
notifyChanged();
}
}
@VisibleForTesting
void onSilenceChanged(boolean silenced) {
final BroadcastReceiver receiver = getReceiver();
if (receiver == null) {
return;
}
if (silenced) {
if (!mReceiverRegistered) {
mManager.getContext().registerReceiver(receiver, getIntentFilter());
mReceiverRegistered = true;
}
} else {
if (mReceiverRegistered) {
mManager.getContext().unregisterReceiver(receiver);
mReceiverRegistered = false;
}
}
}
protected BroadcastReceiver getReceiver() {
return null;
}
protected IntentFilter getIntentFilter() {
return null;
}
public boolean shouldShow() {
return isActive() && !isSilenced();
}
long getLastChange() {
return mLastStateChange;
}
public void onResume() {
}
public void onPause() {
}
// State.
public abstract void refreshState();
public abstract int getMetricsConstant();
// UI.
public abstract Drawable getIcon();
public abstract CharSequence getTitle();
public abstract CharSequence getSummary();
public abstract CharSequence[] getActions();
public abstract void onPrimaryClick();
public abstract void onActionClick(int index);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 The Android Open Source Project
* 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.
@@ -13,77 +13,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.util.Log;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.VisibleForTesting;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
import com.android.settings.dashboard.DashboardAdapter;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.WirelessUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import java.util.List;
import java.util.Objects;
public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder> {
public static final String TAG = "ConditionAdapter";
public class ConditionAdapter extends RecyclerView.Adapter<DashboardAdapter.DashboardItemHolder> {
private final Context mContext;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private List<Condition> mConditions;
private boolean mExpanded;
private final ConditionManager mConditionManager;
private final List<ConditionalCard> mConditions;
private final boolean mExpanded;
private View.OnClickListener mConditionClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
//TODO: get rid of setTag/getTag
Condition condition = (Condition) v.getTag();
mMetricsFeatureProvider.action(mContext,
MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
condition.getMetricsConstant());
condition.onPrimaryClick();
}
};
@VisibleForTesting
ItemTouchHelper.SimpleCallback mSwipeCallback = new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.START | ItemTouchHelper.END) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
return true;
}
@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return viewHolder.getItemViewType() == R.layout.condition_tile
? super.getSwipeDirs(recyclerView, viewHolder) : 0;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
Object item = getItem(viewHolder.getItemId());
// item can become null when running monkey
if (item != null) {
((Condition) item).silence();
}
}
};
public ConditionAdapter(Context context, List<Condition> conditions, boolean expanded) {
public ConditionAdapter(Context context, ConditionManager conditionManager,
List<ConditionalCard> conditions, boolean expanded) {
mContext = context;
mConditionManager = conditionManager;
mConditions = conditions;
mExpanded = expanded;
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
@@ -91,30 +52,22 @@ public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
setHasStableIds(true);
}
public Object getItem(long itemId) {
for (Condition condition : mConditions) {
if (Objects.hash(condition.getTitle()) == itemId) {
return condition;
}
}
return null;
@Override
public DashboardAdapter.DashboardItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new DashboardAdapter.DashboardItemHolder(LayoutInflater.from(parent.getContext())
.inflate(viewType, parent, false));
}
@Override
public DashboardItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new DashboardItemHolder(LayoutInflater.from(parent.getContext()).inflate(
viewType, parent, false));
}
@Override
public void onBindViewHolder(DashboardItemHolder holder, int position) {
bindViews(mConditions.get(position), holder,
position == mConditions.size() - 1, mConditionClickListener);
public void onBindViewHolder(DashboardAdapter.DashboardItemHolder holder, int position) {
final ConditionalCard condition = mConditions.get(position);
final boolean isLastItem = position == mConditions.size() - 1;
bindViews(condition, holder, isLastItem);
}
@Override
public long getItemId(int position) {
return Objects.hash(mConditions.get(position).getTitle());
return mConditions.get(position).getId();
}
@Override
@@ -130,52 +83,42 @@ public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
return 0;
}
public void addDismissHandling(final RecyclerView recyclerView) {
final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mSwipeCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
}
private void bindViews(final Condition condition,
DashboardItemHolder view, boolean isLastItem,
View.OnClickListener onClickListener) {
if (condition instanceof AirplaneModeCondition) {
Log.d(TAG, "Airplane mode condition has been bound with "
+ "isActive=" + condition.isActive() + ". Airplane mode is currently " +
WirelessUtils.isAirplaneModeOn(condition.mManager.getContext()));
}
View card = view.itemView.findViewById(R.id.content);
card.setTag(condition);
card.setOnClickListener(onClickListener);
private void bindViews(final ConditionalCard condition,
DashboardAdapter.DashboardItemHolder view, boolean isLastItem) {
mMetricsFeatureProvider.visible(mContext, MetricsProto.MetricsEvent.DASHBOARD_SUMMARY,
condition.getMetricsConstant());
view.itemView.findViewById(R.id.content).setOnClickListener(
v -> {
mMetricsFeatureProvider.action(mContext,
MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
condition.getMetricsConstant());
mConditionManager.onPrimaryClick(mContext, condition.getId());
});
view.icon.setImageDrawable(condition.getIcon());
view.title.setText(condition.getTitle());
view.summary.setText(condition.getSummary());
CharSequence[] actions = condition.getActions();
final boolean hasButtons = actions.length > 0;
setViewVisibility(view.itemView, R.id.divider, !isLastItem);
final CharSequence action = condition.getActionText();
final boolean hasButtons = !TextUtils.isEmpty(action);
setViewVisibility(view.itemView, R.id.buttonBar, hasButtons);
view.summary.setText(condition.getSummary());
for (int i = 0; i < 2; i++) {
Button button = (Button) view.itemView.findViewById(i == 0
? R.id.first_action : R.id.second_action);
if (actions.length > i) {
button.setVisibility(View.VISIBLE);
button.setText(actions[i]);
final int index = i;
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
.action(context, MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
condition.getMetricsConstant());
condition.onActionClick(index);
}
});
} else {
button.setVisibility(View.GONE);
}
final Button button = view.itemView.findViewById(R.id.first_action);
if (hasButtons) {
button.setVisibility(View.VISIBLE);
button.setText(action);
button.setOnClickListener(v -> {
final Context context = v.getContext();
mMetricsFeatureProvider.action(
context, MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
condition.getMetricsConstant());
mConditionManager.onActionClick(condition.getId());
});
} else {
button.setVisibility(View.GONE);
}
setViewVisibility(view.itemView, R.id.divider, !isLastItem);
}
private void setViewVisibility(View containerView, int viewId, boolean visible) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* 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.
@@ -13,279 +13,187 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.os.AsyncTask;
import android.os.PersistableBundle;
import android.util.Log;
import android.util.Xml;
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.NonNull;
import androidx.annotation.VisibleForTesting;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ConditionManager implements LifecycleObserver, OnResume, OnPause {
public class ConditionManager {
private static final String TAG = "ConditionManager";
private static final boolean DEBUG = false;
@VisibleForTesting
final List<ConditionalCard> mCandidates;
@VisibleForTesting
final List<ConditionalCardController> mCardControllers;
private static final String PKG = "com.android.settings.homepage.conditional.";
private static final long DISPLAYABLE_CHECKER_TIMEOUT_MS = 20;
private static final String FILE_NAME = "condition_state.xml";
private static final String TAG_CONDITIONS = "cs";
private static final String TAG_CONDITION = "c";
private static final String ATTR_CLASS = "cls";
private final ExecutorService mExecutorService;
private final Context mAppContext;
private final ConditionListener mListener;
private static ConditionManager sInstance;
private boolean mIsListeningToStateChange;
private final Context mContext;
private final ArrayList<Condition> mConditions;
private File mXmlFile;
private final ArrayList<ConditionListener> mListeners = new ArrayList<>();
private ConditionManager(Context context, boolean loadConditionsNow) {
mContext = context;
mConditions = new ArrayList<>();
if (loadConditionsNow) {
Log.d(TAG, "conditions loading synchronously");
ConditionLoader loader = new ConditionLoader();
loader.onPostExecute(loader.doInBackground());
} else {
Log.d(TAG, "conditions loading asychronously");
new ConditionLoader().execute();
}
public ConditionManager(Context context, ConditionListener listener) {
mAppContext = context.getApplicationContext();
mExecutorService = Executors.newCachedThreadPool();
mCandidates = new ArrayList<>();
mCardControllers = new ArrayList<>();
mListener = listener;
initCandidates();
}
public void refreshAll() {
final int N = mConditions.size();
for (int i = 0; i < N; i++) {
mConditions.get(i).refreshState();
/**
* Returns a list of {@link ConditionalCard}s eligible for display.
*/
public List<ConditionalCard> getDisplayableCards() {
final List<ConditionalCard> cards = new ArrayList<>();
final List<Future<ConditionalCard>> displayableCards = new ArrayList<>();
// Check displayable future
for (ConditionalCard card : mCandidates) {
final DisplayableChecker future = new DisplayableChecker(
card, getController(card.getId()));
displayableCards.add(mExecutorService.submit(future));
}
}
private void readFromXml(File xmlFile, ArrayList<Condition> conditions) {
if (DEBUG) Log.d(TAG, "Reading from " + xmlFile.toString());
try {
XmlPullParser parser = Xml.newPullParser();
FileReader in = new FileReader(xmlFile);
parser.setInput(in);
int state = parser.getEventType();
while (state != XmlPullParser.END_DOCUMENT) {
if (TAG_CONDITION.equals(parser.getName())) {
int depth = parser.getDepth();
String clz = parser.getAttributeValue("", ATTR_CLASS);
if (!clz.startsWith(PKG)) {
clz = PKG + clz;
}
Condition condition = createCondition(Class.forName(clz));
PersistableBundle bundle = PersistableBundle.restoreFromXml(parser);
if (DEBUG) Log.d(TAG, "Reading " + clz + " -- " + bundle);
if (condition != null) {
condition.restoreState(bundle);
conditions.add(condition);
} else {
Log.e(TAG, "failed to add condition: " + clz);
}
while (parser.getDepth() > depth) {
parser.next();
}
// Collect future and add displayable cards
for (Future<ConditionalCard> cardFuture : displayableCards) {
try {
final ConditionalCard card = cardFuture.get(DISPLAYABLE_CHECKER_TIMEOUT_MS,
TimeUnit.MILLISECONDS);
if (card != null) {
cards.add(card);
}
state = parser.next();
}
in.close();
} catch (XmlPullParserException | IOException | ClassNotFoundException e) {
Log.w(TAG, "Problem reading " + FILE_NAME, e);
}
}
private void saveToXml() {
if (DEBUG) Log.d(TAG, "Writing to " + mXmlFile.toString());
try {
XmlSerializer serializer = Xml.newSerializer();
FileWriter writer = new FileWriter(mXmlFile);
serializer.setOutput(writer);
serializer.startDocument("UTF-8", true);
serializer.startTag("", TAG_CONDITIONS);
final int N = mConditions.size();
for (int i = 0; i < N; i++) {
PersistableBundle bundle = new PersistableBundle();
if (mConditions.get(i).saveState(bundle)) {
serializer.startTag("", TAG_CONDITION);
final String clz = mConditions.get(i).getClass().getSimpleName();
serializer.attribute("", ATTR_CLASS, clz);
bundle.saveToXml(serializer);
serializer.endTag("", TAG_CONDITION);
}
}
serializer.endTag("", TAG_CONDITIONS);
serializer.flush();
writer.close();
} catch (XmlPullParserException | IOException e) {
Log.w(TAG, "Problem writing " + FILE_NAME, e);
}
}
private void addMissingConditions(ArrayList<Condition> conditions) {
addIfMissing(AirplaneModeCondition.class, conditions);
addIfMissing(HotspotCondition.class, conditions);
addIfMissing(DndCondition.class, conditions);
addIfMissing(BatterySaverCondition.class, conditions);
addIfMissing(CellularDataCondition.class, conditions);
addIfMissing(BackgroundDataCondition.class, conditions);
addIfMissing(WorkModeCondition.class, conditions);
addIfMissing(NightDisplayCondition.class, conditions);
addIfMissing(RingerMutedCondition.class, conditions);
addIfMissing(RingerVibrateCondition.class, conditions);
Collections.sort(conditions, CONDITION_COMPARATOR);
}
private void addIfMissing(Class<? extends Condition> clz, ArrayList<Condition> conditions) {
if (getCondition(clz, conditions) == null) {
if (DEBUG) Log.d(TAG, "Adding missing " + clz.getName());
Condition condition = createCondition(clz);
if (condition != null) {
conditions.add(condition);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
Log.w(TAG, "Failed to get displayable state for card, likely timeout. Skipping", e);
}
}
return cards;
}
private Condition createCondition(Class<?> clz) {
if (AirplaneModeCondition.class == clz) {
return new AirplaneModeCondition(this);
} else if (HotspotCondition.class == clz) {
return new HotspotCondition(this);
} else if (DndCondition.class == clz) {
return new DndCondition(this);
} else if (BatterySaverCondition.class == clz) {
return new BatterySaverCondition(this);
} else if (CellularDataCondition.class == clz) {
return new CellularDataCondition(this);
} else if (BackgroundDataCondition.class == clz) {
return new BackgroundDataCondition(this);
} else if (WorkModeCondition.class == clz) {
return new WorkModeCondition(this);
} else if (NightDisplayCondition.class == clz) {
return new NightDisplayCondition(this);
} else if (RingerMutedCondition.class == clz) {
return new RingerMutedCondition(this);
} else if (RingerVibrateCondition.class == clz) {
return new RingerVibrateCondition(this);
/**
* Handler when the card is clicked.
*
* @see {@link ConditionalCardController#onPrimaryClick(Context)}
*/
public void onPrimaryClick(Context context, long id) {
getController(id).onPrimaryClick(context);
}
/**
* Handler when the card action is clicked.
*
* @see {@link ConditionalCardController#onActionClick()}
*/
public void onActionClick(long id) {
getController(id).onActionClick();
onConditionChanged();
}
/**
* Start monitoring state change for all conditions
*/
public void startMonitoringStateChange() {
if (mIsListeningToStateChange) {
Log.d(TAG, "Already listening to condition state changes, skipping");
return;
}
Log.e(TAG, "unknown condition class: " + clz.getSimpleName());
return null;
mIsListeningToStateChange = true;
for (ConditionalCardController controller : mCardControllers) {
controller.startMonitoringStateChange();
}
// Force a refresh on listener
onConditionChanged();
}
Context getContext() {
return mContext;
/**
* Stop monitoring state change for all conditions
*/
public void stopMonitoringStateChange() {
if (!mIsListeningToStateChange) {
Log.d(TAG, "Not listening to condition state changes, skipping");
return;
}
for (ConditionalCardController controller : mCardControllers) {
controller.stopMonitoringStateChange();
}
mIsListeningToStateChange = false;
}
public <T extends Condition> T getCondition(Class<T> clz) {
return getCondition(clz, mConditions);
/**
* Called when some conditional card's state has changed
*/
void onConditionChanged() {
if (mListener != null) {
mListener.onConditionsChanged();
}
}
private <T extends Condition> T getCondition(Class<T> clz, List<Condition> conditions) {
final int N = conditions.size();
for (int i = 0; i < N; i++) {
if (clz.equals(conditions.get(i).getClass())) {
return (T) conditions.get(i);
@NonNull
<T extends ConditionalCardController> T getController(long id) {
for (ConditionalCardController controller : mCardControllers) {
if (controller.getId() == id) {
return (T) controller;
}
}
return null;
throw new IllegalStateException("Cannot find controller for " + id);
}
public List<Condition> getConditions() {
return mConditions;
private void initCandidates() {
// Initialize controllers first.
mCardControllers.add(new AirplaneModeConditionController(mAppContext, this /* manager */));
mCardControllers.add(new BackgroundDataConditionController(mAppContext));
mCardControllers.add(new BatterySaverConditionController(mAppContext, this /* manager */));
mCardControllers.add(new CellularDataConditionController(mAppContext, this /* manager */));
mCardControllers.add(new DndConditionCardController(mAppContext, this /* manager */));
mCardControllers.add(new HotspotConditionController(mAppContext, this /* manager */));
mCardControllers.add(new NightDisplayConditionController(mAppContext));
mCardControllers.add(new RingerVibrateConditionController(mAppContext, this /* manager */));
mCardControllers.add(new RingerMutedConditionController(mAppContext, this /* manager */));
mCardControllers.add(new WorkModeConditionController(mAppContext));
// Initialize ui model later. UI model depends on controller.
mCandidates.add(new AirplaneModeConditionCard(mAppContext));
mCandidates.add(new BackgroundDataConditionCard(mAppContext));
mCandidates.add(new BatterySaverConditionCard(mAppContext));
mCandidates.add(new CellularDataConditionCard(mAppContext));
mCandidates.add(new DndConditionCard(mAppContext, this /* manager */));
mCandidates.add(new HotspotConditionCard(mAppContext, this /* manager */));
mCandidates.add(new NightDisplayConditionCard(mAppContext));
mCandidates.add(new RingerMutedConditionCard(mAppContext));
mCandidates.add(new RingerVibrateConditionCard(mAppContext));
mCandidates.add(new WorkModeConditionCard(mAppContext));
}
public void notifyChanged(Condition condition) {
saveToXml();
Collections.sort(mConditions, CONDITION_COMPARATOR);
final int N = mListeners.size();
for (int i = 0; i < N; i++) {
mListeners.get(i).onConditionsChanged();
}
}
/**
* Returns card if controller says it's displayable. Otherwise returns null.
*/
public static class DisplayableChecker implements Callable<ConditionalCard> {
public void addListener(ConditionListener listener) {
mListeners.add(listener);
listener.onConditionsChanged();
}
private final ConditionalCard mCard;
private final ConditionalCardController mController;
public void remListener(ConditionListener listener) {
mListeners.remove(listener);
}
@Override
public void onResume() {
for (int i = 0, size = mConditions.size(); i < size; i++) {
mConditions.get(i).onResume();
}
}
@Override
public void onPause() {
for (int i = 0, size = mConditions.size(); i < size; i++) {
mConditions.get(i).onPause();
}
}
private class ConditionLoader extends AsyncTask<Void, Void, ArrayList<Condition>> {
@Override
protected ArrayList<Condition> doInBackground(Void... params) {
Log.d(TAG, "loading conditions from xml");
ArrayList<Condition> conditions = new ArrayList<>();
mXmlFile = new File(mContext.getFilesDir(), FILE_NAME);
if (mXmlFile.exists()) {
readFromXml(mXmlFile, conditions);
}
addMissingConditions(conditions);
return conditions;
private DisplayableChecker(ConditionalCard card, ConditionalCardController controller) {
mCard = card;
mController = controller;
}
@Override
protected void onPostExecute(ArrayList<Condition> conditions) {
Log.d(TAG, "conditions loaded from xml, refreshing conditions");
mConditions.clear();
mConditions.addAll(conditions);
refreshAll();
public ConditionalCard call() throws Exception {
return mController.isDisplayable() ? mCard : null;
}
}
public static ConditionManager get(Context context) {
return get(context, true);
}
public static ConditionManager get(Context context, boolean loadConditionsNow) {
if (sInstance == null) {
sInstance = new ConditionManager(context.getApplicationContext(), loadConditionsNow);
}
return sInstance;
}
private static final Comparator<Condition> CONDITION_COMPARATOR = new Comparator<Condition>() {
@Override
public int compare(Condition lhs, Condition rhs) {
return Long.compare(lhs.getLastChange(), rhs.getLastChange());
}
};
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;

View File

@@ -1,166 +0,0 @@
/*
* Copyright (C) 2015 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.homepage.conditional;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.os.PersistableBundle;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.notification.ZenModeSettings;
/**
* @deprecated in favor of {@link com.android.settings.homepage.conditional.v2.DndConditionCard}
*/
@Deprecated
public class DndCondition extends Condition {
private static final String TAG = "DndCondition";
private static final String KEY_STATE = "state";
private boolean mRegistered;
@VisibleForTesting
static final IntentFilter DND_FILTER =
new IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL);
@VisibleForTesting
protected ZenModeConfig mConfig;
private int mZen;
private final Receiver mReceiver;
public DndCondition(ConditionManager manager) {
super(manager);
mReceiver = new Receiver();
mManager.getContext().registerReceiver(mReceiver, DND_FILTER);
mRegistered = true;
}
@Override
public void refreshState() {
NotificationManager notificationManager =
mManager.getContext().getSystemService(NotificationManager.class);
mZen = notificationManager.getZenMode();
boolean zenModeEnabled = mZen != Settings.Global.ZEN_MODE_OFF;
if (zenModeEnabled) {
mConfig = notificationManager.getZenModeConfig();
} else {
mConfig = null;
}
setActive(zenModeEnabled);
}
@Override
boolean saveState(PersistableBundle bundle) {
bundle.putInt(KEY_STATE, mZen);
return super.saveState(bundle);
}
@Override
void restoreState(PersistableBundle bundle) {
super.restoreState(bundle);
mZen = bundle.getInt(KEY_STATE, Global.ZEN_MODE_OFF);
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_do_not_disturb_on_24dp);
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getString(R.string.condition_zen_title);
}
@Override
public CharSequence getSummary() {
return ZenModeConfig.getDescription(mManager.getContext(), mZen != Global.ZEN_MODE_OFF,
mConfig, true);
}
@Override
public CharSequence[] getActions() {
return new CharSequence[] { mManager.getContext().getString(R.string.condition_turn_off) };
}
@Override
public void onPrimaryClick() {
new SubSettingLauncher(mManager.getContext())
.setDestination(ZenModeSettings.class.getName())
.setSourceMetricsCategory(MetricsEvent.DASHBOARD_SUMMARY)
.setTitleRes(R.string.zen_mode_settings_title)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.launch();
}
@Override
public void onActionClick(int index) {
if (index == 0) {
NotificationManager notificationManager = mManager.getContext().getSystemService(
NotificationManager.class);
notificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG);
setActive(false);
} else {
throw new IllegalArgumentException("Unexpected index " + index);
}
}
@Override
public int getMetricsConstant() {
return MetricsEvent.SETTINGS_CONDITION_DND;
}
public static class Receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
.equals(intent.getAction())) {
final Condition condition =
ConditionManager.get(context).getCondition(DndCondition.class);
if (condition != null) {
condition.refreshState();
}
}
}
}
@Override
public void onResume() {
if (!mRegistered) {
mManager.getContext().registerReceiver(mReceiver, DND_FILTER);
mRegistered = true;
}
}
@Override
public void onPause() {
if (mRegistered) {
mManager.getContext().unregisterReceiver(mReceiver);
mRegistered = false;
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;
@@ -25,12 +25,10 @@ import com.android.settings.R;
public class DndConditionCard implements ConditionalCard {
private final Context mAppContext;
private final ConditionManager mManager;
private final DndConditionCardController mController;
public DndConditionCard(Context appContext, ConditionManager manager) {
mAppContext = appContext;
mManager = manager;
mController = manager.getController(getId());
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;

View File

@@ -1,145 +0,0 @@
/*
* Copyright (C) 2015 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.homepage.conditional;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.UserHandle;
import android.os.UserManager;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.TetherSettings;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@Deprecated
public class HotspotCondition extends Condition {
private final WifiManager mWifiManager;
private final Receiver mReceiver;
private static final IntentFilter WIFI_AP_STATE_FILTER =
new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
public HotspotCondition(ConditionManager manager) {
super(manager);
mWifiManager = mManager.getContext().getSystemService(WifiManager.class);
mReceiver = new Receiver();
}
@Override
public void refreshState() {
boolean wifiTetherEnabled = mWifiManager.isWifiApEnabled();
setActive(wifiTetherEnabled);
}
@Override
protected BroadcastReceiver getReceiver() {
return mReceiver;
}
@Override
protected IntentFilter getIntentFilter() {
return WIFI_AP_STATE_FILTER;
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_hotspot);
}
private String getSsid() {
WifiConfiguration wifiConfig = mWifiManager.getWifiApConfiguration();
if (wifiConfig == null) {
return mManager.getContext().getString(
com.android.internal.R.string.wifi_tether_configure_ssid_default);
} else {
return wifiConfig.SSID;
}
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getString(R.string.condition_hotspot_title);
}
@Override
public CharSequence getSummary() {
return mManager.getContext().getString(R.string.condition_hotspot_summary, getSsid());
}
@Override
public CharSequence[] getActions() {
final Context context = mManager.getContext();
if (RestrictedLockUtils.hasBaseUserRestriction(context,
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId())) {
return new CharSequence[0];
}
return new CharSequence[]{context.getString(R.string.condition_turn_off)};
}
@Override
public void onPrimaryClick() {
new SubSettingLauncher(mManager.getContext())
.setDestination(TetherSettings.class.getName())
.setSourceMetricsCategory(MetricsEvent.DASHBOARD_SUMMARY)
.setTitleRes(R.string.tether_settings_title_all)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.launch();
}
@Override
public void onActionClick(int index) {
if (index == 0) {
final Context context = mManager.getContext();
final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId());
if (admin != null) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin);
} else {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
cm.stopTethering(ConnectivityManager.TETHERING_WIFI);
setActive(false);
}
} else {
throw new IllegalArgumentException("Unexpected index " + index);
}
}
@Override
public int getMetricsConstant() {
return MetricsEvent.SETTINGS_CONDITION_HOTSPOT;
}
public static class Receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) {
ConditionManager.get(context).getCondition(HotspotCondition.class)
.refreshState();
}
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.BroadcastReceiver;
import android.content.Context;

View File

@@ -1,96 +0,0 @@
/*
* Copyright (C) 2016 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.homepage.conditional;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import com.android.internal.app.ColorDisplayController;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.display.NightDisplaySettings;
/**
* @deprecated in favor of {@link NightDisplayConditionController}
*/
@Deprecated
public final class NightDisplayCondition extends Condition
implements ColorDisplayController.Callback {
private ColorDisplayController mController;
NightDisplayCondition(ConditionManager manager) {
super(manager);
mController = new ColorDisplayController(manager.getContext());
mController.setListener(this);
}
@Override
public int getMetricsConstant() {
return MetricsEvent.SETTINGS_CONDITION_NIGHT_DISPLAY;
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_settings_night_display);
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getString(R.string.condition_night_display_title);
}
@Override
public CharSequence getSummary() {
return mManager.getContext().getString(R.string.condition_night_display_summary);
}
@Override
public CharSequence[] getActions() {
return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
}
@Override
public void onPrimaryClick() {
new SubSettingLauncher(mManager.getContext())
.setDestination(NightDisplaySettings.class.getName())
.setSourceMetricsCategory(MetricsEvent.DASHBOARD_SUMMARY)
.setTitleRes(R.string.night_display_title)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.launch();
}
@Override
public void onActionClick(int index) {
if (index == 0) {
mController.setActivated(false);
} else {
throw new IllegalArgumentException("Unexpected index " + index);
}
}
@Override
public void refreshState() {
setActive(mController.isActivated());
}
@Override
public void onActivated(boolean activated) {
refreshState();
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;

View File

@@ -1,71 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.homepage.conditional;
import static android.content.Context.NOTIFICATION_SERVICE;
import android.app.NotificationManager;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.provider.Settings;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@Deprecated
public class RingerMutedCondition extends AbnormalRingerConditionBase {
private final NotificationManager mNotificationManager;
RingerMutedCondition(ConditionManager manager) {
super(manager);
mNotificationManager =
(NotificationManager) mManager.getContext().getSystemService(NOTIFICATION_SERVICE);
}
@Override
public void refreshState() {
int zen = Settings.Global.ZEN_MODE_OFF;
if (mNotificationManager != null) {
zen = mNotificationManager.getZenMode();
}
final boolean zenModeEnabled = zen != Settings.Global.ZEN_MODE_OFF;
final boolean isSilent =
mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT;
setActive(isSilent && !zenModeEnabled);
}
@Override
public int getMetricsConstant() {
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_MUTED;
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_notifications_off_24dp);
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getText(R.string.condition_device_muted_title);
}
@Override
public CharSequence getSummary() {
return mManager.getContext().getText(R.string.condition_device_muted_summary);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import static android.content.Context.NOTIFICATION_SERVICE;

View File

@@ -1,56 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.homepage.conditional;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@Deprecated
public class RingerVibrateCondition extends AbnormalRingerConditionBase {
RingerVibrateCondition(ConditionManager manager) {
super(manager);
}
@Override
public void refreshState() {
setActive(mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE);
}
@Override
public int getMetricsConstant() {
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_VIBRATE;
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_volume_ringer_vibrate);
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getText(R.string.condition_device_vibrate_title);
}
@Override
public CharSequence getSummary() {
return mManager.getContext().getText(R.string.condition_device_vibrate_summary);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.media.AudioManager;

View File

@@ -1,108 +0,0 @@
/*
* Copyright (C) 2016 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.homepage.conditional;
import android.content.Context;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.os.UserManager;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Settings;
import java.util.List;
@Deprecated
public class WorkModeCondition extends Condition {
private UserManager mUm;
private UserHandle mUserHandle;
public WorkModeCondition(ConditionManager conditionManager) {
super(conditionManager);
mUm = (UserManager) mManager.getContext().getSystemService(Context.USER_SERVICE);
}
private void updateUserHandle() {
List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId());
final int profilesCount = profiles.size();
mUserHandle = null;
for (int i = 0; i < profilesCount; i++) {
UserInfo userInfo = profiles.get(i);
if (userInfo.isManagedProfile()) {
// We assume there's only one managed profile, otherwise UI needs to change.
mUserHandle = userInfo.getUserHandle();
break;
}
}
}
@Override
public void refreshState() {
updateUserHandle();
setActive(mUserHandle != null && mUm.isQuietModeEnabled(mUserHandle));
}
@Override
public Drawable getIcon() {
return mManager.getContext().getDrawable(R.drawable.ic_signal_workmode_enable);
}
@Override
public CharSequence getTitle() {
return mManager.getContext().getString(R.string.condition_work_title);
}
@Override
public CharSequence getSummary() {
return mManager.getContext().getString(R.string.condition_work_summary);
}
@Override
public CharSequence[] getActions() {
return new CharSequence[] {
mManager.getContext().getString(R.string.condition_turn_on)
};
}
@Override
public void onPrimaryClick() {
mManager.getContext().startActivity(new Intent(mManager.getContext(),
Settings.AccountDashboardActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
@Override
public void onActionClick(int index) {
if (index == 0) {
if (mUserHandle != null) {
mUm.requestQuietModeEnabled(false, mUserHandle);
}
setActive(false);
} else {
throw new IllegalArgumentException("Unexpected index " + index);
}
}
@Override
public int getMetricsConstant() {
return MetricsEvent.SETTINGS_CONDITION_WORK_MODE;
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
package com.android.settings.homepage.conditional;
import android.content.Context;
import android.content.Intent;

View File

@@ -1,130 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardAdapter;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import java.util.List;
public class ConditionAdapter extends RecyclerView.Adapter<DashboardAdapter.DashboardItemHolder> {
private final Context mContext;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private final ConditionManager mConditionManager;
private final List<ConditionalCard> mConditions;
private final boolean mExpanded;
public ConditionAdapter(Context context, ConditionManager conditionManager,
List<ConditionalCard> conditions, boolean expanded) {
mContext = context;
mConditionManager = conditionManager;
mConditions = conditions;
mExpanded = expanded;
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
setHasStableIds(true);
}
@Override
public DashboardAdapter.DashboardItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new DashboardAdapter.DashboardItemHolder(LayoutInflater.from(parent.getContext())
.inflate(viewType, parent, false));
}
@Override
public void onBindViewHolder(DashboardAdapter.DashboardItemHolder holder, int position) {
final ConditionalCard condition = mConditions.get(position);
final boolean isLastItem = position == mConditions.size() - 1;
bindViews(condition, holder, isLastItem);
}
@Override
public long getItemId(int position) {
return mConditions.get(position).getId();
}
@Override
public int getItemViewType(int position) {
return R.layout.condition_tile;
}
@Override
public int getItemCount() {
if (mExpanded) {
return mConditions.size();
}
return 0;
}
private void bindViews(final ConditionalCard condition,
DashboardAdapter.DashboardItemHolder view, boolean isLastItem) {
mMetricsFeatureProvider.visible(mContext, MetricsProto.MetricsEvent.DASHBOARD_SUMMARY,
condition.getMetricsConstant());
view.itemView.findViewById(R.id.content).setOnClickListener(
v -> {
mMetricsFeatureProvider.action(mContext,
MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
condition.getMetricsConstant());
mConditionManager.onPrimaryClick(mContext, condition.getId());
});
view.icon.setImageDrawable(condition.getIcon());
view.title.setText(condition.getTitle());
view.summary.setText(condition.getSummary());
setViewVisibility(view.itemView, R.id.divider, !isLastItem);
final CharSequence action = condition.getActionText();
final boolean hasButtons = !TextUtils.isEmpty(action);
setViewVisibility(view.itemView, R.id.buttonBar, hasButtons);
final Button button = view.itemView.findViewById(R.id.first_action);
if (hasButtons) {
button.setVisibility(View.VISIBLE);
button.setText(action);
button.setOnClickListener(v -> {
final Context context = v.getContext();
mMetricsFeatureProvider.action(
context, MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
condition.getMetricsConstant());
mConditionManager.onActionClick(condition.getId());
});
} else {
button.setVisibility(View.GONE);
}
}
private void setViewVisibility(View containerView, int viewId, boolean visible) {
View view = containerView.findViewById(viewId);
if (view != null) {
view.setVisibility(visible ? View.VISIBLE : View.GONE);
}
}
}

View File

@@ -1,210 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.homepage.conditional.v2;
import android.content.Context;
import android.util.FeatureFlagUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.settings.core.FeatureFlags;
import com.android.settings.homepage.conditional.ConditionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ConditionManager {
private static final String TAG = "ConditionManager";
@VisibleForTesting
final List<ConditionalCard> mCandidates;
@VisibleForTesting
final List<ConditionalCardController> mCardControllers;
private static final long DISPLAYABLE_CHECKER_TIMEOUT_MS = 20;
private final ExecutorService mExecutorService;
private final Context mAppContext;
private final ConditionListener mListener;
private boolean mIsListeningToStateChange;
/**
* Whether or not the new condition manager is should be used.
*/
public static boolean isEnabled(Context context) {
return FeatureFlagUtils.isEnabled(context, FeatureFlags.CONDITION_MANAGER_V2);
}
public ConditionManager(Context context, ConditionListener listener) {
mAppContext = context.getApplicationContext();
mExecutorService = Executors.newCachedThreadPool();
mCandidates = new ArrayList<>();
mCardControllers = new ArrayList<>();
mListener = listener;
initCandidates();
}
/**
* Returns a list of {@link ConditionalCard}s eligible for display.
*/
public List<ConditionalCard> getDisplayableCards() {
final List<ConditionalCard> cards = new ArrayList<>();
final List<Future<ConditionalCard>> displayableCards = new ArrayList<>();
// Check displayable future
for (ConditionalCard card : mCandidates) {
final DisplayableChecker future = new DisplayableChecker(
card, getController(card.getId()));
displayableCards.add(mExecutorService.submit(future));
}
// Collect future and add displayable cards
for (Future<ConditionalCard> cardFuture : displayableCards) {
try {
final ConditionalCard card = cardFuture.get(DISPLAYABLE_CHECKER_TIMEOUT_MS,
TimeUnit.MILLISECONDS);
if (card != null) {
cards.add(card);
}
} catch (InterruptedException | ExecutionException | TimeoutException e) {
Log.w(TAG, "Failed to get displayable state for card, likely timeout. Skipping", e);
}
}
return cards;
}
/**
* Handler when the card is clicked.
*
* @see {@link ConditionalCardController#onPrimaryClick(Context)}
*/
public void onPrimaryClick(Context context, long id) {
getController(id).onPrimaryClick(context);
}
/**
* Handler when the card action is clicked.
*
* @see {@link ConditionalCardController#onActionClick()}
*/
public void onActionClick(long id) {
getController(id).onActionClick();
onConditionChanged();
}
/**
* Start monitoring state change for all conditions
*/
public void startMonitoringStateChange() {
if (mIsListeningToStateChange) {
Log.d(TAG, "Already listening to condition state changes, skipping");
return;
}
mIsListeningToStateChange = true;
for (ConditionalCardController controller : mCardControllers) {
controller.startMonitoringStateChange();
}
// Force a refresh on listener
onConditionChanged();
}
/**
* Stop monitoring state change for all conditions
*/
public void stopMonitoringStateChange() {
if (!mIsListeningToStateChange) {
Log.d(TAG, "Not listening to condition state changes, skipping");
return;
}
for (ConditionalCardController controller : mCardControllers) {
controller.stopMonitoringStateChange();
}
mIsListeningToStateChange = false;
}
/**
* Called when some conditional card's state has changed
*/
void onConditionChanged() {
if (mListener != null) {
mListener.onConditionsChanged();
}
}
@NonNull
<T extends ConditionalCardController> T getController(long id) {
for (ConditionalCardController controller : mCardControllers) {
if (controller.getId() == id) {
return (T) controller;
}
}
throw new IllegalStateException("Cannot find controller for " + id);
}
private void initCandidates() {
// Initialize controllers first.
mCardControllers.add(new AirplaneModeConditionController(mAppContext, this /* manager */));
mCardControllers.add(new BackgroundDataConditionController(mAppContext));
mCardControllers.add(new BatterySaverConditionController(mAppContext, this /* manager */));
mCardControllers.add(new CellularDataConditionController(mAppContext, this /* manager */));
mCardControllers.add(new DndConditionCardController(mAppContext, this /* manager */));
mCardControllers.add(new HotspotConditionController(mAppContext, this /* manager */));
mCardControllers.add(new NightDisplayConditionController(mAppContext));
mCardControllers.add(new RingerVibrateConditionController(mAppContext, this /* manager */));
mCardControllers.add(new RingerMutedConditionController(mAppContext, this /* manager */));
mCardControllers.add(new WorkModeConditionController(mAppContext));
// Initialize ui model later. UI model depends on controller.
mCandidates.add(new AirplaneModeConditionCard(mAppContext));
mCandidates.add(new BackgroundDataConditionCard(mAppContext));
mCandidates.add(new BatterySaverConditionCard(mAppContext));
mCandidates.add(new CellularDataConditionCard(mAppContext));
mCandidates.add(new DndConditionCard(mAppContext, this /* manager */));
mCandidates.add(new HotspotConditionCard(mAppContext, this /* manager */));
mCandidates.add(new NightDisplayConditionCard(mAppContext));
mCandidates.add(new RingerMutedConditionCard(mAppContext));
mCandidates.add(new RingerVibrateConditionCard(mAppContext));
mCandidates.add(new WorkModeConditionCard(mAppContext));
}
/**
* Returns card if controller says it's displayable. Otherwise returns null.
*/
public static class DisplayableChecker implements Callable<ConditionalCard> {
private final ConditionalCard mCard;
private final ConditionalCardController mController;
private DisplayableChecker(ConditionalCard card, ConditionalCardController controller) {
mCard = card;
mController = controller;
}
@Override
public ConditionalCard call() throws Exception {
return mController.isDisplayable() ? mCard : null;
}
}
}

View File

@@ -27,6 +27,8 @@ import android.provider.SearchIndexableResource;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.Preconditions;
import com.android.settings.R;
@@ -42,8 +44,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import androidx.preference.Preference;
@SearchIndexable
public final class VirtualKeyboardFragment extends SettingsPreferenceFragment implements Indexable {
@@ -130,12 +130,5 @@ public final class VirtualKeyboardFragment extends SettingsPreferenceFragment im
sir.xmlResId = R.xml.virtual_keyboard_settings;
return Arrays.asList(sir);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
keys.add("add_virtual_keyboard_screen");
return keys;
}
};
}

View File

@@ -23,12 +23,13 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.speech.tts.TtsEngines;
import android.text.TextUtils;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -41,6 +42,7 @@ import com.android.settings.widget.PreferenceCategoryController;
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;
@@ -53,7 +55,6 @@ public class LanguageAndInputSettings extends DashboardFragment {
private static final String KEY_KEYBOARDS_CATEGORY = "keyboards_category";
private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
private static final String KEY_POINTER_AND_TTS_CATEGORY = "pointer_and_tts_category";
private static final String KEY_PHYSICAL_KEYBOARD = "physical_keyboard_pref";
@Override
public int getMetricsCategory() {
@@ -175,13 +176,5 @@ public class LanguageAndInputSettings extends DashboardFragment {
Context context) {
return buildPreferenceControllers(context, null);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
// Duplicates in summary and details pages.
keys.add(KEY_PHYSICAL_KEYBOARD);
return keys;
}
};
}

View File

@@ -22,6 +22,9 @@ import android.location.SettingInjectorService;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -41,9 +44,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
/**
* System location settings (Settings &gt; Location). The screen has three parts:
* <ul>
@@ -180,12 +180,5 @@ public class LocationSettings extends DashboardFragment {
return buildPreferenceControllers(context, null /* fragment */,
null /* lifecycle */);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> niks = super.getNonIndexableKeys(context);
niks.add("recent_location_requests_see_all_button"); // 'See all' button
return niks;
}
};
}

View File

@@ -67,12 +67,18 @@ public class AppNotificationSettings extends NotificationSettingsBase {
// if showing legacy settings, pull advanced settings out of the advanced category
Preference badge = findPreference(KEY_BADGE);
Preference appLink = findPreference(KEY_APP_LINK);
PreferenceGroup advanced = (PreferenceGroup) findPreference(KEY_ADVANCED_CATEGORY);
removePreference(KEY_ADVANCED_CATEGORY);
if (badge != null) {
if (advanced != null) {
advanced.removePreference(badge);
}
screen.addPreference(badge);
}
if (appLink != null) {
if (advanced != null) {
advanced.removePreference(appLink);
}
screen.addPreference(appLink);
}
}

View File

@@ -218,9 +218,6 @@ public class ConfigureNotificationSettings extends DashboardFragment implements
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
keys.add(KEY_SWIPE_DOWN);
keys.add(KEY_LOCKSCREEN);
keys.add(KEY_LOCKSCREEN_WORK_PROFILE);
keys.add(KEY_LOCKSCREEN_WORK_PROFILE_HEADER);
return keys;
}
};

View File

@@ -108,12 +108,6 @@ public class ZenModeBlockedEffectsSettings extends ZenModeSettingsBase implement
return result;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
return keys;
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, null);

View File

@@ -82,14 +82,9 @@ public class ZenModeCallsSettings extends ZenModeSettingsBase implements Indexab
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
return keys;
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, null);
}
};
};
}

View File

@@ -80,12 +80,6 @@ public class ZenModeMsgEventReminderSettings extends ZenModeSettingsBase impleme
return result;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
return keys;
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, null);

View File

@@ -90,12 +90,6 @@ public class ZenModeRestrictNotificationsSettings extends ZenModeSettingsBase im
return result;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
return keys;
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, null);

View File

@@ -154,8 +154,6 @@ public class LockscreenDashboardFragment extends DashboardFragment
public List<String> getNonIndexableKeys(Context context) {
final List<String> niks = super.getNonIndexableKeys(context);
niks.add(KEY_ADD_USER_FROM_LOCK_SCREEN);
niks.add(KEY_LOCK_SCREEN_NOTIFICATON_WORK_PROFILE);
niks.add(KEY_LOCK_SCREEN_NOTIFICATON_WORK_PROFILE_HEADER);
return niks;
}

View File

@@ -20,6 +20,8 @@ import android.content.Context;
import android.os.UserHandle;
import android.provider.SearchIndexableResource;
import androidx.fragment.app.Fragment;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
@@ -34,16 +36,12 @@ import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.List;
import androidx.fragment.app.Fragment;
@SearchIndexable
public class ScreenLockSettings extends DashboardFragment
implements OwnerInfoPreferenceController.OwnerInfoCallback {
private static final String TAG = "ScreenLockSettings";
private static final String KEY_LOCK_SCREEN_TITLE = "security_settings_password_sub_screen";
private static final int MY_USER_ID = UserHandle.myUserId();
private LockPatternUtils mLockPatternUtils;
@@ -107,12 +105,5 @@ public class ScreenLockSettings extends DashboardFragment
return buildPreferenceControllers(context, null /* parent */,
null /* lifecycle */, new LockPatternUtils(context));
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
keys.add(KEY_LOCK_SCREEN_TITLE);
return keys;
}
};
}

View File

@@ -29,7 +29,7 @@ public class ResetPreferenceController extends BasePreferenceController {
@Override
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_reset_dashboard)
? AVAILABLE
? AVAILABLE_UNSEARCHABLE
: UNSUPPORTED_ON_DEVICE;
}
}

View File

@@ -19,9 +19,12 @@ import android.content.Context;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.backup.BackupSettingsActivityPreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
@@ -30,10 +33,6 @@ import com.android.settingslib.search.SearchIndexable;
import java.util.Arrays;
import java.util.List;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
@SearchIndexable
public class SystemDashboardFragment extends DashboardFragment {
@@ -97,12 +96,5 @@ public class SystemDashboardFragment extends DashboardFragment {
sir.xmlResId = R.xml.system_dashboard_fragment;
return Arrays.asList(sir);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
keys.add(KEY_RESET);
return keys;
}
};
}

View File

@@ -34,6 +34,10 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -56,10 +60,6 @@ import java.util.MissingResourceException;
import java.util.Objects;
import java.util.Set;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
@SearchIndexable
public class TextToSpeechSettings extends SettingsPreferenceFragment
implements Preference.OnPreferenceChangeListener,
@@ -790,13 +790,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment
sir.xmlResId = R.xml.tts_settings;
return Arrays.asList(sir);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
keys.add("tts_engine_preference");
return keys;
}
};
}

View File

@@ -122,6 +122,7 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings {
// unlikely, as we are iterating over live services.
Log.e(TAG, "can't find package name", e);
}
final String finalTitle = title.toString();
final String summary = service.loadLabel(mPm).toString();
final SwitchPreference pref = new AppSwitchPreference(getPrefContext());
pref.setPersistent(false);
@@ -142,7 +143,7 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings {
}
pref.setOnPreferenceChangeListener((preference, newValue) -> {
final boolean enable = (boolean) newValue;
return setEnabled(cn, summary, enable);
return setEnabled(cn, finalTitle, enable);
});
pref.setKey(cn.flattenToString());
screen.addPreference(pref);

View File

@@ -16,6 +16,7 @@
package com.android.settings.accounts;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
import static com.google.common.truth.Truth.assertThat;
@@ -65,7 +66,7 @@ public class AccountDetailDashboardFragmentTest {
public void setUp() {
mContext = RuntimeEnvironment.application;
mActivityInfo = new ActivityInfo();
mActivityInfo.packageName = "pkg";
mActivityInfo.packageName = mContext.getPackageName();
mActivityInfo.name = "clazz";
mActivityInfo.metaData = new Bundle();
@@ -123,6 +124,7 @@ public class AccountDetailDashboardFragmentTest {
mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key");
mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT);
mActivityInfo.metaData.putString(METADATA_ACCOUNT_TYPE, "com.abc");
mActivityInfo.metaData.putString(META_DATA_PREFERENCE_TITLE, "summary");
mActivityInfo.metaData.putString("com.android.settings.intent.action",
Intent.ACTION_ASSIST);
tile.userHandle = null;

View File

@@ -17,6 +17,7 @@
package com.android.settings.backup;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -25,6 +26,8 @@ import android.app.backup.BackupManager;
import android.content.Context;
import android.os.UserManager;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -38,8 +41,6 @@ import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import androidx.preference.Preference;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = BackupSettingsActivityPreferenceControllerTest.ShadowBackupManager.class)
public class BackupSettingsActivityPreferenceControllerTest {
@@ -63,7 +64,7 @@ public class BackupSettingsActivityPreferenceControllerTest {
mContext = spy(RuntimeEnvironment.application.getApplicationContext());
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
mController = new BackupSettingsActivityPreferenceController(mContext);
mController = new BackupSettingsActivityPreferenceController(mContext, KEY_BACKUP_SETTINGS);
}
@Test

View File

@@ -15,9 +15,11 @@
*/
package com.android.settings.connecteddevice;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
@@ -29,6 +31,11 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.bluetooth.AvailableMediaBluetoothDeviceUpdater;
import com.android.settings.dashboard.DashboardFragment;
@@ -48,11 +55,6 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {
ShadowAudioManager.class,
@@ -177,7 +179,7 @@ public class AvailableMediaDeviceGroupControllerTest {
doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
assertThat(mAvailableMediaDeviceGroupController.getAvailabilityStatus()).isEqualTo(
AVAILABLE);
AVAILABLE_UNSEARCHABLE);
}
@Test

View File

@@ -15,9 +15,11 @@
*/
package com.android.settings.connecteddevice;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@@ -27,6 +29,11 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import com.android.settings.bluetooth.ConnectedBluetoothDeviceUpdater;
import com.android.settings.connecteddevice.dock.DockUpdater;
import com.android.settings.connecteddevice.usb.ConnectedUsbDeviceUpdater;
@@ -44,11 +51,6 @@ import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplicationPackageManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = ShadowApplicationPackageManager.class)
public class ConnectedDeviceGroupControllerTest {
@@ -94,7 +96,7 @@ public class ConnectedDeviceGroupControllerTest {
}
@Test
public void testOnDeviceAdded_firstAdd_becomeVisibleAndPreferenceAdded() {
public void onDeviceAdded_firstAdd_becomeVisibleAndPreferenceAdded() {
mConnectedDeviceGroupController.onDeviceAdded(mPreference);
assertThat(mPreferenceGroup.isVisible()).isTrue();
@@ -102,7 +104,7 @@ public class ConnectedDeviceGroupControllerTest {
}
@Test
public void testOnDeviceRemoved_lastRemove_becomeInvisibleAndPreferenceRemoved() {
public void onDeviceRemoved_lastRemove_becomeInvisibleAndPreferenceRemoved() {
mPreferenceGroup.addPreference(mPreference);
mConnectedDeviceGroupController.onDeviceRemoved(mPreference);
@@ -112,7 +114,7 @@ public class ConnectedDeviceGroupControllerTest {
}
@Test
public void testOnDeviceRemoved_notLastRemove_stillVisible() {
public void onDeviceRemoved_notLastRemove_stillVisible() {
mPreferenceGroup.setVisible(true);
mPreferenceGroup.addPreference(mPreference);
mPreferenceGroup.addPreference(new Preference(mContext));
@@ -123,7 +125,7 @@ public class ConnectedDeviceGroupControllerTest {
}
@Test
public void testDisplayPreference_becomeInvisible() {
public void displayPreference_becomeInvisible() {
doReturn(mPreferenceGroup).when(mPreferenceScreen).findPreference(anyString());
mConnectedDeviceGroupController.displayPreference(mPreferenceScreen);
@@ -132,7 +134,7 @@ public class ConnectedDeviceGroupControllerTest {
}
@Test
public void testRegister() {
public void onStart_shouldRegisterUpdaters() {
// register the callback in onStart()
mConnectedDeviceGroupController.onStart();
verify(mConnectedBluetoothDeviceUpdater).registerCallback();
@@ -141,7 +143,7 @@ public class ConnectedDeviceGroupControllerTest {
}
@Test
public void testUnregister() {
public void onStop_shouldUnregisterUpdaters() {
// unregister the callback in onStop()
mConnectedDeviceGroupController.onStop();
verify(mConnectedBluetoothDeviceUpdater).unregisterCallback();
@@ -150,7 +152,7 @@ public class ConnectedDeviceGroupControllerTest {
}
@Test
public void testGetAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
public void getAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, false);
assertThat(mConnectedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
@@ -158,10 +160,10 @@ public class ConnectedDeviceGroupControllerTest {
}
@Test
public void testGetAvailabilityStatus_BluetoothFeature_returnSupported() {
public void getAvailabilityStatus_BluetoothFeature_returnSupported() {
mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, true);
assertThat(mConnectedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
AVAILABLE);
AVAILABLE_UNSEARCHABLE);
}
}

View File

@@ -263,9 +263,10 @@ public class PreferenceXmlParserUtilsTest {
}
@Test
@Config(qualifiers = "mcc998")
public void extractMetadata_requestSearchable_shouldDefaultToTrue() throws Exception {
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
R.xml.display_settings, MetadataFlag.FLAG_NEED_SEARCHABLE);
R.xml.location_settings, MetadataFlag.FLAG_NEED_SEARCHABLE);
for (Bundle bundle : metadata) {
assertThat(bundle.getBoolean(METADATA_SEARCHABLE)).isTrue();
}

View File

@@ -15,6 +15,8 @@
*/
package com.android.settings.dashboard;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -45,8 +47,9 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.homepage.conditional.Condition;
import com.android.settings.dashboard.suggestions.SuggestionAdapter;
import com.android.settings.homepage.conditional.ConditionManager;
import com.android.settings.homepage.conditional.ConditionalCard;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
@@ -75,26 +78,27 @@ public class DashboardAdapterTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private SettingsActivity mContext;
@Mock
private View mView;
@Mock
private Condition mCondition;
private ConditionalCard mCondition;
@Mock
private Resources mResources;
@Mock
private WindowManager mWindowManager;
@Mock
private ConditionManager mConditionManager;
private ActivityInfo mActivityInfo;
private FakeFeatureFactory mFactory;
private DashboardAdapter mDashboardAdapter;
private List<Condition> mConditionList;
private List<ConditionalCard> mConditionList;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mFactory = FakeFeatureFactory.setupForTest();
FakeFeatureFactory.setupForTest();
mActivityInfo = new ActivityInfo();
mActivityInfo.packageName = "pkg";
mActivityInfo.name = "class";
mActivityInfo.metaData = new Bundle();
mActivityInfo.metaData.putString(META_DATA_PREFERENCE_TITLE, "test-title");
when(mContext.getSystemService(Context.WINDOW_SERVICE)).thenReturn(mWindowManager);
when(mContext.getResources()).thenReturn(mResources);
@@ -102,18 +106,15 @@ public class DashboardAdapterTest {
mConditionList = new ArrayList<>();
mConditionList.add(mCondition);
when(mCondition.shouldShow()).thenReturn(true);
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
mConditionList, null /* conditionManager */,
null /* suggestionControllerMixin */, null /* lifecycle */);
when(mView.getTag()).thenReturn(mCondition);
mConditionManager, null /* suggestionControllerMixin */, null /* lifecycle */);
}
@Test
public void onSuggestionClosed_notOnlySuggestion_updateSuggestionOnly() {
final DashboardAdapter adapter =
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* conditionManager */,
mConditionManager,
null /* suggestionControllerMixin */,
null /* lifecycle */));
final List<Suggestion> suggestions = makeSuggestions("pkg1", "pkg2", "pkg3");
@@ -146,7 +147,7 @@ public class DashboardAdapterTest {
public void onSuggestionClosed_onlySuggestion_updateDashboardData() {
final DashboardAdapter adapter =
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* conditionManager */,
mConditionManager,
null /* suggestionControllerMixin */, null /* lifecycle */));
final List<Suggestion> suggestions = makeSuggestions("pkg1");
adapter.setSuggestions(suggestions);
@@ -163,7 +164,7 @@ public class DashboardAdapterTest {
public void onSuggestionClosed_notInSuggestionList_shouldNotUpdateSuggestionList() {
final DashboardAdapter adapter =
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* conditionManager */,
mConditionManager,
null /* suggestionControllerMixin */, null /* lifecycle */));
final List<Suggestion> suggestions = makeSuggestions("pkg1");
adapter.setSuggestions(suggestions);
@@ -178,8 +179,7 @@ public class DashboardAdapterTest {
@Test
public void onBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* conditionManager */,
null /* suggestionControllerMixin */, null /* lifecycle */);
mConditionManager, null /* suggestionControllerMixin */, null /* lifecycle */);
final List<Suggestion> suggestions = makeSuggestions("pkg1");
mDashboardAdapter.setSuggestions(suggestions);
@@ -215,8 +215,7 @@ public class DashboardAdapterTest {
.thenReturn(context.getDrawable(R.drawable.ic_settings));
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
null /* conditions */, null /* conditionManager */,
null /* suggestionControllerMixin */, null /* lifecycle */);
mConditionManager, null /* suggestionControllerMixin */, null /* lifecycle */);
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
mDashboardAdapter.onBindTile(holder, tile);
@@ -236,7 +235,7 @@ public class DashboardAdapterTest {
final IconCache iconCache = new IconCache(context);
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
null /* conditions */, null /* conditionManager */,
mConditionManager,
null /* suggestionControllerMixin */, null /* lifecycle */);
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
@@ -261,8 +260,7 @@ public class DashboardAdapterTest {
when(iconCache.getIcon(tile.getIcon(context))).thenReturn(mock(RoundedHomepageIcon.class));
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
null /* conditions */, null /* conditionManager */,
null /* suggestionControllerMixin */, null /* lifecycle */);
mConditionManager, null /* suggestionControllerMixin */, null /* lifecycle */);
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
mDashboardAdapter.onBindTile(holder, tile);

View File

@@ -33,8 +33,8 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListUpdateCallback;
import com.android.settings.homepage.conditional.AirplaneModeCondition;
import com.android.settings.homepage.conditional.Condition;
import com.android.settings.homepage.conditional.AirplaneModeConditionCard;
import com.android.settings.homepage.conditional.ConditionalCard;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.DashboardCategory;
@@ -49,13 +49,12 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@RunWith(SettingsRobolectricTestRunner.class)
public class DashboardDataTest {
private static final String TEST_SUGGESTION_TITLE = "Use fingerprint";
private static final String TEST_CATEGORY_TILE_TITLE = "Display";
private static final int TEST_TILE_ID = 12345;
private DashboardData mDashboardDataWithOneConditions;
private DashboardData mDashboardDataWithTwoConditions;
@@ -64,9 +63,9 @@ public class DashboardDataTest {
@Mock
private Tile mTestCategoryTile;
@Mock
private Condition mTestCondition;
private ConditionalCard mTestCondition;
@Mock
private Condition mSecondCondition; // condition used to test insert in DiffUtil
private ConditionalCard mSecondCondition; // condition used to test insert in DiffUtil
private Suggestion mTestSuggestion;
@Before
@@ -84,18 +83,16 @@ public class DashboardDataTest {
suggestions.add(mTestSuggestion);
// Build oneItemConditions
final List<Condition> oneItemConditions = new ArrayList<>();
when(mTestCondition.shouldShow()).thenReturn(true);
final List<ConditionalCard> oneItemConditions = new ArrayList<>();
oneItemConditions.add(mTestCondition);
// Build twoItemConditions
final List<Condition> twoItemsConditions = new ArrayList<>();
when(mSecondCondition.shouldShow()).thenReturn(true);
final List<ConditionalCard> twoItemsConditions = new ArrayList<>();
twoItemsConditions.add(mTestCondition);
twoItemsConditions.add(mSecondCondition);
// Build category
mTestCategoryTile.title = TEST_CATEGORY_TILE_TITLE;
when(mTestCategoryTile.getId()).thenReturn(TEST_TILE_ID);
mDashboardCategory.addTile(mTestCategoryTile);
@@ -132,7 +129,7 @@ public class DashboardDataTest {
assertThat(items.get(1).id).isEqualTo(STABLE_ID_SUGGESTION_CONDITION_DIVIDER);
assertThat(items.get(2).id).isEqualTo(STABLE_ID_CONDITION_CONTAINER);
assertThat(items.get(3).id).isEqualTo(STABLE_ID_CONDITION_FOOTER);
assertThat(items.get(4).id).isEqualTo(Objects.hash(mTestCategoryTile.title));
assertThat(items.get(4).id).isEqualTo(TEST_TILE_ID);
}
@Test
@@ -171,7 +168,7 @@ public class DashboardDataTest {
@Test
public void testGetPositionByEntity_notExisted_returnNotFound() {
final Condition condition = mock(AirplaneModeCondition.class);
final ConditionalCard condition = mock(AirplaneModeConditionCard.class);
final int position = mDashboardDataWithOneConditions.getPositionByEntity(condition);
assertThat(position).isEqualTo(DashboardData.POSITION_NOT_FOUND);
}
@@ -185,15 +182,17 @@ public class DashboardDataTest {
@Test
public void testGetPositionByTile_equalTitle_returnPositionFound() {
final Tile tile = mock(Tile.class);
tile.title = TEST_CATEGORY_TILE_TITLE;
when(tile.getId()).thenReturn(TEST_TILE_ID);
final int position = mDashboardDataWithOneConditions.getPositionByTile(tile);
assertThat(position).isNotEqualTo(DashboardData.POSITION_NOT_FOUND);
}
@Test
public void testGetPositionByTile_notExisted_returnNotFound() {
final Tile tile = mock(Tile.class);
tile.title = "";
when(tile.getId()).thenReturn(123);
final int position = mDashboardDataWithOneConditions.getPositionByTile(tile);
assertThat(position).isEqualTo(DashboardData.POSITION_NOT_FOUND);
}
@@ -226,8 +225,8 @@ public class DashboardDataTest {
testResultData.add(new ListUpdateResult.ResultData(
ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 2, 1));
// Build DashboardData
final List<Condition> oneItemConditions = new ArrayList<>();
when(mTestCondition.shouldShow()).thenReturn(true);
final List<ConditionalCard> oneItemConditions = new ArrayList<>();
oneItemConditions.add(mTestCondition);
final List<Suggestion> suggestions = new ArrayList<>();
suggestions.add(mTestSuggestion);

Some files were not shown because too many files have changed in this diff Show More