Snap for 5117548 from 16340ce52d to qt-release

Change-Id: Idb278814b9104579c2b40cbcc1cbb5522f4dc2c9
This commit is contained in:
android-build-team Robot
2018-11-08 04:01:22 +00:00
48 changed files with 1083 additions and 430 deletions

Binary file not shown.

View File

@@ -8,12 +8,24 @@ message ContextualCardList {
}
message ContextualCard {
// Slice uri of the contextual card
/**
* The category of a card: this is a hint for how a card should be collected,
* ranked, and presented
*/
enum Category {
DEFAULT = 0;
SUGGESTION = 1;
POSSIBLE = 2;
IMPORTANT = 3;
EXCLUSIVE = 4;
}
/** Slice uri of the contextual card */
optional string sliceUri = 1;
// {@link ContextualCardCategory}.
optional int32 category = 2;
// Name of the card. It should be identical in every app
/** Name of the card. It should be identical in every app */
optional string cardName = 3;
}
optional Category card_category = 4;
}

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/ContextualCardStyle">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="@dimen/homepage_condition_full_card_height"
android:paddingStart="@dimen/homepage_card_padding_start"
android:paddingEnd="@dimen/homepage_card_padding_end"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:id="@android:id/icon"
android:layout_width="@dimen/suggestion_card_icon_size"
android:layout_height="@dimen/suggestion_card_icon_size"
android:tint="?android:attr/colorAccent"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="@dimen/homepage_condition_full_card_padding_start"
android:paddingEnd="@dimen/homepage_condition_full_card_padding_end"
android:orientation="vertical">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/homepage_condition_card_title_margin_bottom"
style="@style/TextAppearance.ConditionCardTitle"/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.ConditionCardSummary"/>
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="@dimen/homepage_condition_full_card_divider_width"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/homepage_condition_full_card_divider_padding_top"
android:layout_marginBottom="@dimen/homepage_condition_full_card_divider_padding_bottom"
android:background="?android:attr/dividerVertical" />
<Button
android:id="@+id/first_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/ConditionFullCardBorderlessButton"/>
</LinearLayout>
</androidx.cardview.widget.CardView>

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/homepage_condition_half_card_height"
style="@style/ContextualCardStyle">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/homepage_card_padding_start"
android:paddingEnd="@dimen/homepage_card_padding_end"
android:paddingTop="@dimen/homepage_condition_half_card_padding_top"
android:orientation="vertical">
<ImageView
android:id="@android:id/icon"
android:layout_width="@dimen/suggestion_card_icon_size"
android:layout_height="@dimen/suggestion_card_icon_size"
android:tint="?android:attr/colorAccent"/>
<TextView
android:id="@android:id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/homepage_condition_half_card_title_margin_top"
android:layout_marginBottom="@dimen/homepage_condition_card_title_margin_bottom"
style="@style/TextAppearance.ConditionCardTitle"/>
<TextView
android:id="@android:id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.ConditionCardSummary"/>
<include layout="@layout/horizontal_divider"/>
<Button
android:id="@+id/first_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/ConditionHalfCardBorderlessButton"/>
</LinearLayout>
</androidx.cardview.widget.CardView>

View File

@@ -1,97 +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.
-->
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/ContextualCardStyle">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/condition_header_height"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal">
<ImageView
android:id="@android:id/icon"
android:layout_width="@dimen/suggestion_card_icon_size"
android:layout_height="@dimen/suggestion_card_icon_size"
android:layout_marginTop="12dp"
android:layout_marginStart="14dp"
android:layout_marginEnd="24dp"
android:tint="?android:attr/colorAccent"/>
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"/>
</LinearLayout>
<TextView
android:id="@android:id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="62dp"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingBottom="8dp"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:alpha=".7"
android:textColor="?android:attr/textColorPrimary"/>
<androidx.appcompat.widget.ButtonBarLayout
android:id="@+id/buttonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="62dp"
android:paddingBottom="1dp"
style="?android:attr/buttonBarStyle"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
<Button
android:id="@+id/first_action"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="0dp"
android:alpha=".8"
android:textAlignment="viewStart"
android:textColor="?android:attr/textColorPrimary"
style="?android:attr/buttonBarButtonStyle"/>
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</androidx.appcompat.widget.ButtonBarLayout>
<include layout="@layout/horizontal_divider"/>
</LinearLayout>
</androidx.cardview.widget.CardView>

View File

@@ -346,6 +346,16 @@
<!-- Signal icon in NetworkSelectSetting -->
<dimen name="signal_strength_icon_size">24dp</dimen>
<!-- Condition cards size and padding -->
<dimen name="homepage_condition_card_title_margin_bottom">2dp</dimen>
<dimen name="homepage_condition_half_card_height">150dp</dimen>
<dimen name="homepage_condition_half_card_padding_top">12dp</dimen>
<dimen name="homepage_condition_half_card_title_margin_top">12dp</dimen>
<dimen name="homepage_condition_full_card_height">72dp</dimen>
<dimen name="homepage_condition_full_card_padding_start">24dp</dimen>
<dimen name="homepage_condition_full_card_padding_end">24dp</dimen>
<dimen name="homepage_condition_full_card_divider_width">.75dp</dimen>
<dimen name="homepage_condition_full_card_divider_padding_top">12dp</dimen>
<dimen name="homepage_condition_full_card_divider_padding_bottom">12dp</dimen>
</resources>

View File

@@ -10060,7 +10060,7 @@
<!-- Title for prevent ringing gesture screen -->
<string name="gesture_prevent_ringing_screen_title">Prevent ringing</string>
<!-- Title for prevent ringing setting -->
<string name="gesture_prevent_ringing_title">Press Power &amp; Volume Up together</string>
<string name="gesture_prevent_ringing_title">Press Power &amp; Volume Up together to</string>
<!-- Title for prevent ringing setting -->
<string name="gesture_prevent_ringing_sound_title">Shortcut to prevent ringing</string>
<!-- Option for prevent ringing setting -->

View File

@@ -308,6 +308,16 @@
<item name="android:textColor">?android:attr/colorAccent</item>
</style>
<style name="TextAppearance.ConditionCardTitle"
parent="@android:style/TextAppearance.Material.Body2">
<item name="android:textSize">16sp</item>
</style>
<style name="TextAppearance.ConditionCardSummary"
parent="@android:style/TextAppearance.Material.Body1">
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
<style name="TextAppearance.EntityHeaderTitle"
parent="@android:style/TextAppearance.Material.Subhead">
<item name="android:textColor">?android:attr/textColorPrimary</item>
@@ -463,4 +473,24 @@
<item name="cardElevation">@dimen/homepage_card_elevation</item>
</style>
<style name="ConditionCardBorderlessButton"
parent="android:Widget.DeviceDefault.Button.Borderless">
<item name="android:textColor">?android:attr/colorAccent</item>
<item name="android:textSize">14sp</item>
<item name="android:textAllCaps">false</item>
<item name="android:fontFamily">sans-serif-medium</item>
</style>
<style name="ConditionHalfCardBorderlessButton"
parent="@style/ConditionCardBorderlessButton">
<item name="android:textAlignment">viewStart</item>
<item name="android:paddingStart">0dp</item>
</style>
<style name="ConditionFullCardBorderlessButton"
parent="@style/ConditionCardBorderlessButton">
<item name="android:textAlignment">viewEnd</item>
<item name="android:paddingEnd">0dp</item>
</style>
</resources>

