Snap for 7482035 from aee4809820 to sc-v2-release
Change-Id: I7defc145b1a9f46c66c0068cc9961092f5c00294
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<FrameLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
@@ -24,40 +24,39 @@
|
||||
android:id="@+id/pinned_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="2dp"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/list_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone">
|
||||
android:elevation="2dp"
|
||||
settings:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/apps_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="0dp"
|
||||
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:fastScrollVerticalTrackDrawable="@drawable/line_drawable"
|
||||
settings:layout_constraintTop_toBottomOf="@id/pinned_header"
|
||||
settings:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="bottom|center_horizontal"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/no_applications"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:visibility="invisible"/>
|
||||
android:visibility="invisible"
|
||||
settings:layout_constraintTop_toTopOf="parent"
|
||||
settings:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</FrameLayout>
|
||||
<include layout="@layout/loading_container"
|
||||
settings:layout_constraintTop_toBottomOf="@id/pinned_header"
|
||||
settings:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<include layout="@layout/loading_container"/>
|
||||
|
||||
</FrameLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
|
||||
@@ -149,8 +149,6 @@
|
||||
<dimen name="wifi_assistant_height">182dp</dimen>
|
||||
<dimen name="wifi_assistant_image_top">32dp</dimen>
|
||||
<dimen name="wifi_assistant_image_start">24dp</dimen>
|
||||
<!-- appbar height is equal search bar height (48dp) plus search bar top and bottom margin -->
|
||||
<dimen name="app_bar_height">80dp</dimen>
|
||||
|
||||
<!-- CryptKeeper top margin for password/pin screen -->
|
||||
<dimen name="crypt_keeper_password_top_margin">88dip</dimen>
|
||||
|
||||
@@ -1212,6 +1212,8 @@
|
||||
<annotation id="url">Learn more</annotation></string>
|
||||
<!-- Text shown in fingerprint enroll when we didn't observe progress for a few seconds. [CHAR LIMIT=100] -->
|
||||
<string name="security_settings_fingerprint_enroll_lift_touch_again">Lift finger, then touch sensor again</string>
|
||||
<!-- Text shown during fingerprint enrollment to indicate bad sensor calibration. [CHAR LIMIT=100] -->
|
||||
<string name="security_settings_fingerprint_bad_calibration">Please recalibrate the fingerprint sensor.</string>
|
||||
|
||||
<!-- Text shown when "Add fingerprint" button is disabled -->
|
||||
<string name="fingerprint_add_max">You can add up to <xliff:g id="count" example="5">%d</xliff:g> fingerprints</string>
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
android:title="@string/owner_info_settings_title"
|
||||
android:summary="@string/owner_info_settings_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="security_setting_lockdown_enabled"
|
||||
android:title="@string/lockdown_settings_title"
|
||||
android:summary="@string/lockdown_settings_summary"
|
||||
settings:controller="com.android.settings.security.LockdownButtonPreferenceController" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="lockscreen_privacy_wallet_switch"
|
||||
android:title="@string/lockscreen_privacy_wallet_setting_toggle"
|
||||
|
||||
@@ -77,7 +77,6 @@ import android.provider.ContactsContract.Contacts;
|
||||
import android.provider.ContactsContract.Data;
|
||||
import android.provider.ContactsContract.Profile;
|
||||
import android.provider.ContactsContract.RawContacts;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.Spannable;
|
||||
@@ -164,9 +163,6 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
public static final String PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS =
|
||||
"app_hibernation_targets_pre_s_apps";
|
||||
|
||||
/** Whether or not Settings Shared Axis transition is enabled */
|
||||
public static final String SETTINGS_SHARED_AXIS_ENABLED = "settings_shared_axis_enabled";
|
||||
|
||||
/**
|
||||
* Finds a matching activity for a preference's intent. If a matching
|
||||
* activity is not found, it will remove the preference.
|
||||
@@ -1225,9 +1221,4 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
public static boolean isProviderModelEnabled(Context context) {
|
||||
return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL);
|
||||
}
|
||||
|
||||
public static boolean isPageTransitionEnabled(Context context) {
|
||||
return Settings.Global.getInt(context.getContentResolver(),
|
||||
SETTINGS_SHARED_AXIS_ENABLED, 0) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,10 +401,8 @@ 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);
|
||||
@@ -415,12 +412,10 @@ public class ManageApplications extends InstrumentedFragment
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -45,6 +45,8 @@ public class FingerprintErrorDialog extends BiometricErrorDialog {
|
||||
// This message happens when the underlying crypto layer decides to revoke the
|
||||
// enrollment auth token.
|
||||
return R.string.security_settings_fingerprint_enroll_error_timeout_dialog_message;
|
||||
case FingerprintManager.FINGERPRINT_ERROR_BAD_CALIBARTION:
|
||||
return R.string.security_settings_fingerprint_bad_calibration;
|
||||
default:
|
||||
// There's nothing specific to tell the user about. Ask them to try again.
|
||||
return R.string.security_settings_fingerprint_enroll_error_generic_dialog_message;
|
||||
|
||||
@@ -17,17 +17,14 @@ package com.android.settings.core;
|
||||
|
||||
import android.annotation.LayoutRes;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
@@ -35,16 +32,16 @@ import android.widget.Toolbar;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.CategoryMixin.CategoryHandler;
|
||||
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
|
||||
import com.android.settingslib.transition.SettingsTransitionHelper;
|
||||
import com.android.settingslib.transition.SettingsTransitionHelper.TransitionType;
|
||||
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||
import com.google.android.material.resources.TextAppearanceConfig;
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
@@ -64,6 +61,7 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
|
||||
|
||||
protected CategoryMixin mCategoryMixin;
|
||||
protected CollapsingToolbarLayout mCollapsingToolbarLayout;
|
||||
protected AppBarLayout mAppBarLayout;
|
||||
private Toolbar mToolbar;
|
||||
|
||||
@Override
|
||||
@@ -73,13 +71,6 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
if (Utils.isPageTransitionEnabled(this)) {
|
||||
// Enable Activity transitions
|
||||
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
|
||||
SettingsTransitionHelper.applyForwardTransition(this);
|
||||
SettingsTransitionHelper.applyBackwardTransition(this);
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
if (isLockTaskModePinned() && !isSettingsRunOnTop()) {
|
||||
Log.w(TAG, "Devices lock task mode pinned.");
|
||||
@@ -108,6 +99,8 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
|
||||
if (isToolbarEnabled() && !isAnySetupWizard) {
|
||||
super.setContentView(R.layout.collapsing_toolbar_base_layout);
|
||||
mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
|
||||
mAppBarLayout = findViewById(R.id.app_bar);
|
||||
disableCollapsingToolbarLayoutScrollingBehavior();
|
||||
} else {
|
||||
super.setContentView(R.layout.settings_base_layout);
|
||||
}
|
||||
@@ -140,28 +133,10 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
final int id = item.getItemId();
|
||||
if (id == android.R.id.home) {
|
||||
// Make the up button behave the same as the back button.
|
||||
finishAfterTransition();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startActivityForResult(Intent intent, int requestCode,
|
||||
@androidx.annotation.Nullable Bundle options) {
|
||||
final int transitionType = getTransitionType(intent);
|
||||
if (Utils.isPageTransitionEnabled(this) &&
|
||||
transitionType == TransitionType.TRANSITION_SHARED_AXIS) {
|
||||
super.startActivityForResult(intent, requestCode,
|
||||
createActivityOptionsBundleForTransition(options));
|
||||
return;
|
||||
}
|
||||
|
||||
super.startActivityForResult(intent, requestCode, options);
|
||||
if (transitionType == TransitionType.TRANSITION_SLIDE) {
|
||||
overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out);
|
||||
@@ -170,18 +145,6 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startActivityForResultAsUser(Intent intent, int requestCode,
|
||||
UserHandle userHandle) {
|
||||
if (!Utils.isPageTransitionEnabled(this) || requestCode == DEFAULT_REQUEST) {
|
||||
super.startActivityForResultAsUser(intent, requestCode, userHandle);
|
||||
return;
|
||||
}
|
||||
super.startActivityForResultAsUser(intent, requestCode,
|
||||
createActivityOptionsBundleForTransition(null),
|
||||
userHandle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
// For accessibility activities launched from setup wizard.
|
||||
@@ -274,26 +237,21 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
|
||||
return false;
|
||||
}
|
||||
|
||||
private void disableCollapsingToolbarLayoutScrollingBehavior() {
|
||||
final CoordinatorLayout.LayoutParams params =
|
||||
(CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
|
||||
final AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
|
||||
behavior.setDragCallback(
|
||||
new AppBarLayout.Behavior.DragCallback() {
|
||||
@Override
|
||||
public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
params.setBehavior(behavior);
|
||||
}
|
||||
|
||||
private int getTransitionType(Intent intent) {
|
||||
return intent.getIntExtra(EXTRA_PAGE_TRANSITION_TYPE,
|
||||
SettingsTransitionHelper.TransitionType.TRANSITION_SHARED_AXIS);
|
||||
return intent.getIntExtra(EXTRA_PAGE_TRANSITION_TYPE, TransitionType.TRANSITION_NONE);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Bundle createActivityOptionsBundleForTransition(
|
||||
@androidx.annotation.Nullable Bundle options) {
|
||||
if (mToolbar == null) {
|
||||
Log.w(TAG, "setActionBar(Toolbar) is not called. Cannot apply settings transition!");
|
||||
return options;
|
||||
}
|
||||
final Bundle transitionOptions = ActivityOptions.makeSceneTransitionAnimation(this,
|
||||
mToolbar, "shared_element_view").toBundle();
|
||||
if (options == null) {
|
||||
return transitionOptions;
|
||||
}
|
||||
final Bundle mergedOptions = new Bundle(options);
|
||||
mergedOptions.putAll(transitionOptions);
|
||||
return mergedOptions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -139,13 +139,17 @@ public class AdaptiveSleepPreferenceController {
|
||||
}
|
||||
|
||||
public static int isControllerAvailable(Context context) {
|
||||
return context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_adaptive_sleep_available)
|
||||
&& isAttentionServiceAvailable(context)
|
||||
return isAdaptiveSleepSupported(context)
|
||||
? AVAILABLE_UNSEARCHABLE
|
||||
: UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
static boolean isAdaptiveSleepSupported(Context context) {
|
||||
return context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_adaptive_sleep_available)
|
||||
&& isAttentionServiceAvailable(context);
|
||||
}
|
||||
|
||||
private static boolean isAttentionServiceAvailable(Context context) {
|
||||
final PackageManager packageManager = context.getPackageManager();
|
||||
final String resolvePackage = packageManager.getAttentionServicePackageName();
|
||||
|
||||
@@ -314,8 +314,7 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
}
|
||||
|
||||
private static boolean isScreenAttentionAvailable(Context context) {
|
||||
return context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_adaptive_sleep_available);
|
||||
return AdaptiveSleepPreferenceController.isAdaptiveSleepSupported(context);
|
||||
}
|
||||
|
||||
private static class TimeoutCandidateInfo extends CandidateInfo {
|
||||
|
||||
@@ -259,6 +259,10 @@ public class MediaDeviceUpdateWorker extends SliceBackgroundWorker
|
||||
return mLocalMediaManager.shouldDisableMediaOutput(packageName);
|
||||
}
|
||||
|
||||
boolean shouldEnableVolumeSeekBar(RoutingSessionInfo sessionInfo) {
|
||||
return mLocalMediaManager.shouldEnableVolumeSeekBar(sessionInfo);
|
||||
}
|
||||
|
||||
private class DevicesChangedBroadcastReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
@@ -126,6 +126,12 @@ public class RemoteMediaSlice implements CustomSliceable {
|
||||
+ maxVolume);
|
||||
continue;
|
||||
}
|
||||
if (!getWorker().shouldEnableVolumeSeekBar(info)) {
|
||||
// There is no disable state. We hide it directly.
|
||||
Log.d(TAG, "Unable to add Slice. " + info.getName() + ": This is a group session");
|
||||
continue;
|
||||
}
|
||||
|
||||
final CharSequence appName = Utils.getApplicationLabel(
|
||||
mContext, info.getClientPackageName());
|
||||
final CharSequence outputTitle = mContext.getString(R.string.media_output_label_title,
|
||||
|
||||
@@ -129,6 +129,7 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
|
||||
seekBarPreference.setMin(0);
|
||||
seekBarPreference.setOnPreferenceChangeListener(this);
|
||||
seekBarPreference.setIcon(R.drawable.ic_volume_remote);
|
||||
seekBarPreference.setEnabled(mLocalMediaManager.shouldEnableVolumeSeekBar(info));
|
||||
mPreferenceCategory.addPreference(seekBarPreference);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerExecutor;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyCallback;
|
||||
@@ -235,7 +236,10 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
|
||||
@Override
|
||||
public Intent getSeeMoreIntent() {
|
||||
return null;
|
||||
// Don't remove the see more intent for non-provider model design. This intent will be
|
||||
// used when isCustomizedButtonUsed() returns false.
|
||||
return new Intent(Settings.ACTION_WIRELESS_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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<ApplicationsState.AppEntry> 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
|
||||
|
||||
@@ -28,14 +28,12 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.transition.SettingsTransitionHelper;
|
||||
|
||||
@@ -45,7 +43,6 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
|
||||
@@ -22,16 +22,24 @@ import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.provider.Settings;
|
||||
@@ -80,6 +88,9 @@ public class ScreenTimeoutSettingsTest {
|
||||
@Mock
|
||||
Preference mDisableOptionsPreference;
|
||||
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
@@ -90,6 +101,15 @@ public class ScreenTimeoutSettingsTest {
|
||||
mContentResolver = mContext.getContentResolver();
|
||||
mResources = spy(mContext.getResources());
|
||||
|
||||
doReturn(mPackageManager).when(mContext).getPackageManager();
|
||||
when(mPackageManager.getAttentionServicePackageName()).thenReturn("some.package");
|
||||
when(mPackageManager.checkPermission(any(), any())).thenReturn(
|
||||
PackageManager.PERMISSION_GRANTED);
|
||||
final ResolveInfo attentionServiceResolveInfo = new ResolveInfo();
|
||||
attentionServiceResolveInfo.serviceInfo = new ServiceInfo();
|
||||
when(mPackageManager.resolveService(isA(Intent.class), anyInt())).thenReturn(
|
||||
attentionServiceResolveInfo);
|
||||
|
||||
doReturn(TIMEOUT_ENTRIES).when(mResources).getStringArray(R.array.screen_timeout_entries);
|
||||
doReturn(TIMEOUT_VALUES).when(mResources).getStringArray(R.array.screen_timeout_entries);
|
||||
doReturn(true).when(mResources).getBoolean(
|
||||
@@ -147,6 +167,13 @@ public class ScreenTimeoutSettingsTest {
|
||||
verify(mSettings.mAdaptiveSleepController, never()).addToScreen(mPreferenceScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateCandidates_AttentionServiceNotInstalled_doNoShowAdaptiveSleepPreference() {
|
||||
when(mPackageManager.resolveService(isA(Intent.class), anyInt())).thenReturn(null);
|
||||
|
||||
verify(mSettings.mAdaptiveSleepController, never()).addToScreen(mPreferenceScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateCandidates_enforcedAdmin_showDisabledByAdminPreference() {
|
||||
mSettings.mAdmin = new RestrictedLockUtils.EnforcedAdmin();
|
||||
|
||||
@@ -47,7 +47,6 @@ public class ShadowUtils {
|
||||
private static boolean sIsVoiceCapable;
|
||||
private static ArraySet<String> sResultLinks = new ArraySet<>();
|
||||
private static boolean sIsBatteryPresent;
|
||||
private static boolean sIsPageTransitionEnabled;
|
||||
private static boolean sIsMultipleBiometricsSupported;
|
||||
|
||||
@Implementation
|
||||
@@ -71,7 +70,6 @@ public class ShadowUtils {
|
||||
sIsVoiceCapable = false;
|
||||
sResultLinks = new ArraySet<>();
|
||||
sIsBatteryPresent = true;
|
||||
sIsPageTransitionEnabled = true;
|
||||
sIsMultipleBiometricsSupported = false;
|
||||
}
|
||||
|
||||
@@ -171,15 +169,6 @@ public class ShadowUtils {
|
||||
sIsBatteryPresent = isBatteryPresent;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isPageTransitionEnabled(Context context) {
|
||||
return sIsPageTransitionEnabled;
|
||||
}
|
||||
|
||||
public static void setIsPageTransitionEnabled(boolean isPageTransitionEnabled) {
|
||||
sIsPageTransitionEnabled = isPageTransitionEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isMultipleBiometricsSupported(Context context) {
|
||||
return sIsMultipleBiometricsSupported;
|
||||
|
||||
@@ -255,8 +255,8 @@ public class InternetConnectivityPanelTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSeeMoreIntent_shouldBeNull() {
|
||||
assertThat(mPanel.getSeeMoreIntent()).isNull();
|
||||
public void getSeeMoreIntent_shouldNotNull() {
|
||||
assertThat(mPanel.getSeeMoreIntent()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user