diff --git a/res/drawable-night/ic_enhanced_connectivity.xml b/res/drawable-night/ic_enhanced_connectivity.xml
new file mode 100644
index 00000000000..cd256676316
--- /dev/null
+++ b/res/drawable-night/ic_enhanced_connectivity.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/ic_enhanced_connectivity.xml b/res/drawable/ic_enhanced_connectivity.xml
new file mode 100644
index 00000000000..45767bd7d44
--- /dev/null
+++ b/res/drawable/ic_enhanced_connectivity.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/accessibility_autoclick_preview.xml b/res/layout/accessibility_autoclick_preview.xml
deleted file mode 100644
index 4fa3f8ff8a0..00000000000
--- a/res/layout/accessibility_autoclick_preview.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/res/layout/fingerprint_enroll_introduction.xml b/res/layout/fingerprint_enroll_introduction.xml
index 65c1497d9ff..5f828799269 100644
--- a/res/layout/fingerprint_enroll_introduction.xml
+++ b/res/layout/fingerprint_enroll_introduction.xml
@@ -98,7 +98,7 @@
android:paddingTop="24dp">
-
+ android:elevation="2dp"
+ settings:layout_constraintTop_toTopOf="parent"/>
-
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:scrollbars="none"
+ android:visibility="invisible"
+ settings:fastScrollEnabled="true"
+ settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
+ settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
+ settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
+ settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"
+ settings:layout_constraintTop_toBottomOf="@id/pinned_header"/>
-
+
-
-
-
-
-
-
-
+
+
diff --git a/res/layout/preference_animated_image.xml b/res/layout/preference_animated_image.xml
deleted file mode 100644
index 64cfc982ef7..00000000000
--- a/res/layout/preference_animated_image.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/raw/lottie_swipe_for_notifications.json b/res/raw/lottie_swipe_for_notifications.json
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index fe0ada08622..1b8179abdaf 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -149,8 +149,6 @@
182dp
32dp
24dp
-
- 80dp
88dip
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aeaea6116b8..26fbd795575 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -926,16 +926,8 @@
Cancel
No thanks
-
- No thanks
-
- Continue
I agree
-
- Skip
-
- Next
Skip fingerprint?
@@ -12892,6 +12884,8 @@
Restart
No thanks
+
+ Cancel
Switch
@@ -13389,7 +13383,7 @@
No connection
- Internet won\u0027t auto\u2011connect
+ Mobile data won\u0027t auto\u2011connect
No other networks available
diff --git a/res/xml/accessibility_autoclick_settings.xml b/res/xml/accessibility_autoclick_settings.xml
index ee27cea24e5..06b3dced4e2 100644
--- a/res/xml/accessibility_autoclick_settings.xml
+++ b/res/xml/accessibility_autoclick_settings.xml
@@ -19,14 +19,13 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/accessibility_autoclick_preference_title">
-
+ settings:searchable="false"
+ settings:lottie_rawRes="@drawable/accessibility_dwell" />
-
+
-
+
+
diff --git a/src/com/android/settings/accessibility/AnimatedImagePreference.java b/src/com/android/settings/accessibility/AnimatedImagePreference.java
deleted file mode 100644
index c707e5cc0a7..00000000000
--- a/src/com/android/settings/accessibility/AnimatedImagePreference.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.accessibility;
-
-import android.content.Context;
-import android.graphics.drawable.Animatable;
-import android.graphics.drawable.Animatable2;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-
-import com.airbnb.lottie.LottieAnimationView;
-import com.airbnb.lottie.LottieDrawable;
-
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.Objects;
-
-/**
- * A custom {@link ImageView} preference for showing animated or static image, such as animated webp and static png.
- */
-public class AnimatedImagePreference extends Preference {
-
- private static final String TAG = "AnimatedImagePreference";
- private Uri mImageUri;
- private int mMaxHeight = -1;
-
- private final Animatable2.AnimationCallback mAnimationCallback =
- new Animatable2.AnimationCallback() {
- @Override
- public void onAnimationEnd(Drawable drawable) {
- ((Animatable2) drawable).start();
- }
- };
-
- AnimatedImagePreference(Context context) {
- super(context);
- setLayoutResource(R.layout.preference_animated_image);
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder holder) {
- super.onBindViewHolder(holder);
-
- final ImageView imageView = holder.itemView.findViewById(R.id.animated_img);
- final LottieAnimationView lottieView = holder.itemView.findViewById(R.id.lottie_view);
- if (imageView == null || lottieView == null) {
- return;
- }
-
- if (mImageUri != null) {
- resetAnimations(imageView, lottieView);
- hideAllChildViews(holder.itemView);
-
- imageView.setImageURI(mImageUri);
- if (imageView.getDrawable() != null) {
- startAnimationWith(imageView);
- } else {
- // The lottie image from the raw folder also returns null.
- startLottieAnimationWith(lottieView);
- }
- }
-
- if (mMaxHeight > -1) {
- imageView.setMaxHeight(mMaxHeight);
- lottieView.setMaxHeight(mMaxHeight);
- }
- }
-
- /**
- * Sets image uri to display image in {@link ImageView}
- *
- * @param imageUri the Uri of an image
- */
- public void setImageUri(Uri imageUri) {
- if (imageUri != null && !imageUri.equals(mImageUri)) {
- mImageUri = imageUri;
- notifyChanged();
- }
- }
-
- /**
- * Sets the maximum height of the view.
- *
- * @param maxHeight the maximum height of ImageView in terms of pixels.
- */
- public void setMaxHeight(int maxHeight) {
- if (maxHeight != mMaxHeight) {
- mMaxHeight = maxHeight;
- notifyChanged();
- }
- }
-
- private void startAnimationWith(ImageView imageView) {
- startAnimation(imageView.getDrawable());
-
- imageView.setVisibility(View.VISIBLE);
- }
-
- private void startLottieAnimationWith(LottieAnimationView lottieView) {
- final InputStream inputStream = getInputStreamFromUri(mImageUri);
- Objects.requireNonNull(inputStream, "Invalid resource.");
- lottieView.setAnimation(inputStream, /* cacheKey= */ null);
- lottieView.setRepeatCount(LottieDrawable.INFINITE);
- lottieView.playAnimation();
-
- lottieView.setVisibility(View.VISIBLE);
- }
-
- private void startAnimation(Drawable drawable) {
- if (!(drawable instanceof Animatable)) {
- return;
- }
-
- if (drawable instanceof Animatable2) {
- ((Animatable2) drawable).registerAnimationCallback(mAnimationCallback);
- } else if (drawable instanceof AnimationDrawable) {
- ((AnimationDrawable) drawable).setOneShot(false);
- }
-
- ((Animatable) drawable).start();
- }
-
- private void resetAnimations(ImageView imageView, LottieAnimationView lottieView) {
- resetAnimation(imageView.getDrawable());
-
- lottieView.cancelAnimation();
- }
-
- private void resetAnimation(Drawable drawable) {
- if (!(drawable instanceof Animatable)) {
- return;
- }
-
- if (drawable instanceof Animatable2) {
- ((Animatable2) drawable).clearAnimationCallbacks();
- }
-
- ((Animatable) drawable).stop();
- }
-
- private InputStream getInputStreamFromUri(Uri uri) {
- try {
- return getContext().getContentResolver().openInputStream(uri);
- } catch (FileNotFoundException e) {
- Log.w(TAG, "Cannot find content uri: " + uri, e);
- return null;
- }
- }
-
- private void hideAllChildViews(View itemView) {
- final ViewGroup viewGroup = (ViewGroup) itemView;
- for (int i = 0; i < viewGroup.getChildCount(); i++) {
- viewGroup.getChildAt(i).setVisibility(View.GONE);
- }
- }
-}
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 640ae532161..510f8d3484a 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -59,6 +59,7 @@ import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settings.widget.SettingsMainSwitchPreference;
import com.android.settingslib.HelpUtils;
import com.android.settingslib.accessibility.AccessibilityUtils;
+import com.android.settingslib.widget.IllustrationPreference;
import com.android.settingslib.widget.OnMainSwitchChangeListener;
import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -398,15 +399,13 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
return;
}
- final int screenHalfHeight = AccessibilityUtil.getScreenHeightPixels(getPrefContext()) / 2;
- final AnimatedImagePreference animatedImagePreference =
- new AnimatedImagePreference(getPrefContext());
- animatedImagePreference.setImageUri(mImageUri);
- animatedImagePreference.setSelectable(false);
- animatedImagePreference.setMaxHeight(screenHalfHeight);
- animatedImagePreference.setKey(KEY_ANIMATED_IMAGE);
+ final IllustrationPreference illustrationPreference =
+ new IllustrationPreference(getPrefContext());
+ illustrationPreference.setImageUri(mImageUri);
+ illustrationPreference.setSelectable(false);
+ illustrationPreference.setKey(KEY_ANIMATED_IMAGE);
- getPreferenceScreen().addPreference(animatedImagePreference);
+ getPreferenceScreen().addPreference(illustrationPreference);
}
private void initToggleServiceSwitchPreference() {
diff --git a/src/com/android/settings/applications/RunningServices.java b/src/com/android/settings/applications/RunningServices.java
index 4d13241126f..b1689d5c591 100644
--- a/src/com/android/settings/applications/RunningServices.java
+++ b/src/com/android/settings/applications/RunningServices.java
@@ -72,7 +72,11 @@ public class RunningServices extends SettingsPreferenceFragment {
public void onResume() {
super.onResume();
boolean haveData = mRunningProcessesView.doResume(this, mRunningProcessesAvail);
- mLoadingViewController.handleLoadingContainer(haveData /* done */, false /* animate */);
+ if (haveData) {
+ mLoadingViewController.showContent(false /* animate */);
+ } else {
+ mLoadingViewController.showLoadingView();
+ }
}
@Override
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java
index fd6f4c243e7..d962692e2df 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java
@@ -65,11 +65,19 @@ public abstract class DefaultAppPreferenceController extends AbstractPreferenceC
((TwoTargetPreference) preference).setIconSize(ICON_SIZE_MEDIUM);
}
if (!TextUtils.isEmpty(defaultAppLabel)) {
- preference.setSummary(defaultAppLabel);
+ if (showLabelAsTitle()) {
+ preference.setTitle(defaultAppLabel);
+ } else {
+ preference.setSummary(defaultAppLabel);
+ }
preference.setIcon(Utils.getSafeIcon(getDefaultAppIcon()));
} else {
Log.d(TAG, "No default app");
- preference.setSummary(R.string.app_list_preference_none);
+ if (showLabelAsTitle()) {
+ preference.setTitle(R.string.app_list_preference_none);
+ } else {
+ preference.setSummary(R.string.app_list_preference_none);
+ }
preference.setIcon(null);
}
mayUpdateGearIcon(app, preference);
@@ -102,6 +110,13 @@ public abstract class DefaultAppPreferenceController extends AbstractPreferenceC
return null;
}
+ /**
+ * Whether to show the default app label as the title, instead of as the summary.
+ */
+ protected boolean showLabelAsTitle() {
+ return false;
+ }
+
public Drawable getDefaultAppIcon() {
if (!isAvailable()) {
return null;
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java
index d32322b6fdb..1493e302881 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java
@@ -69,4 +69,9 @@ public class DefaultAutofillPreferenceController extends DefaultAppPreferenceCon
}
return null;
}
+
+ @Override
+ protected boolean showLabelAsTitle() {
+ return true;
+ }
}
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 6d675240b64..43e929b8054 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -208,7 +208,6 @@ public class ManageApplications extends InstrumentedFragment
private ApplicationsAdapter mApplications;
private View mLoadingContainer;
- private View mListContainer;
private SearchView mSearchView;
// Size resource used for packages whose size computation failed for some reason
@@ -402,25 +401,21 @@ public class ManageApplications extends InstrumentedFragment
mRootView = inflater.inflate(R.layout.manage_applications_apps, null);
mLoadingContainer = mRootView.findViewById(R.id.loading_container);
- mListContainer = mRootView.findViewById(R.id.list_container);
- if (mListContainer != null) {
- // Create adapter and list view here
- mEmptyView = mListContainer.findViewById(android.R.id.empty);
+ mEmptyView = mRootView.findViewById(android.R.id.empty);
+ mRecyclerView = mRootView.findViewById(R.id.apps_list);
- mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter,
- savedInstanceState);
- if (savedInstanceState != null) {
- mApplications.mHasReceivedLoadEntries =
- savedInstanceState.getBoolean(EXTRA_HAS_ENTRIES, false);
- mApplications.mHasReceivedBridgeCallback =
- savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false);
- }
- mRecyclerView = mListContainer.findViewById(R.id.apps_list);
- mRecyclerView.setItemAnimator(null);
- mRecyclerView.setLayoutManager(new LinearLayoutManager(
- getContext(), RecyclerView.VERTICAL, false /* reverseLayout */));
- mRecyclerView.setAdapter(mApplications);
+ mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter,
+ savedInstanceState);
+ if (savedInstanceState != null) {
+ mApplications.mHasReceivedLoadEntries =
+ savedInstanceState.getBoolean(EXTRA_HAS_ENTRIES, false);
+ mApplications.mHasReceivedBridgeCallback =
+ savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false);
}
+ mRecyclerView.setItemAnimator(null);
+ mRecyclerView.setLayoutManager(new LinearLayoutManager(
+ getContext(), RecyclerView.VERTICAL, false /* reverseLayout */));
+ mRecyclerView.setAdapter(mApplications);
// We have to do this now because PreferenceFrameLayout looks at it
// only when the view is added.
@@ -985,16 +980,8 @@ public class ManageApplications extends InstrumentedFragment
// overlapped by floating filter.
if (hasFilter) {
mManageApplications.mSpinnerHeader.setVisibility(View.VISIBLE);
- mManageApplications.mRecyclerView.setPadding(0 /* left */,
- mContext.getResources().getDimensionPixelSize(
- R.dimen.app_bar_height) /* top */,
- 0 /* right */,
- 0 /* bottom */);
} else {
mManageApplications.mSpinnerHeader.setVisibility(View.GONE);
- mManageApplications.mRecyclerView.setPadding(0 /* left */, 0 /* top */,
- 0 /* right */,
- 0 /* bottom */);
}
}
}
@@ -1044,7 +1031,8 @@ public class ManageApplications extends InstrumentedFragment
mManageApplications = manageApplications;
mLoadingViewController = new LoadingViewController(
mManageApplications.mLoadingContainer,
- mManageApplications.mListContainer
+ mManageApplications.mRecyclerView,
+ mManageApplications.mEmptyView
);
mContext = manageApplications.getActivity();
mIconDrawableFactory = IconDrawableFactory.newInstance(mContext);
@@ -1303,11 +1291,9 @@ public class ManageApplications extends InstrumentedFragment
mOriginalEntries = entries;
notifyDataSetChanged();
if (getItemCount() == 0) {
- mManageApplications.mRecyclerView.setVisibility(View.GONE);
- mManageApplications.mEmptyView.setVisibility(View.VISIBLE);
+ mLoadingViewController.showEmpty(false /* animate */);
} else {
- mManageApplications.mEmptyView.setVisibility(View.GONE);
- mManageApplications.mRecyclerView.setVisibility(View.VISIBLE);
+ mLoadingViewController.showContent(false /* animate */);
if (mManageApplications.mSearchView != null
&& mManageApplications.mSearchView.isVisibleToUser()) {
@@ -1324,10 +1310,6 @@ public class ManageApplications extends InstrumentedFragment
mLastIndex = -1;
}
- if (mSession.getAllApps().size() != 0
- && mManageApplications.mListContainer.getVisibility() != View.VISIBLE) {
- mLoadingViewController.showContent(true /* animate */);
- }
if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
// No enabled or disabled filters for usage access.
return;
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
index 8c3b1ceb89a..a75fb0f4526 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
@@ -64,9 +64,13 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
super.onCreate(savedInstanceState);
final ImageView iconFingerprint = findViewById(R.id.icon_fingerprint);
+ final ImageView iconDeviceLocked = findViewById(R.id.icon_device_locked);
+ final ImageView iconTrashCan = findViewById(R.id.icon_trash_can);
final ImageView iconInfo = findViewById(R.id.icon_info);
final ImageView iconLink = findViewById(R.id.icon_link);
iconFingerprint.getDrawable().setColorFilter(getIconColorFilter());
+ iconDeviceLocked.getDrawable().setColorFilter(getIconColorFilter());
+ iconTrashCan.getDrawable().setColorFilter(getIconColorFilter());
iconInfo.getDrawable().setColorFilter(getIconColorFilter());
iconLink.getDrawable().setColorFilter(getIconColorFilter());
@@ -87,7 +91,7 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
@StringRes
int getNegativeButtonTextId() {
- return R.string.security_settings_fingerprint_enroll_introduction_skip;
+ return R.string.security_settings_fingerprint_enroll_introduction_no_thanks;
}
@StringRes
diff --git a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java
index e1059119b16..4bd8afd98ed 100644
--- a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java
@@ -26,7 +26,6 @@ import android.os.UserHandle;
import android.view.View;
import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricUtils;
@@ -34,8 +33,6 @@ import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.SetupChooseLockGeneric;
import com.android.settings.password.SetupSkipDialog;
-import com.google.android.setupcompat.template.FooterButton;
-
public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction {
/**
* Returns the number of fingerprint enrolled.
@@ -56,11 +53,6 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu
}
}
- @Override
- int getNegativeButtonTextId() {
- return R.string.security_settings_face_enroll_introduction_cancel;
- }
-
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@@ -78,19 +70,6 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu
return intent;
}
- @Override
- protected void initViews() {
- super.initViews();
-
- FooterButton nextButton = getNextButton();
- nextButton.setText(
- this, R.string.security_settings_fingerprint_enroll_introduction_continue_setup);
-
- final FooterButton cancelButton = getCancelButton();
- cancelButton.setText(
- this, R.string.security_settings_fingerprint_enroll_introduction_cancel_setup);
- }
-
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if lock was already present, do not return intent data since it must have been
diff --git a/src/com/android/settings/gestures/OneHandedSettings.java b/src/com/android/settings/gestures/OneHandedSettings.java
index 6d1cbfd35d9..51c6b663671 100644
--- a/src/com/android/settings/gestures/OneHandedSettings.java
+++ b/src/com/android/settings/gestures/OneHandedSettings.java
@@ -16,19 +16,18 @@
package com.android.settings.gestures;
+import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
import com.android.internal.accessibility.AccessibilityShortcutController;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.widget.IllustrationPreference;
/**
* Fragment for One-handed mode settings
@@ -37,13 +36,27 @@ import com.android.settings.search.BaseSearchIndexProvider;
* providing basic accessibility shortcut service setup.
*/
public class OneHandedSettings extends AccessibilityShortcutPreferenceFragment {
+
private static final String ONE_HANDED_SHORTCUT_KEY = "one_handed_shortcuts_preference";
+ private static final String ONE_HANDED_ILLUSTRATION_KEY = "one_handed_header";
private String mFeatureName;
+ private OneHandedSettingsUtils mUtils;
@Override
protected void updatePreferenceStates() {
OneHandedSettingsUtils.setUserId(UserHandle.myUserId());
super.updatePreferenceStates();
+
+ final IllustrationPreference preference =
+ (IllustrationPreference) getPreferenceScreen().findPreference(
+ ONE_HANDED_ILLUSTRATION_KEY);
+ if (preference != null) {
+ final boolean isSwipeDownNotification =
+ OneHandedSettingsUtils.isSwipeDownNotificationEnabled(getContext());
+ preference.setLottieAnimationResId(
+ isSwipeDownNotification ? R.raw.lottie_swipe_for_notifications
+ : R.raw.lottie_one_hand_mode);
+ }
}
@Override
@@ -69,9 +82,21 @@ public class OneHandedSettings extends AccessibilityShortcutPreferenceFragment {
}
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- return super.onCreateView(inflater, container, savedInstanceState);
+ public void onStart() {
+ super.onStart();
+ mUtils = new OneHandedSettingsUtils(this.getContext());
+ mUtils.registerToggleAwareObserver(uri -> {
+ Activity activity = getActivity();
+ if (activity != null) {
+ activity.runOnUiThread(() -> updatePreferenceStates());
+ }
+ });
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mUtils.unregisterToggleAwareObserver();
}
@Override
diff --git a/src/com/android/settings/network/AdaptiveConnectivityTogglePreferenceController.java b/src/com/android/settings/network/AdaptiveConnectivityTogglePreferenceController.java
index e1e56a8a6fa..e3d779ce938 100644
--- a/src/com/android/settings/network/AdaptiveConnectivityTogglePreferenceController.java
+++ b/src/com/android/settings/network/AdaptiveConnectivityTogglePreferenceController.java
@@ -22,12 +22,14 @@ import android.provider.Settings;
import androidx.preference.PreferenceScreen;
-import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.widget.SettingsMainSwitchPreferenceController;
/**
- * {@link TogglePreferenceController} that controls whether Adaptive connectivity option is enabled.
+ * {@link SettingsMainSwitchPreferenceController}
+ * that controls whether Adaptive connectivity option is enabled.
*/
-public class AdaptiveConnectivityTogglePreferenceController extends TogglePreferenceController {
+public class AdaptiveConnectivityTogglePreferenceController extends
+ SettingsMainSwitchPreferenceController {
private final WifiManager mWifiManager;
diff --git a/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java b/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java
index 0064e6ccfd2..e67ac42af47 100644
--- a/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java
+++ b/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java
@@ -338,7 +338,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc
getString(R.string.sim_action_restart_title),
getString(R.string.sim_action_enable_dsds_text),
getString(R.string.sim_action_reboot),
- getString(R.string.cancel));
+ getString(R.string.sim_action_cancel));
}
/* Displays the SIM toggling confirmation dialog. */
@@ -359,7 +359,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc
title,
null,
getString(R.string.yes),
- getString(R.string.cancel));
+ getString(R.string.sim_action_cancel));
}
private void showEnableSimConfirmDialog() {
@@ -384,7 +384,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc
getSwitchSubscriptionTitle(),
getSwitchDialogBodyMsg(activeSub, isBetweenEsim),
getSwitchDialogPosBtnText(),
- getString(android.R.string.cancel));
+ getString(R.string.sim_action_cancel));
}
private void showNonSwitchSimConfirmDialog() {
@@ -395,7 +395,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc
getEnableSubscriptionTitle(),
null /* msg */,
getString(R.string.yes),
- getString(android.R.string.cancel));
+ getString(R.string.sim_action_cancel));
}
private String getSwitchDialogPosBtnText() {
diff --git a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java
index c98b036d7e2..166ee5d4ffc 100644
--- a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java
+++ b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java
@@ -65,9 +65,6 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder {
}
void setTitle(CharSequence title) {
- if (title == null) {
- return;
- }
mTitle.setText(title);
}
diff --git a/src/com/android/settings/widget/LoadingViewController.java b/src/com/android/settings/widget/LoadingViewController.java
index 294e55e7ea8..66eebf387ba 100644
--- a/src/com/android/settings/widget/LoadingViewController.java
+++ b/src/com/android/settings/widget/LoadingViewController.java
@@ -22,34 +22,66 @@ import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import androidx.annotation.Nullable;
+
/**
- * A helper class that manages show/hide loading spinner.
+ * A helper class that manages show/hide loading spinner, content view and empty view (optional).
*/
public class LoadingViewController {
private static final long DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS = 100L;
- public final Handler mFgHandler;
- public final View mLoadingView;
- public final View mContentView;
+ private final Handler mFgHandler;
+ private final View mLoadingView;
+ private final View mContentView;
+ private final View mEmptyView;
public LoadingViewController(View loadingView, View contentView) {
+ this(loadingView, contentView, null /* emptyView*/);
+ }
+
+ public LoadingViewController(View loadingView, View contentView, @Nullable View emptyView) {
mLoadingView = loadingView;
mContentView = contentView;
+ mEmptyView = emptyView;
mFgHandler = new Handler(Looper.getMainLooper());
}
private Runnable mShowLoadingContainerRunnable = new Runnable() {
public void run() {
- handleLoadingContainer(false /* done */, false /* animate */);
+ showLoadingView();
}
};
+ /**
+ * Shows content view and hides loading view & empty view.
+ */
public void showContent(boolean animate) {
// Cancel any pending task to show the loading animation and show the list of
// apps directly.
mFgHandler.removeCallbacks(mShowLoadingContainerRunnable);
- handleLoadingContainer(true /* show */, animate);
+ handleLoadingContainer(true /* showContent */, false /* showEmpty*/, animate);
+ }
+
+ /**
+ * Shows empty view and hides loading view & content view.
+ */
+ public void showEmpty(boolean animate) {
+ if (mEmptyView == null) {
+ return;
+ }
+
+ // Cancel any pending task to show the loading animation and show the list of
+ // apps directly.
+ mFgHandler.removeCallbacks(mShowLoadingContainerRunnable);
+ handleLoadingContainer(false /* showContent */, true /* showEmpty */, animate);
+ }
+
+ /**
+ * Shows loading view and hides content view & empty view.
+ */
+ public void showLoadingView() {
+ handleLoadingContainer(false /* showContent */, false /* showEmpty */, false /* animate */);
}
public void showLoadingViewDelayed() {
@@ -57,8 +89,9 @@ public class LoadingViewController {
mShowLoadingContainerRunnable, DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS);
}
- public void handleLoadingContainer(boolean done, boolean animate) {
- handleLoadingContainer(mLoadingView, mContentView, done, animate);
+ private void handleLoadingContainer(boolean showContent, boolean showEmpty, boolean animate) {
+ handleLoadingContainer(mLoadingView, mContentView, mEmptyView,
+ showContent, showEmpty, animate);
}
/**
@@ -75,6 +108,25 @@ public class LoadingViewController {
setViewShown(content, done, animate);
}
+ /**
+ * Show/hide loading view and content view and empty view.
+ *
+ * @param loading The loading spinner view
+ * @param content The content view
+ * @param empty The empty view shows no item summary to users.
+ * @param showContent If true, content is set visible and loading is set invisible.
+ * @param showEmpty If true, empty is set visible and loading is set invisible.
+ * @param animate Whether or not content/loading views should animate in/out.
+ */
+ public static void handleLoadingContainer(View loading, View content, View empty,
+ boolean showContent, boolean showEmpty, boolean animate) {
+ if (empty != null) {
+ setViewShown(empty, showEmpty, animate);
+ }
+ setViewShown(content, showContent, animate);
+ setViewShown(loading, !showContent && !showEmpty, animate);
+ }
+
private static void setViewShown(final View view, boolean shown, boolean animate) {
if (animate) {
Animation animation = AnimationUtils.loadAnimation(view.getContext(),
diff --git a/tests/robotests/src/com/android/settings/accessibility/AnimatedImagePreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/AnimatedImagePreferenceTest.java
deleted file mode 100644
index c7e5b13be83..00000000000
--- a/tests/robotests/src/com/android/settings/accessibility/AnimatedImagePreferenceTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2020 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.accessibility;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.graphics.drawable.AnimatedImageDrawable;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.AnimationDrawable;
-import android.net.Uri;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-
-import com.airbnb.lottie.LottieAnimationView;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.io.InputStream;
-
-/** Tests for {@link AnimatedImagePreference}. */
-@RunWith(RobolectricTestRunner.class)
-public class AnimatedImagePreferenceTest {
- private final Context mContext = RuntimeEnvironment.application;
- private Uri mImageUri;
- private PreferenceViewHolder mViewHolder;
- private AnimatedImagePreference mAnimatedImagePreference;
-
- @Mock
- private ViewGroup mRootView;
-
- @Spy
- private ImageView mImageView;
-
- @Before
- public void init() {
- MockitoAnnotations.initMocks(this);
-
- mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(mRootView));
- doReturn(new LottieAnimationView(mContext)).when(mRootView).findViewById(R.id.lottie_view);
- mImageView = spy(new ImageView(mContext));
-
- mAnimatedImagePreference = new AnimatedImagePreference(mContext);
- mImageUri = new Uri.Builder().build();
- }
-
- @Test
- public void playAnimation_animatedImageDrawable_success() {
- final AnimatedImageDrawable drawable = mock(AnimatedImageDrawable.class);
- doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
- doReturn(drawable).when(mImageView).getDrawable();
-
- mAnimatedImagePreference.setImageUri(mImageUri);
- mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
- verify(drawable).start();
- }
-
- @Test
- public void playAnimation_animatedVectorDrawable_success() {
- final AnimatedVectorDrawable drawable = mock(AnimatedVectorDrawable.class);
- doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
- doReturn(drawable).when(mImageView).getDrawable();
-
- mAnimatedImagePreference.setImageUri(mImageUri);
- mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
- verify(drawable).start();
- }
-
- @Test
- public void playAnimation_animationDrawable_success() {
- final AnimationDrawable drawable = mock(AnimationDrawable.class);
- doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
- doReturn(drawable).when(mImageView).getDrawable();
-
- mAnimatedImagePreference.setImageUri(mImageUri);
- mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
- verify(drawable).start();
- }
-
- @Test
- public void setImageUri_viewNotExist_setFail() {
- doReturn(null).when(mRootView).findViewById(R.id.animated_img);
-
- mAnimatedImagePreference.setImageUri(mImageUri);
- mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
- verify(mImageView, never()).setImageURI(mImageUri);
- }
-
- @Test
- public void setMaxHeight_success() {
- final int maxHeight = 100;
- doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
-
- mAnimatedImagePreference.setMaxHeight(maxHeight);
- mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
- assertThat(mImageView.getMaxHeight()).isEqualTo(maxHeight);
- }
-
- @Test
- public void setImageUriAndRebindViewHolder_lottieImageFromRawFolder_setAnimation() {
- final int fakeLottieResId = 111111;
- final Uri lottieImageUri =
- new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
- .authority(mContext.getPackageName())
- .appendPath(String.valueOf(fakeLottieResId))
- .build();
- final LottieAnimationView lottieView = spy(new LottieAnimationView(mContext));
- doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
- doReturn(lottieView).when(mRootView).findViewById(R.id.lottie_view);
-
- mAnimatedImagePreference.setImageUri(lottieImageUri);
- mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
- verify(lottieView).setAnimation(any(InputStream.class), eq(null));
- }
-}
diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
index 86f5fe83c6c..25eca7adb22 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
@@ -28,7 +28,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -49,7 +48,6 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.SearchView;
import androidx.fragment.app.FragmentActivity;
@@ -155,22 +153,6 @@ public class ManageApplicationsTest {
assertThat(mMenu.findItem(R.id.sort_order_frequent_notification).isVisible()).isFalse();
}
- @Test
- public void onCreateView_shouldNotShowLoadingContainer() {
- ReflectionHelpers.setField(mFragment, "mResetAppsHelper", mock(ResetAppsHelper.class));
- doNothing().when(mFragment).createHeader();
-
- final LayoutInflater layoutInflater = mock(LayoutInflater.class);
- final View view = mock(View.class);
- final View loadingContainer = mock(View.class);
- when(layoutInflater.inflate(anyInt(), eq(null))).thenReturn(view);
- when(view.findViewById(R.id.loading_container)).thenReturn(loadingContainer);
-
- mFragment.onCreateView(layoutInflater, mock(ViewGroup.class), null);
-
- verify(loadingContainer, never()).setVisibility(View.VISIBLE);
- }
-
@Test
public void onCreateOptionsMenu_shouldSetSearchQueryListener() {
final SearchView searchView = mock(SearchView.class);
@@ -221,7 +203,6 @@ public class ManageApplicationsTest {
@Test
public void updateLoading_appLoaded_shouldNotDelayCallToHandleLoadingContainer() {
ReflectionHelpers.setField(mFragment, "mLoadingContainer", mock(View.class));
- ReflectionHelpers.setField(mFragment, "mListContainer", mock(View.class));
final ManageApplications.ApplicationsAdapter adapter =
spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
@@ -243,7 +224,6 @@ public class ManageApplicationsTest {
@Test
public void updateLoading_appNotLoaded_shouldDelayCallToHandleLoadingContainer() {
ReflectionHelpers.setField(mFragment, "mLoadingContainer", mock(View.class));
- ReflectionHelpers.setField(mFragment, "mListContainer", mock(View.class));
final ManageApplications.ApplicationsAdapter adapter =
spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
@@ -272,7 +252,6 @@ public class ManageApplicationsTest {
when(listContainer.getVisibility()).thenReturn(View.INVISIBLE);
when(listContainer.getContext()).thenReturn(context);
ReflectionHelpers.setField(mFragment, "mLoadingContainer", loadingContainer);
- ReflectionHelpers.setField(mFragment, "mListContainer", listContainer);
final ManageApplications.ApplicationsAdapter adapter =
spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
@@ -296,7 +275,7 @@ public class ManageApplicationsTest {
adapter.onRebuildComplete(null);
- verify(loadingViewController).showContent(true /* animate */);
+ verify(loadingViewController).showEmpty(false /* animate */);
}
@Test
@@ -304,15 +283,16 @@ public class ManageApplicationsTest {
final String query = "Test";
final RecyclerView recyclerView = mock(RecyclerView.class);
final View emptyView = mock(View.class);
+ final View loadingContainer = mock(View.class);
ReflectionHelpers.setField(mFragment, "mRecyclerView", recyclerView);
ReflectionHelpers.setField(mFragment, "mEmptyView", emptyView);
+ ReflectionHelpers.setField(mFragment, "mLoadingContainer", loadingContainer);
final SearchView searchView = mock(SearchView.class);
ReflectionHelpers.setField(mFragment, "mSearchView", searchView);
when(searchView.isVisibleToUser()).thenReturn(true);
when(searchView.getQuery()).thenReturn(query);
final View listContainer = mock(View.class);
when(listContainer.getVisibility()).thenReturn(View.VISIBLE);
- ReflectionHelpers.setField(mFragment, "mListContainer", listContainer);
ReflectionHelpers.setField(
mFragment, "mFilterAdapter", mock(ManageApplications.FilterSpinnerAdapter.class));
final ArrayList appList = new ArrayList<>();
@@ -491,8 +471,6 @@ public class ManageApplicationsTest {
mFragment.mFilterAdapter.updateFilterView(true);
assertThat(mFragment.mSpinnerHeader.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(mFragment.mRecyclerView.getPaddingTop()).isEqualTo(
- mContext.getResources().getDimensionPixelSize(R.dimen.app_bar_height));
}
@Test