View File

@@ -26,13 +26,8 @@
app:animation="@raw/gesture_prevent_ringing"
app:preview="@drawable/gesture_prevent_ringing" />
<ListPreference
android:key="gesture_prevent_ringing"
android:title="@string/gesture_prevent_ringing_title"
android:entries="@array/gesture_prevent_ringing_entries"
android:entryValues="@array/gesture_prevent_ringing_values"
app:controller="com.android.settings.gestures.PreventRingingPreferenceController"
app:keywords="@string/keywords_gesture"
app:allowDividerAbove="true" />
<PreferenceCategory
android:key="gesture_prevent_ringing_category"
android:title="@string/gesture_prevent_ringing_title">
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -979,4 +979,14 @@ public final class Utils extends com.android.settingslib.Utils {
return packageManager.getDefaultActivityIcon();
}
}
/** Returns true if the current package is installed & enabled. */
public static boolean isPackageEnabled(Context context, String packageName) {
try {
return context.getPackageManager().getApplicationInfo(packageName, 0).enabled;
} catch (Exception e) {
Log.e(TAG, "Error while retrieving application info for package " + packageName, e);
}
return false;
}
}

View File

@@ -20,8 +20,6 @@ import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import androidx.annotation.NonNull;
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
@@ -31,6 +29,8 @@ import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
public class GesturesSettingPreferenceController extends BasePreferenceController {
private final AssistGestureFeatureProvider mFeatureProvider;
private List<AbstractPreferenceController> mGestureControllers;
@@ -76,7 +76,7 @@ public class GesturesSettingPreferenceController extends BasePreferenceControlle
.setConfig(ambientDisplayConfiguration));
controllers.add(new DoubleTapScreenPreferenceController(context, FAKE_PREF_KEY)
.setConfig(ambientDisplayConfiguration));
controllers.add(new PreventRingingPreferenceController(context, FAKE_PREF_KEY));
controllers.add(new PreventRingingParentPreferenceController(context, FAKE_PREF_KEY));
return controllers;
}

View File

