Merge "Fix deep link issue of Slice cards in home page"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c5e512e..7807f0e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -69,6 +69,7 @@
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" />
<uses-permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_MODE" />
+ <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
<uses-permission android:name="android.permission.SET_TIME" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATIONS" />
<uses-permission android:name="android.permission.REBOOT" />
diff --git a/res/layout/settings_homepage_container.xml b/res/layout/settings_homepage_container.xml
index 8d81e82..75d449f 100644
--- a/res/layout/settings_homepage_container.xml
+++ b/res/layout/settings_homepage_container.xml
@@ -21,24 +21,17 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@android:color/transparent"
- app:elevation="0dp">
- <include layout="@layout/search_bar"/>
- </com.google.android.material.appbar.AppBarLayout>
-
<androidx.core.widget.NestedScrollView
android:id="@+id/main_content_scrollable_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:layout_behavior="@string/appbar_scrolling_view_behavior">
+ app:layout_behavior="com.android.settings.widget.FloatingAppBarScrollingViewBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
+ android:paddingTop="@dimen/app_bar_height"
android:descendantFocusability="blocksDescendants">
<FrameLayout
@@ -55,4 +48,10 @@
</LinearLayout>
</androidx.core.widget.NestedScrollView>
+
+ <com.google.android.material.appbar.AppBarLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <include layout="@layout/search_bar"/>
+ </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 83848af..a6c6c37 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -105,6 +105,8 @@
<dimen name="search_bar_avatar_size">32dp</dimen>
<dimen name="search_bar_avatar_start_margin">4dp</dimen>
<dimen name="search_bar_avatar_end_margin">16dp</dimen>
+ <!-- appbar height is equal search bar height (48dp) plus search bar top and bottom margin -->
+ <dimen name="app_bar_height">80dp</dimen>
<!-- Dimensions for Wifi Assistant Card -->
<dimen name="wifi_assistant_padding_top_bottom">16dp</dimen>
diff --git a/src/com/android/settings/CredentialStorage.java b/src/com/android/settings/CredentialStorage.java
index 7b0be94..5ab543f 100644
--- a/src/com/android/settings/CredentialStorage.java
+++ b/src/com/android/settings/CredentialStorage.java
@@ -172,8 +172,9 @@
dialog.show(getSupportFragmentManager(), ConfigureKeyGuardDialog.TAG);
return;
}
- installIfAvailable();
- finish();
+ if (installIfAvailable()) {
+ finish();
+ }
return;
}
}
@@ -217,10 +218,13 @@
/**
* Install credentials if available, otherwise do nothing.
+ *
+ * @return true if the installation is done and the activity should be finished, false if
+ * an asynchronous task is pending and will finish the activity when it's done.
*/
- private void installIfAvailable() {
+ private boolean installIfAvailable() {
if (mInstallBundle == null || mInstallBundle.isEmpty()) {
- return;
+ return true;
}
final Bundle bundle = mInstallBundle;
@@ -235,16 +239,17 @@
if (uid != Process.WIFI_UID) {
Log.e(TAG, "Failed to install credentials as uid " + uid + ": cross-user installs"
+ " may only target wifi uids");
- return;
+ return true;
}
final Intent installIntent = new Intent(ACTION_INSTALL)
.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
.putExtras(bundle);
startActivityAsUser(installIntent, new UserHandle(dstUserId));
- return;
+ return true;
}
+ boolean shouldFinish = true;
if (bundle.containsKey(Credentials.EXTRA_USER_PRIVATE_KEY_NAME)) {
final String key = bundle.getString(Credentials.EXTRA_USER_PRIVATE_KEY_NAME);
final byte[] value = bundle.getByteArray(Credentials.EXTRA_USER_PRIVATE_KEY_DATA);
@@ -259,7 +264,7 @@
if (!mKeyStore.importKey(key, value, uid, flags)) {
Log.e(TAG, "Failed to install " + key + " as uid " + uid);
- return;
+ return true;
}
// The key was prepended USER_PRIVATE_KEY by the CredentialHelper. However,
// KeyChain internally uses the raw alias name and only prepends USER_PRIVATE_KEY
@@ -270,6 +275,7 @@
if (uid == Process.SYSTEM_UID || uid == KeyStore.UID_SELF) {
new MarkKeyAsUserSelectable(
key.replaceFirst("^" + Credentials.USER_PRIVATE_KEY, "")).execute();
+ shouldFinish = false;
}
}
@@ -281,7 +287,7 @@
if (!mKeyStore.put(certName, certData, uid, flags)) {
Log.e(TAG, "Failed to install " + certName + " as uid " + uid);
- return;
+ return shouldFinish;
}
}
@@ -291,7 +297,7 @@
if (!mKeyStore.put(caListName, caListData, uid, flags)) {
Log.e(TAG, "Failed to install " + caListName + " as uid " + uid);
- return;
+ return shouldFinish;
}
}
@@ -300,6 +306,7 @@
sendBroadcast(broadcast);
setResult(RESULT_OK);
+ return shouldFinish;
}
/**
@@ -411,6 +418,13 @@
return false;
}
}
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ Log.i(TAG, String.format("Marked alias %s as selectable, success? %s",
+ mAlias, result));
+ CredentialStorage.this.finish();
+ }
}
/**
diff --git a/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java b/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java
index 408db09..33e7771 100644
--- a/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java
+++ b/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java
@@ -36,8 +36,9 @@
public class EmergencyInfoPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin {
+ public static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENCY_INFO";
+
private static final String KEY_EMERGENCY_INFO = "emergency_info";
- private static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENCY_INFO";
private static final String PACKAGE_NAME_EMERGENCY = "com.android.emergency";
public EmergencyInfoPreferenceController(Context context) {
@@ -57,7 +58,7 @@
public void updateState(Preference preference) {
UserInfo info = mContext.getSystemService(UserManager.class).getUserInfo(
- UserHandle.myUserId());
+ UserHandle.myUserId());
preference.setSummary(mContext.getString(R.string.emergency_info_summary, info.name));
}
diff --git a/src/com/android/settings/display/ColorModePreferenceController.java b/src/com/android/settings/display/ColorModePreferenceController.java
index 4679436..5d6a412 100644
--- a/src/com/android/settings/display/ColorModePreferenceController.java
+++ b/src/com/android/settings/display/ColorModePreferenceController.java
@@ -14,11 +14,7 @@
package com.android.settings.display;
import android.content.Context;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Log;
+import android.hardware.display.ColorDisplayManager;
import androidx.annotation.VisibleForTesting;
@@ -29,19 +25,16 @@
public class ColorModePreferenceController extends BasePreferenceController {
private static final String TAG = "ColorModePreference";
- private static final int SURFACE_FLINGER_TRANSACTION_QUERY_COLOR_MANAGEMENT = 1030;
-
- private final ConfigurationWrapper mConfigWrapper;
private ColorDisplayController mColorDisplayController;
public ColorModePreferenceController(Context context, String key) {
super(context, key);
- mConfigWrapper = new ConfigurationWrapper();
}
@Override
public int getAvailabilityStatus() {
- return mConfigWrapper.isDeviceColorManaged()
+ return mContext.getSystemService(ColorDisplayManager.class)
+ .isDeviceColorManaged()
&& !getColorDisplayController().getAccessibilityTransformActivated() ?
AVAILABLE_UNSEARCHABLE : DISABLED_FOR_USER;
}
@@ -68,32 +61,4 @@
}
return mColorDisplayController;
}
-
- @VisibleForTesting
- static class ConfigurationWrapper {
- private final IBinder mSurfaceFlinger;
-
- ConfigurationWrapper() {
- mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger");
- }
-
- boolean isDeviceColorManaged() {
- if (mSurfaceFlinger != null) {
- final Parcel data = Parcel.obtain();
- final Parcel reply = Parcel.obtain();
- data.writeInterfaceToken("android.ui.ISurfaceComposer");
- try {
- mSurfaceFlinger.transact(SURFACE_FLINGER_TRANSACTION_QUERY_COLOR_MANAGEMENT,
- data, reply, 0);
- return reply.readBoolean();
- } catch (RemoteException ex) {
- Log.e(TAG, "Failed to query color management support", ex);
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- return false;
- }
- }
}
diff --git a/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java b/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java
index 8ad5e63..1710f51 100644
--- a/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java
@@ -17,7 +17,6 @@
package com.android.settings.display;
import android.content.Context;
-
import android.hardware.display.ColorDisplayManager;
import androidx.preference.DropDownPreference;
diff --git a/src/com/android/settings/flashlight/FlashlightSliceBuilder.java b/src/com/android/settings/flashlight/FlashlightSlice.java
similarity index 66%
rename from src/com/android/settings/flashlight/FlashlightSliceBuilder.java
rename to src/com/android/settings/flashlight/FlashlightSlice.java
index 5833229..a2c4561 100644
--- a/src/com/android/settings/flashlight/FlashlightSliceBuilder.java
+++ b/src/com/android/settings/flashlight/FlashlightSlice.java
@@ -28,6 +28,7 @@
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
+import android.net.Uri;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.util.Log;
@@ -41,69 +42,78 @@
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.slices.CustomSliceRegistry;
-import com.android.settings.slices.SliceBroadcastReceiver;
+import com.android.settings.slices.CustomSliceable;
/**
* Utility class to build a Flashlight Slice, and handle all associated actions.
*/
-public class FlashlightSliceBuilder {
+public class FlashlightSlice implements CustomSliceable {
- private static final String TAG = "FlashlightSliceBuilder";
-
- /**
- * Action notifying a change on the Flashlight Slice.
- */
- public static final String ACTION_FLASHLIGHT_SLICE_CHANGED =
- "com.android.settings.flashlight.action.FLASHLIGHT_SLICE_CHANGED";
+ private static final String TAG = "FlashlightSlice";
/**
* Action broadcasting a change on whether flashlight is on or off.
*/
- public static final String ACTION_FLASHLIGHT_CHANGED =
+ private static final String ACTION_FLASHLIGHT_CHANGED =
"com.android.settings.flashlight.action.FLASHLIGHT_CHANGED";
- public static final IntentFilter INTENT_FILTER = new IntentFilter(ACTION_FLASHLIGHT_CHANGED);
+ private final Context mContext;
- private FlashlightSliceBuilder() {
+ public FlashlightSlice(Context context) {
+ mContext = context;
}
- public static Slice getSlice(Context context) {
- if (!isFlashlightAvailable(context)) {
+ @Override
+ public Slice getSlice() {
+ if (!isFlashlightAvailable(mContext)) {
return null;
}
- final PendingIntent toggleAction = getBroadcastIntent(context);
- @ColorInt final int color = Utils.getColorAccentDefaultColor(context);
+ final PendingIntent toggleAction = getBroadcastIntent(mContext);
+ @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
final IconCompat icon =
- IconCompat.createWithResource(context, R.drawable.ic_signal_flashlight);
- return new ListBuilder(context, CustomSliceRegistry.FLASHLIGHT_SLICE_URI,
+ IconCompat.createWithResource(mContext, R.drawable.ic_signal_flashlight);
+ return new ListBuilder(mContext, CustomSliceRegistry.FLASHLIGHT_SLICE_URI,
ListBuilder.INFINITY)
.setAccentColor(color)
.addRow(new RowBuilder()
- .setTitle(context.getText(R.string.power_flashlight))
+ .setTitle(mContext.getText(R.string.power_flashlight))
.setTitleItem(icon, ICON_IMAGE)
.setPrimaryAction(
- SliceAction.createToggle(toggleAction, null, isFlashlightEnabled(context))))
+ SliceAction.createToggle(toggleAction, null,
+ isFlashlightEnabled(mContext))))
.build();
}
- /**
- * Update the current flashlight status to the boolean value keyed by
- * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
- */
- public static void handleUriChange(Context context, Intent intent) {
+ @Override
+ public Uri getUri() {
+ return CustomSliceRegistry.FLASHLIGHT_SLICE_URI;
+ }
+
+ @Override
+ public IntentFilter getIntentFilter() {
+ return new IntentFilter(ACTION_FLASHLIGHT_CHANGED);
+ }
+
+ @Override
+ public void onNotifyChange(Intent intent) {
try {
- final String cameraId = getCameraId(context);
+ final String cameraId = getCameraId(mContext);
if (cameraId != null) {
final boolean state = intent.getBooleanExtra(
- EXTRA_TOGGLE_STATE, isFlashlightEnabled(context));
- final CameraManager cameraManager = context.getSystemService(CameraManager.class);
+ EXTRA_TOGGLE_STATE, isFlashlightEnabled(mContext));
+ final CameraManager cameraManager = mContext.getSystemService(CameraManager.class);
cameraManager.setTorchMode(cameraId, state);
}
} catch (CameraAccessException e) {
Log.e(TAG, "Camera couldn't set torch mode.", e);
}
- context.getContentResolver().notifyChange(CustomSliceRegistry.FLASHLIGHT_SLICE_URI, null);
+ mContext.getContentResolver().notifyChange(CustomSliceRegistry.FLASHLIGHT_SLICE_URI, null);
+ }
+
+ @Override
+ public Intent getIntent() {
+ return null;
}
private static String getCameraId(Context context) throws CameraAccessException {
@@ -121,12 +131,6 @@
return null;
}
- private static PendingIntent getBroadcastIntent(Context context) {
- final Intent intent = new Intent(ACTION_FLASHLIGHT_SLICE_CHANGED);
- intent.setClass(context, SliceBroadcastReceiver.class);
- return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
- }
private static boolean isFlashlightAvailable(Context context) {
return Settings.Secure.getInt(
diff --git a/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java b/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java
index 2484e53..f8be2d6 100644
--- a/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java
@@ -16,9 +16,12 @@
package com.android.settings.homepage.contextualcards.deviceinfo;
+import static com.android.settings.accounts.EmergencyInfoPreferenceController.ACTION_EDIT_EMERGENCY_INFO;
+
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
@@ -27,37 +30,57 @@
import com.android.settings.R;
import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.slices.CustomSliceable;
// This is a slice helper class for EmergencyInfo
-public class EmergencyInfoSlice {
+public class EmergencyInfoSlice implements CustomSliceable {
- private static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENCY_INFO";
+ private final Context mContext;
- public static Slice getSlice(Context context) {
- final ListBuilder listBuilder = new ListBuilder(context,
+ public EmergencyInfoSlice(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public Slice getSlice() {
+ final ListBuilder listBuilder = new ListBuilder(mContext,
CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI,
ListBuilder.INFINITY);
listBuilder.addRow(
new ListBuilder.RowBuilder()
- .setTitle(context.getText(R.string.emergency_info_title))
+ .setTitle(mContext.getText(R.string.emergency_info_title))
.setSubtitle(
- context.getText(R.string.emergency_info_contextual_card_summary))
- .setPrimaryAction(createPrimaryAction(context)));
+ mContext.getText(R.string.emergency_info_contextual_card_summary))
+ .setPrimaryAction(createPrimaryAction()));
return listBuilder.build();
}
- private static SliceAction createPrimaryAction(Context context) {
- PendingIntent pendingIntent =
+ @Override
+ public Uri getUri() {
+ return CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI;
+ }
+
+ @Override
+ public Intent getIntent() {
+ return new Intent(ACTION_EDIT_EMERGENCY_INFO);
+ }
+
+ @Override
+ public void onNotifyChange(Intent intent) {
+ }
+
+ private SliceAction createPrimaryAction() {
+ final PendingIntent pendingIntent =
PendingIntent.getActivity(
- context,
+ mContext,
0 /* requestCode */,
- new Intent(ACTION_EDIT_EMERGENCY_INFO),
+ getIntent(),
PendingIntent.FLAG_UPDATE_CURRENT);
return SliceAction.createDeeplink(
pendingIntent,
- IconCompat.createWithResource(context, R.drawable.empty_icon),
+ IconCompat.createWithResource(mContext, R.drawable.empty_icon),
ListBuilder.ICON_IMAGE,
- context.getText(R.string.emergency_info_title));
+ mContext.getText(R.string.emergency_info_title));
}
}
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java
index 4378be3..8720a3c 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java
@@ -69,9 +69,9 @@
dbHelper.markContextualCardAsDismissed(mContext, card.getName());
});
showFeedbackDialog(card);
- final ContextualCardFeatureProvider contexualCardFeatureProvider =
+ final ContextualCardFeatureProvider contextualCardFeatureProvider =
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
- contexualCardFeatureProvider.logContextualCardDismiss(mContext, card);
+ contextualCardFeatureProvider.logContextualCardDismiss(mContext, card);
}
@Override
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index a2d6e2b..267fe4d 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -28,8 +28,11 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
+import androidx.lifecycle.OnLifecycleEvent;
import androidx.recyclerview.widget.RecyclerView;
import androidx.slice.Slice;
import androidx.slice.SliceItem;
@@ -51,13 +54,15 @@
* Card renderer for {@link ContextualCard} built as slices.
*/
public class SliceContextualCardRenderer implements ContextualCardRenderer,
- SliceView.OnSliceActionListener {
+ SliceView.OnSliceActionListener, LifecycleObserver {
public static final int VIEW_TYPE = R.layout.homepage_slice_tile;
private static final String TAG = "SliceCardRenderer";
@VisibleForTesting
- final Map<String, LiveData<Slice>> mSliceLiveDataMap;
+ final Map<Uri, LiveData<Slice>> mSliceLiveDataMap;
+ @VisibleForTesting
+ final Set<SliceViewHolder> mFlippedCardSet;
private final Context mContext;
private final LifecycleOwner mLifecycleOwner;
@@ -71,6 +76,8 @@
mSliceLiveDataMap = new ArrayMap<>();
mControllerRendererPool = controllerRendererPool;
mCardSet = new ArraySet<>();
+ mFlippedCardSet = new ArraySet<>();
+ mLifecycleOwner.getLifecycle().addObserver(this);
}
@Override
@@ -88,8 +95,6 @@
final SliceViewHolder cardHolder = (SliceViewHolder) holder;
final Uri uri = card.getSliceUri();
- //TODO(b/116063073): The URI check should be done earlier when we are performing final
- // filtering after having the full list.
if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Log.w(TAG, "Invalid uri, skipping slice: " + uri);
return;
@@ -99,11 +104,11 @@
cardHolder.sliceView.setTag(uri);
//TODO(b/114009676): We will soon have a field to decide what slice mode we should set.
cardHolder.sliceView.setMode(SliceView.MODE_LARGE);
- LiveData<Slice> sliceLiveData = mSliceLiveDataMap.get(uri.toString());
+ LiveData<Slice> sliceLiveData = mSliceLiveDataMap.get(uri);
if (sliceLiveData == null) {
sliceLiveData = SliceLiveData.fromUri(mContext, uri);
- mSliceLiveDataMap.put(uri.toString(), sliceLiveData);
+ mSliceLiveDataMap.put(uri, sliceLiveData);
}
mCardSet.add(card);
@@ -122,20 +127,24 @@
}
private void initDismissalActions(SliceViewHolder cardHolder, ContextualCard card) {
- final ViewFlipper viewFlipper = cardHolder.itemView.findViewById(R.id.viewFlipper);
cardHolder.sliceView.setOnLongClickListener(v -> {
- viewFlipper.showNext();
+ cardHolder.viewFlipper.showNext();
+ mFlippedCardSet.add(cardHolder);
return true;
});
final Button btnKeep = cardHolder.itemView.findViewById(R.id.keep);
btnKeep.setOnClickListener(v -> {
- viewFlipper.showPrevious();
+ cardHolder.resetCard();
+ mFlippedCardSet.remove(cardHolder);
});
final Button btnRemove = cardHolder.itemView.findViewById(R.id.remove);
btnRemove.setOnClickListener(v -> {
mControllerRendererPool.getController(mContext, card.getCardType()).onDismissed(card);
+ cardHolder.resetCard();
+ mFlippedCardSet.remove(cardHolder);
+ mSliceLiveDataMap.get(card.getSliceUri()).removeObservers(mLifecycleOwner);
});
}
@@ -158,12 +167,24 @@
}
}
+ @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+ public void onStop() {
+ mFlippedCardSet.stream().forEach(holder -> holder.resetCard());
+ mFlippedCardSet.clear();
+ }
+
public static class SliceViewHolder extends RecyclerView.ViewHolder {
public final SliceView sliceView;
+ public final ViewFlipper viewFlipper;
public SliceViewHolder(View view) {
super(view);
sliceView = view.findViewById(R.id.slice_view);
+ viewFlipper = view.findViewById(R.id.viewFlipper);
+ }
+
+ public void resetCard() {
+ viewFlipper.setDisplayedChild(0);
}
}
}
diff --git a/src/com/android/settings/location/LocationSliceBuilder.java b/src/com/android/settings/location/LocationSlice.java
similarity index 66%
rename from src/com/android/settings/location/LocationSliceBuilder.java
rename to src/com/android/settings/location/LocationSlice.java
index f70d09b..6dc4241 100644
--- a/src/com/android/settings/location/LocationSliceBuilder.java
+++ b/src/com/android/settings/location/LocationSlice.java
@@ -38,29 +38,31 @@
import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SliceBuilderUtils;
/**
* Utility class to build an intent-based Location Slice.
*/
-public class LocationSliceBuilder {
+public class LocationSlice implements CustomSliceable {
- private LocationSliceBuilder() {
+ private final Context mContext;
+
+ public LocationSlice(Context context) {
+ mContext = context;
}
- /**
- * Return a Location Slice bound to {@link CustomSliceRegistry#LOCATION_SLICE_URI}.
- */
- public static Slice getSlice(Context context) {
- final IconCompat icon = IconCompat.createWithResource(context,
+ @Override
+ public Slice getSlice() {
+ final IconCompat icon = IconCompat.createWithResource(mContext,
R.drawable.ic_signal_location);
- final String title = context.getString(R.string.location_settings_title);
- @ColorInt final int color = Utils.getColorAccentDefaultColor(context);
- final PendingIntent primaryAction = getPrimaryAction(context);
+ final CharSequence title = mContext.getText(R.string.location_settings_title);
+ @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
+ final PendingIntent primaryAction = getPrimaryAction();
final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon,
ListBuilder.ICON_IMAGE, title);
- return new ListBuilder(context, CustomSliceRegistry.LOCATION_SLICE_URI,
+ return new ListBuilder(mContext, CustomSliceRegistry.LOCATION_SLICE_URI,
ListBuilder.INFINITY)
.setAccentColor(color)
.addRow(new RowBuilder()
@@ -70,19 +72,30 @@
.build();
}
- public static Intent getIntent(Context context) {
- final String screenTitle = context.getText(R.string.location_settings_title).toString();
+ @Override
+ public Uri getUri() {
+ return CustomSliceRegistry.LOCATION_SLICE_URI;
+ }
+
+ @Override
+ public void onNotifyChange(Intent intent) {
+
+ }
+
+ @Override
+ public Intent getIntent() {
+ final String screenTitle = mContext.getText(R.string.location_settings_title).toString();
final Uri contentUri = new Uri.Builder().appendPath(KEY_LOCATION).build();
- return SliceBuilderUtils.buildSearchResultPageIntent(context,
+ return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
LocationSettings.class.getName(), KEY_LOCATION, screenTitle,
MetricsEvent.LOCATION)
- .setClassName(context.getPackageName(), SubSettings.class.getName())
+ .setClassName(mContext.getPackageName(), SubSettings.class.getName())
.setData(contentUri);
}
- private static PendingIntent getPrimaryAction(Context context) {
- final Intent intent = getIntent(context);
- return PendingIntent.getActivity(context, 0 /* requestCode */,
+ private PendingIntent getPrimaryAction() {
+ final Intent intent = getIntent();
+ return PendingIntent.getActivity(mContext, 0 /* requestCode */,
intent, 0 /* flags */);
}
}
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index b1124f8..9ebeda0 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -22,7 +22,6 @@
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
-import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -131,16 +130,12 @@
@VisibleForTesting
boolean isDialogNeeded() {
final boolean enableData = !mTelephonyManager.isDataEnabled();
- final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(
- mSubId);
- final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
final boolean isMultiSim = (mTelephonyManager.getSimCount() > 1);
- final boolean isMultipleDataOnCapable =
- (mTelephonyManager.getNumberOfModemsWithSimultaneousDataConnections() > 1);
- final boolean isDefaultDataSubscription = (nextSir != null && currentSir != null
- && currentSir.getSubscriptionId() == nextSir.getSubscriptionId());
+ final int defaultSubId = mSubscriptionManager.getDefaultDataSubscriptionId();
+ final boolean needToDisableOthers = mSubscriptionManager
+ .isActiveSubscriptionId(defaultSubId) && defaultSubId != mSubId;
if (enableData) {
- if (isMultiSim && !isMultipleDataOnCapable && !isDefaultDataSubscription) {
+ if (isMultiSim && needToDisableOthers) {
mDialogType = MobileDataDialogFragment.TYPE_MULTI_SIM_DIALOG;
return true;
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
index dc184d3..27cc367 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
@@ -230,7 +230,8 @@
subscriptionManager.getActiveSubscriptionInfoList();
if (subInfoList != null) {
for (SubscriptionInfo subInfo : subInfoList) {
- if (subInfo.getSubscriptionId() != subId) {
+ // We never disable mobile data for opportunistic subscriptions.
+ if (subInfo.getSubscriptionId() != subId && !subInfo.isOpportunistic()) {
context.getSystemService(TelephonyManager.class).createForSubscriptionId(
subInfo.getSubscriptionId()).setDataEnabled(false);
}
diff --git a/src/com/android/settings/slices/CustomSliceManager.java b/src/com/android/settings/slices/CustomSliceManager.java
index bef72b7..8f8ee96 100644
--- a/src/com/android/settings/slices/CustomSliceManager.java
+++ b/src/com/android/settings/slices/CustomSliceManager.java
@@ -22,13 +22,16 @@
import androidx.annotation.VisibleForTesting;
+import com.android.settings.flashlight.FlashlightSlice;
import com.android.settings.homepage.contextualcards.deviceinfo.BatterySlice;
import com.android.settings.homepage.contextualcards.deviceinfo.DataUsageSlice;
import com.android.settings.homepage.contextualcards.deviceinfo.DeviceInfoSlice;
+import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice;
import com.android.settings.homepage.contextualcards.deviceinfo.StorageSlice;
import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice;
import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
+import com.android.settings.location.LocationSlice;
import com.android.settings.wifi.WifiSlice;
import java.util.Map;
@@ -106,6 +109,9 @@
mUriMap.put(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI, ConnectedDeviceSlice.class);
mUriMap.put(CustomSliceRegistry.DATA_USAGE_SLICE_URI, DataUsageSlice.class);
mUriMap.put(CustomSliceRegistry.DEVICE_INFO_SLICE_URI, DeviceInfoSlice.class);
+ mUriMap.put(CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI, EmergencyInfoSlice.class);
+ mUriMap.put(CustomSliceRegistry.FLASHLIGHT_SLICE_URI, FlashlightSlice.class);
+ mUriMap.put(CustomSliceRegistry.LOCATION_SLICE_URI, LocationSlice.class);
mUriMap.put(CustomSliceRegistry.LOW_STORAGE_SLICE_URI, LowStorageSlice.class);
mUriMap.put(CustomSliceRegistry.STORAGE_SLICE_URI, StorageSlice.class);
mUriMap.put(CustomSliceRegistry.WIFI_SLICE_URI, WifiSlice.class);
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 109f02e..80b7133 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -41,9 +41,6 @@
import com.android.settings.R;
import com.android.settings.bluetooth.BluetoothSliceBuilder;
import com.android.settings.core.BasePreferenceController;
-import com.android.settings.flashlight.FlashlightSliceBuilder;
-import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice;
-import com.android.settings.location.LocationSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.SliceBroadcastRelay;
@@ -182,12 +179,6 @@
} else if (CustomSliceRegistry.BLUETOOTH_URI.equals(sliceUri)) {
registerIntentToUri(BluetoothSliceBuilder.INTENT_FILTER, sliceUri);
return;
- } else if (CustomSliceRegistry.FLASHLIGHT_SLICE_URI.equals(sliceUri)) {
- registerIntentToUri(FlashlightSliceBuilder.INTENT_FILTER, sliceUri);
- mRegisteredUris.add(sliceUri);
- return;
- } else if (CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI.equals(sliceUri)) {
- return;
}
// Start warming the slice, we expect someone will want it soon.
@@ -240,8 +231,6 @@
return ZenModeSliceBuilder.getSlice(getContext());
} else if (CustomSliceRegistry.BLUETOOTH_URI.equals(sliceUri)) {
return BluetoothSliceBuilder.getSlice(getContext());
- } else if (CustomSliceRegistry.LOCATION_SLICE_URI.equals(sliceUri)) {
- return LocationSliceBuilder.getSlice(getContext());
} else if (CustomSliceRegistry.ENHANCED_4G_SLICE_URI.equals(sliceUri)) {
return FeatureFactory.getFactory(getContext())
.getSlicesFeatureProvider()
@@ -252,10 +241,6 @@
.getSlicesFeatureProvider()
.getNewWifiCallingSliceHelper(getContext())
.createWifiCallingPreferenceSlice(sliceUri);
- } else if (CustomSliceRegistry.FLASHLIGHT_SLICE_URI.equals(sliceUri)) {
- return FlashlightSliceBuilder.getSlice(getContext());
- } else if (CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI.equals(sliceUri)) {
- return EmergencyInfoSlice.getSlice(getContext());
}
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index 2860e9a..823c729 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -17,7 +17,6 @@
package com.android.settings.slices;
import static com.android.settings.bluetooth.BluetoothSliceBuilder.ACTION_BLUETOOTH_SLICE_CHANGED;
-import static com.android.settings.flashlight.FlashlightSliceBuilder.ACTION_FLASHLIGHT_SLICE_CHANGED;
import static com.android.settings.network.telephony.Enhanced4gLteSliceHelper.ACTION_ENHANCED_4G_LTE_CHANGED;
import static com.android.settings.notification.ZenModeSliceBuilder.ACTION_ZEN_MODE_SLICE_CHANGED;
import static com.android.settings.slices.SettingsSliceProvider.ACTION_COPY;
@@ -46,7 +45,6 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.SliderPreferenceController;
import com.android.settings.core.TogglePreferenceController;
-import com.android.settings.flashlight.FlashlightSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.overlay.FeatureFactory;
@@ -108,9 +106,6 @@
.getNewWifiCallingSliceHelper(context)
.handleWifiCallingPreferenceChanged(intent);
break;
- case ACTION_FLASHLIGHT_SLICE_CHANGED:
- FlashlightSliceBuilder.handleUriChange(context, intent);
- break;
case ACTION_COPY:
handleCopyAction(context, key, isPlatformSlice);
break;
diff --git a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
index 01708af..d633b7a 100644
--- a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
+++ b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
@@ -24,7 +24,6 @@
import androidx.annotation.Keep;
import com.android.settings.bluetooth.BluetoothSliceBuilder;
-import com.android.settings.location.LocationSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.overlay.FeatureFactory;
@@ -66,8 +65,6 @@
launchIntent = ZenModeSliceBuilder.getIntent(this /* context */);
} else if (CustomSliceRegistry.BLUETOOTH_URI.equals(sliceUri)) {
launchIntent = BluetoothSliceBuilder.getIntent(this /* context */);
- } else if (CustomSliceRegistry.LOCATION_SLICE_URI.equals(sliceUri)) {
- launchIntent = LocationSliceBuilder.getIntent(this /* context */);
} else {
final SlicesDatabaseAccessor slicesDatabaseAccessor =
new SlicesDatabaseAccessor(this /* context */);
diff --git a/src/com/android/settings/widget/FloatingAppBarScrollingViewBehavior.java b/src/com/android/settings/widget/FloatingAppBarScrollingViewBehavior.java
new file mode 100644
index 0000000..23f6ccd
--- /dev/null
+++ b/src/com/android/settings/widget/FloatingAppBarScrollingViewBehavior.java
@@ -0,0 +1,61 @@
+/*
+ * 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.widget;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
+
+import com.google.android.material.appbar.AppBarLayout;
+
+/**
+ * This scrolling view behavior will set the background of the {@link AppBarLayout} as
+ * transparent and without the elevation. Also make header overlapped the scrolling child view.
+ */
+public class FloatingAppBarScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior {
+ private boolean initialized;
+
+ public FloatingAppBarScrollingViewBehavior(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
+ boolean changed = super.onDependentViewChanged(parent, child, dependency);
+ if (!initialized && dependency instanceof AppBarLayout) {
+ initialized = true;
+ AppBarLayout appBarLayout = (AppBarLayout) dependency;
+ setAppBarLayoutTransparent(appBarLayout);
+ }
+ return changed;
+ }
+
+ @VisibleForTesting
+ void setAppBarLayoutTransparent(AppBarLayout appBarLayout) {
+ appBarLayout.setBackgroundColor(Color.TRANSPARENT);
+ appBarLayout.setTargetElevation(0);
+ }
+
+ @Override
+ protected boolean shouldHeaderOverlapScrollingChild() {
+ return true;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceBuilderTest.java b/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceTest.java
similarity index 94%
rename from tests/robotests/src/com/android/settings/flashlight/FlashlightSliceBuilderTest.java
rename to tests/robotests/src/com/android/settings/flashlight/FlashlightSliceTest.java
index 56a84bb..4af5754 100644
--- a/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceBuilderTest.java
+++ b/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceTest.java
@@ -42,7 +42,7 @@
@RunWith(SettingsRobolectricTestRunner.class)
-public class FlashlightSliceBuilderTest {
+public class FlashlightSliceTest {
private Context mContext;
@@ -58,7 +58,7 @@
public void getFlashlightSlice_correctData() {
Settings.Secure.putInt(
mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
- final Slice slice = FlashlightSliceBuilder.getSlice(mContext);
+ final Slice slice = new FlashlightSlice(mContext).getSlice();
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
final List<SliceAction> toggles = metadata.getToggles();
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
index 13a2bc5..7d71302 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import android.app.Activity;
@@ -51,10 +52,14 @@
@RunWith(SettingsRobolectricTestRunner.class)
public class SliceContextualCardRendererTest {
+ private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test");
+
@Mock
private LiveData<Slice> mSliceLiveData;
@Mock
private ControllerRendererPool mControllerRendererPool;
+ @Mock
+ private SliceContextualCardController mController;
private Activity mActivity;
private SliceContextualCardRenderer mRenderer;
@@ -75,10 +80,9 @@
@Test
public void bindView_shouldSetScrollableToFalse() {
- final String sliceUri = "content://com.android.settings.slices/action/flashlight";
RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
- mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
+ mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
assertThat(
((SliceContextualCardRenderer.SliceViewHolder) viewHolder).sliceView.isScrollable
@@ -87,7 +91,7 @@
@Test
public void bindView_invalidScheme_sliceShouldBeNull() {
- final String sliceUri = "contet://com.android.settings.slices/action/flashlight";
+ final Uri sliceUri = Uri.parse("contet://com.android.settings.slices/action/flashlight");
RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
@@ -99,64 +103,124 @@
@Test
public void bindView_newSliceLiveData_shouldAddDataToMap() {
- final String sliceUri = "content://com.android.settings.slices/action/flashlight";
-
- mRenderer.bindView(getSliceViewHolder(), buildContextualCard(sliceUri));
+ mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
assertThat(mRenderer.mSliceLiveDataMap.size()).isEqualTo(1);
}
@Test
public void bindView_sliceLiveDataShouldObserveSliceView() {
- final String sliceUri = "content://com.android.settings.slices/action/flashlight";
+ mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
- mRenderer.bindView(getSliceViewHolder(), buildContextualCard(sliceUri));
-
- assertThat(mRenderer.mSliceLiveDataMap.get(sliceUri).hasObservers()).isTrue();
+ assertThat(mRenderer.mSliceLiveDataMap.get(TEST_SLICE_URI).hasObservers()).isTrue();
}
@Test
public void bindView_sliceLiveDataShouldRemoveObservers() {
- final String sliceUri = "content://com.android.settings.slices/action/flashlight";
- mRenderer.mSliceLiveDataMap.put(sliceUri, mSliceLiveData);
+ mRenderer.mSliceLiveDataMap.put(TEST_SLICE_URI, mSliceLiveData);
- mRenderer.bindView(getSliceViewHolder(), buildContextualCard(sliceUri));
+ mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
verify(mSliceLiveData).removeObservers(mLifecycleOwner);
}
@Test
public void longClick_shouldFlipCard() {
- final String sliceUri = "content://com.android.settings.slices/action/flashlight";
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
final View card = viewHolder.itemView.findViewById(R.id.slice_view);
final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.viewFlipper);
final View dismissalView = viewHolder.itemView.findViewById(R.id.dismissal_view);
- mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
+ mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
- assertThat(card).isNotNull();
card.performLongClick();
assertThat(viewFlipper.getCurrentView()).isEqualTo(dismissalView);
}
@Test
+ public void longClick_shouldAddViewHolderToSet() {
+ final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+ final View card = viewHolder.itemView.findViewById(R.id.slice_view);
+ mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+
+ card.performLongClick();
+
+ assertThat(mRenderer.mFlippedCardSet).contains(viewHolder);
+ }
+
+ @Test
public void viewClick_keepCard_shouldFlipBackToSlice() {
- final String sliceUri = "content://com.android.settings.slices/action/flashlight";
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
final View card = viewHolder.itemView.findViewById(R.id.slice_view);
final Button btnKeep = viewHolder.itemView.findViewById(R.id.keep);
final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.viewFlipper);
- mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
+ mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
- assertThat(card).isNotNull();
card.performLongClick();
- assertThat(btnKeep).isNotNull();
btnKeep.performClick();
assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
}
+ @Test
+ public void viewClick_keepCard_shouldRemoveViewHolderFromSet() {
+ final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+ final View card = viewHolder.itemView.findViewById(R.id.slice_view);
+ final Button btnKeep = viewHolder.itemView.findViewById(R.id.keep);
+ mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+
+ card.performLongClick();
+ btnKeep.performClick();
+
+ assertThat(mRenderer.mFlippedCardSet).doesNotContain(viewHolder);
+ }
+
+ @Test
+ public void viewClick_removeCard_shouldRemoveViewHolderFromSet() {
+ final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+ final View card = viewHolder.itemView.findViewById(R.id.slice_view);
+ final Button btnRemove = viewHolder.itemView.findViewById(R.id.remove);
+ final ContextualCard contextualCard = buildContextualCard(TEST_SLICE_URI);
+ mRenderer.bindView(viewHolder, contextualCard);
+ doReturn(mController).when(mControllerRendererPool).getController(mActivity,
+ ContextualCard.CardType.SLICE);
+
+ card.performLongClick();
+ btnRemove.performClick();
+
+ assertThat(mRenderer.mFlippedCardSet).doesNotContain(viewHolder);
+ }
+
+ @Test
+ public void viewClick_removeCard_sliceLiveDataShouldRemoveObservers() {
+ final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+ final View card = viewHolder.itemView.findViewById(R.id.slice_view);
+ final Button btnRemove = viewHolder.itemView.findViewById(R.id.remove);
+ final ContextualCard contextualCard = buildContextualCard(TEST_SLICE_URI);
+ mRenderer.mSliceLiveDataMap.put(TEST_SLICE_URI, mSliceLiveData);
+ mRenderer.bindView(viewHolder, contextualCard);
+ doReturn(mController).when(mControllerRendererPool).getController(mActivity,
+ ContextualCard.CardType.SLICE);
+
+ card.performLongClick();
+ btnRemove.performClick();
+
+ assertThat(mRenderer.mSliceLiveDataMap.get(TEST_SLICE_URI).hasObservers()).isFalse();
+ }
+
+ @Test
+ public void onStop_cardIsFlipped_shouldFlipBack() {
+ final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+ final View card = viewHolder.itemView.findViewById(R.id.slice_view);
+ final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.viewFlipper);
+ mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+
+ card.performLongClick();
+ mRenderer.onStop();
+
+ assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
+ }
+
private RecyclerView.ViewHolder getSliceViewHolder() {
final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
final RecyclerView recyclerView = new RecyclerView(mActivity);
@@ -166,10 +230,11 @@
return mRenderer.createViewHolder(view);
}
- private ContextualCard buildContextualCard(String sliceUri) {
+ private ContextualCard buildContextualCard(Uri sliceUri) {
return new ContextualCard.Builder()
.setName("test_name")
- .setSliceUri(Uri.parse(sliceUri))
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setSliceUri(sliceUri)
.build();
}
}
diff --git a/tests/robotests/src/com/android/settings/location/LocationSliceBuilderTest.java b/tests/robotests/src/com/android/settings/location/LocationSliceTest.java
similarity index 93%
rename from tests/robotests/src/com/android/settings/location/LocationSliceBuilderTest.java
rename to tests/robotests/src/com/android/settings/location/LocationSliceTest.java
index ecbf858..8f1045a 100644
--- a/tests/robotests/src/com/android/settings/location/LocationSliceBuilderTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationSliceTest.java
@@ -24,7 +24,7 @@
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
-public class LocationSliceBuilderTest {
+public class LocationSliceTest {
private Context mContext;
@@ -38,7 +38,7 @@
@Test
public void getLocationSlice_correctSliceContent() {
- final Slice LocationSlice = LocationSliceBuilder.getSlice(mContext);
+ final Slice LocationSlice = new LocationSlice(mContext).getSlice();
final SliceMetadata metadata = SliceMetadata.from(mContext, LocationSlice);
final List<SliceAction> toggles = metadata.getToggles();
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
index 2fc3d98..e1ad93b 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
@@ -20,6 +20,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -104,9 +105,8 @@
public void isDialogNeeded_enableNonDefaultSimInMultiSimMode_returnTrue() {
doReturn(false).when(mTelephonyManager).isDataEnabled();
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
- doReturn(null).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
+ doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(anyInt());
doReturn(2).when(mTelephonyManager).getSimCount();
- doReturn(1).when(mTelephonyManager).getNumberOfModemsWithSimultaneousDataConnections();
assertThat(mController.isDialogNeeded()).isTrue();
assertThat(mController.mDialogType).isEqualTo(
diff --git a/tests/robotests/src/com/android/settings/widget/FloatingAppBarScrollingViewBehaviorTest.java b/tests/robotests/src/com/android/settings/widget/FloatingAppBarScrollingViewBehaviorTest.java
new file mode 100644
index 0000000..6acc4d9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/widget/FloatingAppBarScrollingViewBehaviorTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import com.google.android.material.appbar.AppBarLayout;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class FloatingAppBarScrollingViewBehaviorTest {
+
+ private FloatingAppBarScrollingViewBehavior mScrollingViewBehavior;
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mScrollingViewBehavior = new FloatingAppBarScrollingViewBehavior(mContext,
+ Robolectric.buildAttributeSet().build());
+ }
+
+ @Test
+ public void shouldHeaderOverlapScrollingChild_returnTrue() {
+ assertThat(mScrollingViewBehavior.shouldHeaderOverlapScrollingChild()).isTrue();
+ }
+
+ @Test
+ public void setAppBarLayoutTransparent_backgroundDefaultAsWhite_shouldBeTransparent() {
+ mContext.setTheme(R.style.Theme_Settings_Home);
+ final AppBarLayout appBarLayout = new AppBarLayout(mContext);
+ appBarLayout.setBackgroundColor(Color.WHITE);
+ mScrollingViewBehavior.setAppBarLayoutTransparent(appBarLayout);
+ assertThat(((ColorDrawable) appBarLayout.getBackground()).getColor()).isEqualTo(
+ Color.TRANSPARENT);
+ }
+}