@@ -0,0 +1,222 @@
/*
* 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.gestures;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.widget.RadioButtonPreference;
import com.android.settings.widget.VideoPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
public class PreventRingingGesturePreferenceController extends AbstractPreferenceController
implements RadioButtonPreference.OnClickListener, LifecycleObserver, OnSaveInstanceState,
OnResume, OnPause, OnCreate, PreferenceControllerMixin {
@VisibleForTesting static final String KEY_VIBRATE = "prevent_ringing_option_vibrate";
@VisibleForTesting static final String KEY_NONE = "prevent_ringing_option_none";
@VisibleForTesting static final String KEY_MUTE = "prevent_ringing_option_mute";
private final String KEY_VIDEO_PAUSED = "key_video_paused";
private final String PREF_KEY_VIDEO = "gesture_prevent_ringing_video";
private final String KEY = "gesture_prevent_ringing_category";
private final Context mContext;
private VideoPreference mVideoPreference;
private boolean mVideoPaused;
private PreferenceCategory mPreferenceCategory;
@VisibleForTesting RadioButtonPreference mVibratePref;
@VisibleForTesting RadioButtonPreference mNonePref;
@VisibleForTesting RadioButtonPreference mMutePref;
private SettingObserver mSettingObserver;
public PreventRingingGesturePreferenceController(Context context, Lifecycle lifecycle) {
super(context);
mContext = context;
if (lifecycle != null) {
lifecycle.addObserver(this);
}
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
if (isAvailable()) {
mPreferenceCategory = (PreferenceCategory) screen.findPreference(getPreferenceKey());
mVibratePref = makeRadioPreference(KEY_VIBRATE, R.string.prevent_ringing_option_vibrate);
mMutePref = makeRadioPreference(KEY_MUTE, R.string.prevent_ringing_option_mute);
mNonePref = makeRadioPreference(KEY_NONE, R.string.prevent_ringing_option_none);
if (mPreferenceCategory != null) {
mSettingObserver = new SettingObserver(mPreferenceCategory);
}
mVideoPreference = (VideoPreference) screen.findPreference(getVideoPrefKey());
}
}
@Override
public boolean isAvailable() {
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled);
}
@Override
public String getPreferenceKey() {
return KEY;
}
public String getVideoPrefKey() {
return PREF_KEY_VIDEO;
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean(KEY_VIDEO_PAUSED, mVideoPaused);
}
@Override
public void onRadioButtonClicked(RadioButtonPreference preference) {
int preventRingingSetting = keyToSetting(preference.getKey());
if (preventRingingSetting != Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE)) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.VOLUME_HUSH_GESTURE, preventRingingSetting);
}
}
@Override
public void updateState(Preference preference) {
int preventRingingSetting = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE);
final boolean isVibrate = preventRingingSetting == Settings.Secure.VOLUME_HUSH_VIBRATE;
final boolean isMute = preventRingingSetting == Settings.Secure.VOLUME_HUSH_MUTE;
final boolean isOff = preventRingingSetting == Settings.Secure.VOLUME_HUSH_OFF
|| (!isVibrate && !isMute);
if (mVibratePref != null && mVibratePref.isChecked() != isVibrate) {
mVibratePref.setChecked(isVibrate);
}
if (mMutePref != null && mMutePref.isChecked() != isMute) {
mMutePref.setChecked(isMute);
}
if (mNonePref != null && mNonePref.isChecked() != isOff) {
mNonePref.setChecked(isOff);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
mVideoPaused = savedInstanceState.getBoolean(KEY_VIDEO_PAUSED, false);
}
}
@Override
public void onResume() {
if (mSettingObserver != null) {
mSettingObserver.register(mContext.getContentResolver());
mSettingObserver.onChange(false, null);
}
if (mVideoPreference != null) {
mVideoPreference.onViewVisible(mVideoPaused);
}
}
@Override
public void onPause() {
if (mSettingObserver != null) {
mSettingObserver.unregister(mContext.getContentResolver());
}
if (mVideoPreference != null) {
mVideoPaused = mVideoPreference.isVideoPaused();
mVideoPreference.onViewInvisible();
}
}
private int keyToSetting(String key) {
switch (key) {
case KEY_NONE:
return Settings.Secure.VOLUME_HUSH_OFF;
case KEY_MUTE:
return Settings.Secure.VOLUME_HUSH_MUTE;
case KEY_VIBRATE:
default:
return Settings.Secure.VOLUME_HUSH_VIBRATE;
}
}
private RadioButtonPreference makeRadioPreference(String key, int titleId) {
RadioButtonPreference pref = new RadioButtonPreference(mPreferenceCategory.getContext());
pref.setKey(key);
pref.setTitle(titleId);
pref.setOnClickListener(this);
mPreferenceCategory.addPreference(pref);
return pref;
}
private class SettingObserver extends ContentObserver {
private final Uri VOLUME_HUSH_GESTURE = Settings.Secure.getUriFor(
Settings.Secure.VOLUME_HUSH_GESTURE);
private final Preference mPreference;
public SettingObserver(Preference preference) {
super(new Handler());
mPreference = preference;
}
public void register(ContentResolver cr) {
cr.registerContentObserver(VOLUME_HUSH_GESTURE, false, this);
}
public void unregister(ContentResolver cr) {
cr.unregisterContentObserver(this);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (uri == null || VOLUME_HUSH_GESTURE.equals(uri)) {
updateState(mPreference);
}
}
}
}

View File

@@ -23,8 +23,11 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
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;
@@ -39,6 +42,18 @@ public class PreventRingingGestureSettings extends DashboardFragment {
super.onAttach(context);
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle());
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle) {
List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new PreventRingingGesturePreferenceController(context, lifecycle));
return controllers;
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.SETTINGS_PREVENT_RINGING;
@@ -68,6 +83,12 @@ public class PreventRingingGestureSettings extends DashboardFragment {
sir.xmlResId = R.xml.prevent_ringing_gesture_settings;
return Arrays.asList(sir);
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
};
}

View File

@@ -1,132 +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.gestures;
import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
import android.content.Context;
import android.os.Bundle;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.widget.VideoPreference;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
public class PreventRingingPreferenceController extends PreventRingingParentPreferenceController
implements Preference.OnPreferenceChangeListener,
LifecycleObserver, OnResume, OnPause, OnCreate, OnSaveInstanceState {
private static final String PREF_KEY_VIDEO = "gesture_prevent_ringing_video";
@VisibleForTesting
static final String KEY_VIDEO_PAUSED = "key_video_paused";
private VideoPreference mVideoPreference;
@VisibleForTesting
boolean mVideoPaused;
public PreventRingingPreferenceController(Context context, String key) {
super(context, key);
}
@Override
public int getAvailabilityStatus() {
final int status = super.getAvailabilityStatus();
if (status == AVAILABLE_UNSEARCHABLE) {
return AVAILABLE;
}
return status;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
if (isAvailable()) {
mVideoPreference = (VideoPreference) screen.findPreference(getVideoPrefKey());
}
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (preference != null) {
if (preference instanceof ListPreference) {
ListPreference pref = (ListPreference) preference;
int value = Settings.Secure.getInt(
mContext.getContentResolver(), SECURE_KEY, VOLUME_HUSH_VIBRATE);
switch (value) {
case VOLUME_HUSH_VIBRATE:
pref.setValue(String.valueOf(value));
break;
case VOLUME_HUSH_MUTE:
pref.setValue(String.valueOf(value));
break;
default:
pref.setValue(String.valueOf(VOLUME_HUSH_OFF));
}
}
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
mVideoPaused = savedInstanceState.getBoolean(KEY_VIDEO_PAUSED, false);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean(KEY_VIDEO_PAUSED, mVideoPaused);
}
@Override
public void onPause() {
if (mVideoPreference != null) {
mVideoPaused = mVideoPreference.isVideoPaused();
mVideoPreference.onViewInvisible();
}
}
@Override
public void onResume() {
if (mVideoPreference != null) {
mVideoPreference.onViewVisible(mVideoPaused);
}
}
protected String getVideoPrefKey() {
return PREF_KEY_VIDEO;
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
int value = Integer.parseInt((String) newValue);
Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY, value);
preference.setSummary(getSummary());
return true;
}
}

View File

@@ -42,6 +42,7 @@ public class ContextualCard {
int CONDITIONAL = 3;
}
private final Builder mBuilder;
private final String mName;
@CardType
private final int mCardType;
@@ -142,7 +143,12 @@ public class ContextualCard {
return TextUtils.isEmpty(mSliceUri);
}
public Builder mutate() {
return mBuilder;
}
public ContextualCard(Builder builder) {
mBuilder = builder;
mName = builder.mName;
mCardType = builder.mCardType;
mRankingScore = builder.mRankingScore;
@@ -164,28 +170,47 @@ public class ContextualCard {
}
ContextualCard(Cursor c) {
mBuilder = new Builder();
mName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.NAME));
mBuilder.setName(mName);
mCardType = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.TYPE));
mBuilder.setCardType(mCardType);
mRankingScore = c.getDouble(c.getColumnIndex(CardDatabaseHelper.CardColumns.SCORE));
mBuilder.setRankingScore(mRankingScore);
mSliceUri = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.SLICE_URI));
mBuilder.setSliceUri(Uri.parse(mSliceUri));
mCategory = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.CATEGORY));
mBuilder.setCategory(mCategory);
mLocalizedToLocale = c.getString(
c.getColumnIndex(CardDatabaseHelper.CardColumns.LOCALIZED_TO_LOCALE));
mBuilder.setLocalizedToLocale(mLocalizedToLocale);
mPackageName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.PACKAGE_NAME));
mBuilder.setPackageName(mPackageName);
mAppVersion = c.getLong(c.getColumnIndex(CardDatabaseHelper.CardColumns.APP_VERSION));
mBuilder.setAppVersion(mAppVersion);
mTitleResName = c.getString(
c.getColumnIndex(CardDatabaseHelper.CardColumns.TITLE_RES_NAME));
mBuilder.setTitleResName(mTitleResName);
mTitleText = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.TITLE_TEXT));
mBuilder.setTitleText(mTitleText);
mSummaryResName = c.getString(
c.getColumnIndex(CardDatabaseHelper.CardColumns.SUMMARY_RES_NAME));
mBuilder.setSummaryResName(mSummaryResName);
mSummaryText = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.SUMMARY_TEXT));
mBuilder.setSummaryText(mSummaryText);
mIconResName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.ICON_RES_NAME));
mBuilder.setIconResName(mIconResName);
mIconResId = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.ICON_RES_ID));
mBuilder.setIconResId(mIconResId);
mCardAction = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.CARD_ACTION));
mBuilder.setCardAction(mCardAction);
mExpireTimeMS = c.getLong(c.getColumnIndex(CardDatabaseHelper.CardColumns.EXPIRE_TIME_MS));
mBuilder.setExpireTimeMS(mExpireTimeMS);
mIsHalfWidth = (c.getInt(
c.getColumnIndex(CardDatabaseHelper.CardColumns.SUPPORT_HALF_WIDTH)) == 1);
mBuilder.setIsHalfWidth(mIsHalfWidth);
mIconDrawable = null;
mBuilder.setIconDrawable(mIconDrawable);
}
@Override

View File

@@ -16,43 +16,61 @@
package com.android.settings.homepage.contextualcards;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.settings.homepage.contextualcards.ContextualCard.CardType;
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
public class ContextualCardLookupTable {
private static final String TAG = "ContextualCardLookup";
static class ControllerRendererMapping implements Comparable<ControllerRendererMapping> {
@CardType
private final int mCardType;
private final Class<? extends ContextualCardController> mControllerClass;
private final Class<? extends ContextualCardRenderer> mRendererClass;
final int mCardType;
final int mViewType;
final Class<? extends ContextualCardController> mControllerClass;
final Class<? extends ContextualCardRenderer> mRendererClass;
private ControllerRendererMapping(@CardType int cardType,
ControllerRendererMapping(@CardType int cardType, int viewType,
Class<? extends ContextualCardController> controllerClass,
Class<? extends ContextualCardRenderer> rendererClass) {
mCardType = cardType;
mViewType = viewType;
mControllerClass = controllerClass;
mRendererClass = rendererClass;
}
@Override
public int compareTo(ControllerRendererMapping other) {
return Integer.compare(this.mCardType, other.mCardType);
return Comparator.comparingInt((ControllerRendererMapping mapping) -> mapping.mCardType)
.thenComparingInt(mapping -> mapping.mViewType)
.compare(this, other);
}
}
private static final Set<ControllerRendererMapping> LOOKUP_TABLE =
@VisibleForTesting
static final Set<ControllerRendererMapping> LOOKUP_TABLE =
new TreeSet<ControllerRendererMapping>() {{
add(new ControllerRendererMapping(CardType.CONDITIONAL,
ConditionContextualCardRenderer.HALF_WIDTH_VIEW_TYPE,
ConditionContextualCardController.class,
ConditionContextualCardRenderer.class));
add(new ControllerRendererMapping(CardType.CONDITIONAL,
ConditionContextualCardRenderer.FULL_WIDTH_VIEW_TYPE,
ConditionContextualCardController.class,
ConditionContextualCardRenderer.class));
add(new ControllerRendererMapping(CardType.SLICE,
SliceContextualCardRenderer.VIEW_TYPE,
SliceContextualCardController.class,
SliceContextualCardRenderer.class));
}};
@@ -67,14 +85,27 @@ public class ContextualCardLookupTable {
return null;
}
//TODO(b/112578070): Implement multi renderer cases.
public static Class<? extends ContextualCardRenderer> getCardRendererClasses(
public static Class<? extends ContextualCardRenderer> getCardRendererClassByCardType(
@CardType int cardType) {
for (ControllerRendererMapping mapping : LOOKUP_TABLE) {
if (mapping.mCardType == cardType) {
return mapping.mRendererClass;
}
return LOOKUP_TABLE.stream()
.filter(m -> m.mCardType == cardType)
.findFirst()
.map(mapping -> mapping.mRendererClass)
.orElse(null);
}
public static Class<? extends ContextualCardRenderer> getCardRendererClassByViewType(
int viewType) throws IllegalStateException {
List<ControllerRendererMapping> validMappings = LOOKUP_TABLE.stream()
.filter(m -> m.mViewType == viewType).collect(Collectors.toList());
if (validMappings == null || validMappings.isEmpty()) {
Log.w(TAG, "No matching mapping");
return null;
}
return null;
if (validMappings.size() != 1) {
throw new IllegalStateException("Have duplicate VIEW_TYPE in lookup table.");
}
return validMappings.get(0).mRendererClass;
}
}

View File

@@ -26,9 +26,9 @@ import androidx.recyclerview.widget.RecyclerView;
public interface ContextualCardRenderer {
/**
* The layout type of the controller.
* The layout type of the renderer.
*/
int getViewType();
int getViewType(boolean isHalfWidth);
/**
* When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder},

View File

@@ -61,26 +61,26 @@ public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.Vi
@Override
public int getItemViewType(int position) {
return mContextualCards.get(position).getCardType();
final ContextualCard card = mContextualCards.get(position);
final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByCardType(
mContext, mLifecycleOwner, card.getCardType());
return renderer.getViewType(card.isHalfWidth());
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int cardType) {
final ContextualCardRenderer renderer = mControllerRendererPool.getRenderer(mContext,
mLifecycleOwner, cardType);
final int viewType = renderer.getViewType();
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByViewType(
mContext, mLifecycleOwner, viewType);
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return renderer.createViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final int cardType = mContextualCards.get(position).getCardType();
final ContextualCardRenderer renderer = mControllerRendererPool.getRenderer(mContext,
mLifecycleOwner, cardType);
renderer.bindView(holder, mContextualCards.get(position));
final ContextualCard card = mContextualCards.get(position);
final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByCardType(
mContext, mLifecycleOwner, card.getCardType());
renderer.bindView(holder, card);
}
@Override

View File

@@ -16,12 +16,14 @@
package com.android.settings.homepage.contextualcards;
import android.annotation.NonNull;
import android.content.Context;
import android.util.Log;
import androidx.collection.ArraySet;
import androidx.lifecycle.LifecycleOwner;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
@@ -63,14 +65,32 @@ public class ControllerRendererPool {
return (T) controller;
}
public Set<ContextualCardController> getControllers() {
@VisibleForTesting
Set<ContextualCardController> getControllers() {
return mControllers;
}
public ContextualCardRenderer getRenderer(Context context, LifecycleOwner lifecycleOwner,
@ContextualCard.CardType int cardType) {
@VisibleForTesting
Set<ContextualCardRenderer> getRenderers() {
return mRenderers;
}
public ContextualCardRenderer getRendererByViewType(Context context,
LifecycleOwner lifecycleOwner, int viewType) {
final Class<? extends ContextualCardRenderer> clz =
ContextualCardLookupTable.getCardRendererClasses(cardType);
ContextualCardLookupTable.getCardRendererClassByViewType(viewType);
return getRenderer(context, lifecycleOwner, clz);
}
public ContextualCardRenderer getRendererByCardType(Context context,
LifecycleOwner lifecycleOwner, @ContextualCard.CardType int cardType) {
final Class<? extends ContextualCardRenderer> clz =
ContextualCardLookupTable.getCardRendererClassByCardType(cardType);
return getRenderer(context, lifecycleOwner, clz);
}
private ContextualCardRenderer getRenderer(Context context, LifecycleOwner lifecycleOwner,
@NonNull Class<? extends ContextualCardRenderer> clz) {
for (ContextualCardRenderer renderer : mRenderers) {
if (renderer.getClass() == clz) {
Log.d(TAG, "Renderer is already there.");

View File

@@ -26,7 +26,6 @@ import com.android.settings.intelligence.ContextualCardProto.ContextualCard;
import com.android.settings.intelligence.ContextualCardProto.ContextualCardList;
import com.android.settings.wifi.WifiSlice;
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardCategory;
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardProvider;
/** Provides dynamic card for SettingsIntelligence. */
@@ -41,19 +40,19 @@ public class SettingsContextualCardProvider extends ContextualCardProvider {
ContextualCard.newBuilder()
.setSliceUri(WifiSlice.WIFI_URI.toString())
.setCardName(KEY_WIFI)
.setCategory(ContextualCardCategory.IMPORTANT)
.setCardCategory(ContextualCard.Category.IMPORTANT)
.build();
final ContextualCard batteryInfoCard =
ContextualCard.newBuilder()
.setSliceUri(BatterySlice.BATTERY_CARD_URI.toString())
.setCardName(BatterySlice.PATH_BATTERY_INFO)
.setCategory(ContextualCardCategory.DEFAULT)
.setCardCategory(ContextualCard.Category.DEFAULT)
.build();
final ContextualCard connectedDeviceCard =
ContextualCard.newBuilder()
.setSliceUri(ConnectedDeviceSlice.CONNECTED_DEVICE_URI.toString())
.setCardName(ConnectedDeviceSlice.PATH_CONNECTED_DEVICE)
.setCategory(ContextualCardCategory.IMPORTANT)
.setCardCategory(ContextualCard.Category.IMPORTANT)
.build();
final ContextualCardList cards = ContextualCardList.newBuilder()
.addCard(wifiCard)

View File

@@ -79,6 +79,7 @@ public class AirplaneModeConditionController implements ConditionalCardControlle
.setTitleText(mAppContext.getText(R.string.condition_airplane_title).toString())
.setSummaryText(mAppContext.getText(R.string.condition_airplane_summary).toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_airplanemode_active))
.setIsHalfWidth(true)
.build();
}

View File

@@ -73,6 +73,7 @@ public class BackgroundDataConditionController implements ConditionalCardControl
.setTitleText(mAppContext.getText(R.string.condition_bg_data_title).toString())
.setSummaryText(mAppContext.getText(R.string.condition_bg_data_summary).toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_data_saver))
.setIsHalfWidth(true)
.build();
}

View File

@@ -82,6 +82,7 @@ public class BatterySaverConditionController implements ConditionalCardControlle
.setTitleText(mAppContext.getText(R.string.condition_battery_title).toString())
.setSummaryText(mAppContext.getText(R.string.condition_battery_summary).toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_battery_saver_accent_24dp))
.setIsHalfWidth(true)
.build();
}

View File

@@ -89,6 +89,7 @@ public class CellularDataConditionController implements ConditionalCardControlle
.setTitleText(mAppContext.getText(R.string.condition_cellular_title).toString())
.setSummaryText(mAppContext.getText(R.string.condition_cellular_summary).toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_cellular_off))
.setIsHalfWidth(true)
.build();
}

View File

@@ -85,6 +85,14 @@ public class ConditionContextualCardController implements ContextualCardControll
public void onConditionsChanged() {
final List<ContextualCard> conditionCards = mConditionManager.getDisplayableCards();
final boolean isOddNumber = conditionCards.size() % 2 == 1;
if (isOddNumber) {
final int lastIndex = conditionCards.size() - 1;
final ConditionalContextualCard card = (ConditionalContextualCard) conditionCards.get(
lastIndex);
conditionCards.set(lastIndex, card.mutate().setIsHalfWidth(false).build());
}
if (mListener != null) {
final Map<Integer, List<ContextualCard>> conditionalCards = new ArrayMap<>();
conditionalCards.put(ContextualCard.CardType.CONDITIONAL, conditionCards);

View File

@@ -37,6 +37,8 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
* Card renderer for {@link ConditionalContextualCard}.
*/
public class ConditionContextualCardRenderer implements ContextualCardRenderer {
public static final int HALF_WIDTH_VIEW_TYPE = R.layout.homepage_condition_half_tile;
public static final int FULL_WIDTH_VIEW_TYPE = R.layout.homepage_condition_full_tile;
private final Context mContext;
private final ControllerRendererPool mControllerRendererPool;
@@ -48,8 +50,12 @@ public class ConditionContextualCardRenderer implements ContextualCardRenderer {
}
@Override
public int getViewType() {
return R.layout.homepage_condition_tile;
public int getViewType(boolean isHalfWidth) {
if (isHalfWidth) {
return HALF_WIDTH_VIEW_TYPE;
} else {
return FULL_WIDTH_VIEW_TYPE;
}
}
@Override
@@ -87,15 +93,12 @@ public class ConditionContextualCardRenderer implements ContextualCardRenderer {
view.icon.setImageDrawable(card.getIconDrawable());
view.title.setText(card.getTitleText());
view.summary.setText(card.getSummaryText());
setViewVisibility(view.itemView, R.id.divider, false);
}
private void initializeActionButton(ConditionalCardHolder view, ConditionalContextualCard card,
MetricsFeatureProvider metricsFeatureProvider) {
final CharSequence action = card.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) {
@@ -114,13 +117,6 @@ public class ConditionContextualCardRenderer implements ContextualCardRenderer {
}
}
private void setViewVisibility(View containerView, int viewId, boolean visible) {
View view = containerView.findViewById(viewId);
if (view != null) {
view.setVisibility(visible ? View.VISIBLE : View.GONE);
}
}
public static class ConditionalCardHolder extends RecyclerView.ViewHolder {
public final ImageView icon;

View File

@@ -100,6 +100,7 @@ public class DndConditionCardController implements ConditionalCardController {
.setTitleText(mAppContext.getText(R.string.condition_zen_title).toString())
.setSummaryText(getSummary().toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
.setIsHalfWidth(true)
.build();
}

View File

@@ -99,6 +99,7 @@ public class HotspotConditionController implements ConditionalCardController {
.setTitleText(mAppContext.getText(R.string.condition_hotspot_title).toString())
.setSummaryText(getSummary().toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_hotspot))
.setIsHalfWidth(true)
.build();
}

View File

@@ -78,6 +78,7 @@ public class NightDisplayConditionController implements ConditionalCardControlle
.setSummaryText(
mAppContext.getText(R.string.condition_night_display_summary).toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_settings_night_display))
.setIsHalfWidth(true)
.build();
}

View File

@@ -72,6 +72,7 @@ public class RingerMutedConditionController extends AbnormalRingerConditionContr
.setSummaryText(
mAppContext.getText(R.string.condition_device_muted_summary).toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_notifications_off_24dp))
.setIsHalfWidth(true)
.build();
}
}

View File

@@ -60,6 +60,7 @@ public class RingerVibrateConditionController extends AbnormalRingerConditionCon
.setSummaryText(
mAppContext.getText(R.string.condition_device_vibrate_summary).toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_volume_ringer_vibrate))
.setIsHalfWidth(true)
.build();
}
}

View File

@@ -93,6 +93,7 @@ public class WorkModeConditionController implements ConditionalCardController {
.setTitleText(mAppContext.getText(R.string.condition_work_title).toString())
.setSummaryText(mAppContext.getText(R.string.condition_work_summary).toString())
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_signal_workmode_enable))
.setIsHalfWidth(true)
.build();
}

View File

@@ -45,6 +45,7 @@ import java.util.Map;
*/
public class SliceContextualCardRenderer implements ContextualCardRenderer,
SliceView.OnSliceActionListener {
public static final int VIEW_TYPE = R.layout.homepage_slice_tile;
private static final String TAG = "SliceCardRenderer";
@@ -61,8 +62,8 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
}
@Override
public int getViewType() {
return R.layout.homepage_slice_tile;
public int getViewType(boolean isHalfWidth) {
return VIEW_TYPE;
}
@Override

View File

@@ -25,9 +25,11 @@ import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.search.SearchIndexableResources;
@@ -64,6 +66,13 @@ public interface SearchFeatureProvider {
if (activity == null || toolbar == null) {
return;
}
if (!Utils.isPackageEnabled(activity, getSettingsIntelligencePkgName())) {
final ViewGroup parent = (ViewGroup)toolbar.getParent();
if (parent != null) {
parent.setVisibility(View.GONE);
}
return;
}
// Please forgive me for what I am about to do.
//
// Need to make the navigation icon non-clickable so that the entire card is clickable

View File

@@ -56,9 +56,15 @@ public class SearchMenuController implements LifecycleObserver, OnCreateOptionsM
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final Context context = mHost.getContext();
final String SettingsIntelligencePkgName = FeatureFactory.getFactory(context)
.getSearchFeatureProvider().getSettingsIntelligencePkgName();
if (!Utils.isDeviceProvisioned(mHost.getContext())) {
return;
}
if (!Utils.isPackageEnabled(mHost.getContext(), SettingsIntelligencePkgName)) {
return;
}
if (menu == null) {
return;
}
@@ -72,10 +78,8 @@ public class SearchMenuController implements LifecycleObserver, OnCreateOptionsM
searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
searchItem.setOnMenuItemClickListener(target -> {
final Context context = mHost.getContext();
final Intent intent = SearchFeatureProvider.SEARCH_UI_INTENT;
intent.setPackage(FeatureFactory.getFactory(mHost.getContext())
.getSearchFeatureProvider().getSettingsIntelligencePkgName());
intent.setPackage(SettingsIntelligencePkgName);
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
.action(context, MetricsProto.MetricsEvent.ACTION_SEARCH_RESULTS);
mHost.startActivityForResult(intent, 0 /* requestCode */);

View File

@@ -401,6 +401,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
// Build and return intent
Intent intent = new Intent();
intent.setComponent(componentName);
intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mSubId);
return intent;
}

View File

@@ -38,6 +38,7 @@ import androidx.fragment.app.FragmentTransaction;
import com.android.settings.core.OnActivityResultListener;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.Before;
import org.junit.Test;
@@ -46,6 +47,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
@@ -69,6 +71,7 @@ public class SettingsActivityTest {
}
@Test
@Config(shadows = ShadowUtils.class)
public void onCreate_deviceNotProvisioned_shouldDisableSearch() {
Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
final SettingsActivity activity = Robolectric.buildActivity(SettingsActivity.class)
@@ -80,6 +83,7 @@ public class SettingsActivityTest {
}
@Test
@Config(shadows = ShadowUtils.class)
public void onCreate_deviceProvisioned_shouldEnableSearch() {
Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
final SettingsActivity activity = Robolectric.buildActivity(SettingsActivity.class)

View File

@@ -93,6 +93,7 @@ public class UtilsTest {
when(mContext.getSystemService(WifiManager.class)).thenReturn(wifiManager);
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
.thenReturn(connectivityManager);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
}
@Test
@@ -200,4 +201,27 @@ public class UtilsTest {
verify(mPackageManager).getApplicationInfoAsUser(eq(PACKAGE_NAME), anyInt(), eq(USER_ID));
verify(mIconDrawableFactory).getBadgedIcon(mApplicationInfo, USER_ID);
}
@Test
public void isPackageEnabled_appEnabled_returnTrue()
throws PackageManager.NameNotFoundException{
mApplicationInfo.enabled = true;
when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isTrue();
}
@Test
public void isPackageEnabled_appDisabled_returnTrue()
throws PackageManager.NameNotFoundException{
mApplicationInfo.enabled = false;
when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
}
@Test
public void isPackageEnabled_noApp_returnFalse() {
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
}
}

View File

@@ -0,0 +1,152 @@
/*
* 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.gestures;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import android.content.Context;
import android.content.res.Resources;
import android.preference.PreferenceCategory;
import android.provider.Settings;
import androidx.preference.PreferenceScreen;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.robolectric.RuntimeEnvironment;
@RunWith(SettingsRobolectricTestRunner.class)
public class PreventRingingGesturePreferenceControllerTest {
private Context mContext;
private Resources mResources;
private PreventRingingGesturePreferenceController mController;
@Before
public void setUp() {
mContext = spy(RuntimeEnvironment.application);
mResources = mock(Resources.class);
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled))
.thenReturn(true);
mController = new PreventRingingGesturePreferenceController(mContext, null);
mController.mVibratePref = new RadioButtonPreference(mContext);
mController.mNonePref = new RadioButtonPreference(mContext);
mController.mMutePref = new RadioButtonPreference(mContext);
}
@Test
public void testIsAvailable_configIsTrue_shouldReturnTrue() {
when(mResources.getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void testIsAvailable_configIsFalse_shouldReturnFalse() {
when(mResources.getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(false);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void testUpdateState_mute() {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.VOLUME_HUSH_MUTE);
mController.updateState(null);
assertThat(mController.mVibratePref.isChecked()).isFalse();
assertThat(mController.mNonePref.isChecked()).isFalse();
assertThat(mController.mMutePref.isChecked()).isTrue();
}
@Test
public void testUpdateState_vibrate() {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.VOLUME_HUSH_VIBRATE);
mController.updateState(null);
assertThat(mController.mVibratePref.isChecked()).isTrue();
assertThat(mController.mNonePref.isChecked()).isFalse();
assertThat(mController.mMutePref.isChecked()).isFalse();
}
@Test
public void testUpdateState_other() {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
7);
mController.updateState(null);
assertThat(mController.mVibratePref.isChecked()).isFalse();
assertThat(mController.mNonePref.isChecked()).isTrue();
assertThat(mController.mMutePref.isChecked()).isFalse();
}
@Test
public void testRadioButtonClicked_mute() {
RadioButtonPreference rbPref = new RadioButtonPreference(mContext);
rbPref.setKey(PreventRingingGesturePreferenceController.KEY_MUTE);
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.VOLUME_HUSH_OFF);
mController.onRadioButtonClicked(rbPref);
assertThat(Settings.Secure.VOLUME_HUSH_MUTE).isEqualTo(
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_OFF));
}
@Test
public void testRadioButtonClicked_vibrate() {
RadioButtonPreference rbPref = new RadioButtonPreference(mContext);
rbPref.setKey(PreventRingingGesturePreferenceController.KEY_VIBRATE);
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.VOLUME_HUSH_OFF);
mController.onRadioButtonClicked(rbPref);
assertThat(Settings.Secure.VOLUME_HUSH_VIBRATE).isEqualTo(
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_OFF));
}
@Test
public void testRadioButtonClicked_off() {
RadioButtonPreference rbPref = new RadioButtonPreference(mContext);
rbPref.setKey(PreventRingingGesturePreferenceController.KEY_NONE);
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.VOLUME_HUSH_MUTE);
mController.onRadioButtonClicked(rbPref);
assertThat(Settings.Secure.VOLUME_HUSH_OFF).isEqualTo(
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE));
}
}

View File

@@ -1,122 +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.gestures;
import static android.provider.Settings.Secure.VOLUME_HUSH_GESTURE;
import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(SettingsRobolectricTestRunner.class)
public class PreventRingingPreferenceControllerTest {
private static final String KEY_PICK_UP = "gesture_prevent_ringing";
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private PreventRingingPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new PreventRingingPreferenceController(mContext, KEY_PICK_UP);
}
@Test
public void testIsAvailable_configIsTrue_shouldReturnTrue() {
when(mContext.getResources().getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void testIsAvailable_configIsFalse_shouldReturnFalse() {
when(mContext.getResources().getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(false);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void testUpdateState_mute() {
ListPreference pref = mock(ListPreference.class);
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.VOLUME_HUSH_MUTE);
mController.updateState(pref);
verify(pref).setValue(String.valueOf(Settings.Secure.VOLUME_HUSH_MUTE));
}
@Test
public void testUpdateState_vibrate() {
ListPreference pref = mock(ListPreference.class);
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.VOLUME_HUSH_VIBRATE);
mController.updateState(pref);
verify(pref).setValue(String.valueOf(Settings.Secure.VOLUME_HUSH_VIBRATE));
}
@Test
public void testUpdateState_other() {
ListPreference pref = mock(ListPreference.class);
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
7);
mController.updateState(pref);
verify(pref).setValue(String.valueOf(Settings.Secure.VOLUME_HUSH_OFF));
}
@Test
public void testUpdateState_parentPage() {
Preference pref = mock(Preference.class);
// verify no exception
mController.updateState(pref);
}
@Test
public void testOnPreferenceChange() {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
7);
mController.onPreferenceChange(mock(Preference.class), String.valueOf(VOLUME_HUSH_MUTE));
assertEquals(VOLUME_HUSH_MUTE, Settings.Secure.getInt(mContext.getContentResolver(),
VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF));
}
}

View File

@@ -0,0 +1,115 @@
/*
* 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.contextualcards;
import static com.google.common.truth.Truth.assertThat;
import com.android.settings.homepage.contextualcards.ContextualCardLookupTable
.ControllerRendererMapping;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
public class ContextualCardLookupTableTest {
private static final int UNSUPPORTED_CARD_TYPE = -99999;
private static final int UNSUPPORTED_VIEW_TYPE = -99999;
private List<ControllerRendererMapping> mOriginalLookupTable;
@Before
public void setUp() {
mOriginalLookupTable = new ArrayList<>();
ContextualCardLookupTable.LOOKUP_TABLE.stream()
.forEach(mapping -> mOriginalLookupTable.add(mapping));
}
@After
public void reset() {
ContextualCardLookupTable.LOOKUP_TABLE.clear();
ContextualCardLookupTable.LOOKUP_TABLE.addAll(mOriginalLookupTable);
}
@Test
public void getCardControllerClass_hasSupportedCardType_shouldGetCorrespondingController() {
for (ControllerRendererMapping mapping : ContextualCardLookupTable.LOOKUP_TABLE) {
assertThat(ContextualCardLookupTable.getCardControllerClass(mapping.mCardType))
.isEqualTo(mapping.mControllerClass);
}
}
@Test
public void getCardControllerClass_hasUnsupportedCardType_shouldAlwaysGetNull() {
assertThat(ContextualCardLookupTable.getCardControllerClass(UNSUPPORTED_CARD_TYPE))
.isNull();
}
@Test
public void
getCardRendererClassByViewType_hasSupportedViewType_shouldGetCorrespondingRenderer() {
for (ControllerRendererMapping mapping : ContextualCardLookupTable.LOOKUP_TABLE) {
assertThat(ContextualCardLookupTable.getCardRendererClassByViewType(mapping.mViewType))
.isEqualTo(mapping.mRendererClass);
}
}
@Test
public void getCardRendererClassByViewType_hasUnsupportedViewType_shouldAlwaysGetNull() {
assertThat(ContextualCardLookupTable.getCardRendererClassByViewType(
UNSUPPORTED_VIEW_TYPE)).isNull();
}
@Test(expected = IllegalStateException.class)
public void
getCardRendererClassByViewType_hasDuplicateViewType_shouldThrowsIllegalStateException() {
final ControllerRendererMapping mapping1 =
new ControllerRendererMapping(
1111 /* cardType */, UNSUPPORTED_VIEW_TYPE /* viewType */,
ContextualCardController.class, ContextualCardRenderer.class
);
final ControllerRendererMapping mapping2 =
new ControllerRendererMapping(
2222 /* cardType */, UNSUPPORTED_VIEW_TYPE /* viewType */,
ContextualCardController.class, ContextualCardRenderer.class
);
ContextualCardLookupTable.LOOKUP_TABLE.add(mapping1);
ContextualCardLookupTable.LOOKUP_TABLE.add(mapping2);
ContextualCardLookupTable.getCardRendererClassByViewType(UNSUPPORTED_VIEW_TYPE);
}
@Test
public void getRendererClassByCardType_hasSupportedCardType_shouldGetCorrespondingRenderer() {
for (ControllerRendererMapping mapping : ContextualCardLookupTable.LOOKUP_TABLE) {
assertThat(ContextualCardLookupTable.getCardRendererClassByCardType(mapping.mCardType))
.isEqualTo(mapping.mRendererClass);
}
}
@Test
public void getCardRendererClassByCardType_hasUnsupportedCardType_shouldAlwaysGetNull() {
assertThat(ContextualCardLookupTable.getCardRendererClassByCardType(UNSUPPORTED_CARD_TYPE))
.isNull();
}
}

View File

@@ -0,0 +1,137 @@
/*
* 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.contextualcards;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.lifecycle.LifecycleOwner;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
@RunWith(SettingsRobolectricTestRunner.class)
public class ControllerRendererPoolTest {
private static final int UNSUPPORTED_CARD_TYPE = -99999;
private static final int UNSUPPORTED_VIEW_TYPE = -99999;
private ControllerRendererPool mPool;
private Context mContext;
private Lifecycle mLifecycle;
private LifecycleOwner mLifecycleOwner;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mPool = new ControllerRendererPool();
}
@Test
public void getController_hasSupportedCardType_shouldReturnCorrespondingController() {
ContextualCardLookupTable.LOOKUP_TABLE.stream().forEach(mapping -> assertThat(
mPool.getController(mContext, mapping.mCardType).getClass()).isEqualTo(
mapping.mControllerClass));
}
@Test
public void getController_hasSupportedCardType_shouldHaveTwoControllersInPool() {
final long count = ContextualCardLookupTable.LOOKUP_TABLE.stream().map(
mapping -> mapping.mControllerClass).distinct().count();
ContextualCardLookupTable.LOOKUP_TABLE.stream().forEach(
mapping -> mPool.getController(mContext, mapping.mCardType));
assertThat(mPool.getControllers()).hasSize((int) count);
}
@Test
public void getController_hasUnsupportedCardType_shouldReturnNullAndPoolIsEmpty() {
final ContextualCardController controller = mPool.getController(mContext,
UNSUPPORTED_CARD_TYPE);
assertThat(controller).isNull();
assertThat(mPool.getControllers()).isEmpty();
}
@Test
public void getRenderer_hasSupportedViewType_shouldReturnCorrespondingRenderer() {
ContextualCardLookupTable.LOOKUP_TABLE.stream().forEach(mapping -> assertThat(
mPool.getRendererByViewType(mContext, mLifecycleOwner,
mapping.mViewType).getClass()).isEqualTo(mapping.mRendererClass));
}
@Test
public void getRenderer_hasSupportedViewType_shouldHaveDistinctRenderersInPool() {
final long count = ContextualCardLookupTable.LOOKUP_TABLE.stream().map(
mapping -> mapping.mRendererClass).distinct().count();
ContextualCardLookupTable.LOOKUP_TABLE.stream().forEach(
mapping -> mPool.getRendererByViewType(mContext, mLifecycleOwner,
mapping.mViewType));
assertThat(mPool.getRenderers()).hasSize((int) count);
}
@Test
public void getRenderer_hasUnsupportedViewType_shouldReturnNullAndPoolIsEmpty() {
final ContextualCardRenderer renderer = mPool.getRendererByViewType(mContext,
mLifecycleOwner,
UNSUPPORTED_VIEW_TYPE);
assertThat(renderer).isNull();
assertThat(mPool.getRenderers()).isEmpty();
}
@Test
public void getRenderer_hasSupportedCardTypeAndWidth_shouldReturnCorrespondingRenderer() {
ContextualCardLookupTable.LOOKUP_TABLE.stream().forEach(mapping -> assertThat(
mPool.getRendererByCardType(mContext, mLifecycleOwner,
mapping.mCardType).getClass()).isEqualTo(mapping.mRendererClass));
}
@Test
public void getRenderer_hasSupportedCardTypeAndWidth_shouldHaveDistinctRenderersInPool() {
final long count = ContextualCardLookupTable.LOOKUP_TABLE.stream().map(
mapping -> mapping.mRendererClass).distinct().count();
ContextualCardLookupTable.LOOKUP_TABLE.stream().forEach(
mapping -> mPool.getRendererByCardType(mContext, mLifecycleOwner,
mapping.mCardType));
assertThat(mPool.getRenderers()).hasSize((int) count);
}
@Test
public void getRenderer_hasUnsupportedCardType_shouldReturnNullAndPoolIsEmpty() {
final ContextualCardRenderer renderer = mPool.getRendererByCardType(mContext,
mLifecycleOwner,
UNSUPPORTED_CARD_TYPE);
assertThat(renderer).isNull();
assertThat(mPool.getRenderers()).isEmpty();
}
}

View File

@@ -19,7 +19,12 @@ package com.android.settings.homepage.contextualcards;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import android.app.slice.SliceManager;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
@@ -28,30 +33,37 @@ import com.android.settings.intelligence.ContextualCardProto.ContextualCardList;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wifi.WifiSlice;
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardCategory;
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
@RunWith(SettingsRobolectricTestRunner.class)
public class SettingsContextualCardProviderTest {
@Mock
private SliceManager mSliceManager;
private ContentResolver mResolver;
private Uri mUri;
private SettingsContextualCardProvider mProvider;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mResolver = RuntimeEnvironment.application.getContentResolver();
mUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsContextualCardProvider.CARD_AUTHORITY)
.build();
mProvider = Robolectric.setupContentProvider(SettingsContextualCardProvider.class);
mProvider = spy(Robolectric.setupContentProvider(SettingsContextualCardProvider.class));
final Context context = spy(RuntimeEnvironment.application);
doReturn(mSliceManager).when(context).getSystemService(SliceManager.class);
doReturn(context).when(mProvider).getContext();
}
@Test
@@ -59,7 +71,7 @@ public class SettingsContextualCardProviderTest {
final int actualNo = mProvider.getContextualCards().getCardCount();
final Bundle returnValue =
mResolver.call(mUri, ContextualCardProvider.METHOD_GET_CARD_LIST, "", null);
mProvider.call(ContextualCardProvider.METHOD_GET_CARD_LIST, "", null);
final ContextualCardList cards =
ContextualCardList.parseFrom(
returnValue.getByteArray(ContextualCardProvider.BUNDLE_CARD_LIST));
@@ -76,6 +88,6 @@ public class SettingsContextualCardProviderTest {
}
}
assertThat(wifiCard.getCategory()).isEqualTo(ContextualCardCategory.IMPORTANT);
assertThat(wifiCard.getCardCategory()).isEqualTo(ContextualCard.Category.IMPORTANT);
}
}

View File

@@ -61,7 +61,7 @@ public class ConditionContextualCardRendererTest {
@Test
public void bindView_shouldSetListener() {
final int viewType = mRenderer.getViewType();
final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
final RecyclerView recyclerView = new RecyclerView(mContext);
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
@@ -78,7 +78,7 @@ public class ConditionContextualCardRendererTest {
@Test
public void viewClick_shouldInvokeControllerPrimaryClick() {
final int viewType = mRenderer.getViewType();
final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
final RecyclerView recyclerView = new RecyclerView(mContext);
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);

View File

@@ -113,7 +113,7 @@ public class SliceContextualCardRendererTest {
}
private RecyclerView.ViewHolder getSliceViewHolder() {
final int viewType = mRenderer.getViewType();
final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
final RecyclerView recyclerView = new RecyclerView(mContext);
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);

View File

@@ -29,12 +29,14 @@ import android.widget.Toolbar;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
public class SearchFeatureProviderImplTest {
@@ -50,6 +52,7 @@ public class SearchFeatureProviderImplTest {
}
@Test
@Config(shadows = ShadowUtils.class)
public void initSearchToolbar_shouldInitWithOnClickListener() {
mProvider.initSearchToolbar(mActivity, null);
// Should not crash.

View File

@@ -30,6 +30,7 @@ import android.view.MenuItem;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.core.lifecycle.ObservableFragment;
import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
@@ -39,8 +40,10 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = ShadowUtils.class)
public class SearchMenuControllerTest {
@Mock

View File

@@ -21,9 +21,13 @@ import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.SearchFeatureProviderImpl;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -102,6 +106,11 @@ public class ShadowUtils {
return null;
}
@Implementation
public static boolean isPackageEnabled(Context context, String packageName) {
return true;
}
public static void setApplicationLabel(String packageName, String appLabel) {
if (sAppNameMap == null) {
sAppNameMap = new HashMap<>();