Snap for 7408786 from f8f435397c to sc-v2-release

Change-Id: I4cfef67d0e9da99a902fc114ab8cd9b942a8e034
This commit is contained in:
android-build-team Robot
2021-05-29 03:08:41 +00:00
13 changed files with 219 additions and 99 deletions

View File

@@ -2448,7 +2448,7 @@
<activity
android:name="com.android.settings.accounts.AddAccountSettings"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:theme="@style/Theme.SubSettings"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="true"
android:label="@string/header_add_an_account">

View File

@@ -18,7 +18,8 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path
android:pathData="M15,3V4H20V6H19V19C19,20.1 18.1,21 17,21H7C5.9,21 5,20.1 5,19V6H4V4H9V3H15ZM7,19H17V6H7V19ZM9,8H11V17H9V8ZM15,8H13V17H15V8Z"
android:fillColor="#5F6368"

View File

@@ -15,28 +15,32 @@
limitations under the License
-->
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container_layout"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay">
android:layout_height="wrap_content"
android:clipChildren="true">
<LinearLayout
<ScrollView
android:id="@+id/container_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay">
<include android:id="@+id/software_shortcut"
layout="@layout/accessibility_edit_shortcut_component"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp" />
android:orientation="vertical"
android:padding="24dp">
<include android:id="@+id/hardware_shortcut"
layout="@layout/accessibility_edit_shortcut_component" />
<include android:id="@+id/software_shortcut"
layout="@layout/accessibility_edit_shortcut_component"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp" />
</LinearLayout>
<include android:id="@+id/hardware_shortcut"
layout="@layout/accessibility_edit_shortcut_component" />
</ScrollView>
</LinearLayout>
</ScrollView>
</FrameLayout>

View File

@@ -15,64 +15,69 @@
limitations under the License
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container_layout"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay">
android:layout_height="wrap_content"
android:clipChildren="true">
<LinearLayout
<ScrollView
android:id="@+id/container_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<include
android:id="@+id/software_shortcut"
layout="@layout/accessibility_edit_shortcut_component"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp" />
<include
android:id="@+id/hardware_shortcut"
layout="@layout/accessibility_edit_shortcut_component"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp" />
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay">
<LinearLayout
android:id="@+id/advanced_shortcut"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:orientation="horizontal">
android:orientation="vertical"
android:padding="24dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:contentDescription="@null"
android:scaleType="centerCrop"
android:src="@drawable/ic_keyboard_arrow_down" />
<TextView
<include
android:id="@+id/software_shortcut"
layout="@layout/accessibility_edit_shortcut_component"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingStart="12dp"
android:text="@string/accessibility_shortcut_edit_dialog_title_advance"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?android:attr/colorAccent"
android:textSize="16sp" />
android:layout_height="wrap_content"
android:layout_marginBottom="32dp" />
<include
android:id="@+id/hardware_shortcut"
layout="@layout/accessibility_edit_shortcut_component"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp" />
<LinearLayout
android:id="@+id/advanced_shortcut"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:contentDescription="@null"
android:scaleType="centerCrop"
android:src="@drawable/ic_keyboard_arrow_down" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingStart="12dp"
android:text="@string/accessibility_shortcut_edit_dialog_title_advance"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?android:attr/colorAccent"
android:textSize="16sp" />
</LinearLayout>
<include
android:id="@+id/triple_tap_shortcut"
layout="@layout/accessibility_edit_shortcut_component"
android:visibility="gone" />
</LinearLayout>
<include
android:id="@+id/triple_tap_shortcut"
layout="@layout/accessibility_edit_shortcut_component"
android:visibility="gone" />
</LinearLayout>
</ScrollView>
</ScrollView>
</FrameLayout>

View File

@@ -648,7 +648,7 @@
<style name="AccessibilityDialogIcon">
<item name="android:layout_width">18dp</item>
<item name="android:layout_height">18dp</item>
<item name="android:layout_marginRight">12dp</item>
<item name="android:layout_marginEnd">12dp</item>
<item name="android:scaleType">fitCenter</item>
</style>

View File

@@ -312,6 +312,7 @@ public class AppLaunchSettings extends AppInfoBase implements
/** Initialize add link preference */
private void initAddLinkPreference() {
mAddLinkPreference = findPreference(ADD_LINK_PREF_KEY);
mAddLinkPreference.setVisible(isAddLinksShown());
mAddLinkPreference.setEnabled(isAddLinksNotEmpty());
mAddLinkPreference.setOnPreferenceClickListener(preference -> {
final int stateNoneLinksNo = getLinksNumber(DOMAIN_STATE_NONE);
@@ -327,6 +328,10 @@ public class AppLaunchSettings extends AppInfoBase implements
return getLinksNumber(DOMAIN_STATE_NONE) > 0;
}
private boolean isAddLinksShown() {
return (isAddLinksNotEmpty() || getLinksNumber(DOMAIN_STATE_SELECTED) > 0);
}
private void showProgressDialogFragment() {
final Bundle args = new Bundle();
args.putString(APP_PACKAGE_KEY, mPackageName);

View File

@@ -73,6 +73,7 @@ public class StorageCategoryFragment extends DashboardFragment
LoaderManager.LoaderCallbacks<SparseArray<StorageAsyncLoader.StorageResult>>,
Preference.OnPreferenceClickListener {
private static final String TAG = "StorageCategoryFrag";
private static final String SELECTED_STORAGE_ENTRY_KEY = "selected_storage_entry_key";
private static final String SUMMARY_PREF_KEY = "storage_summary";
private static final String FREE_UP_SPACE_PREF_KEY = "free_up_space";
private static final int STORAGE_JOB_ID = 0;
@@ -127,6 +128,10 @@ public class StorageCategoryFragment extends DashboardFragment
mStorageManager = getActivity().getSystemService(StorageManager.class);
if (icicle != null) {
mSelectedStorageEntry = icicle.getParcelable(SELECTED_STORAGE_ENTRY_KEY);
}
initializePreference();
}
@@ -167,6 +172,12 @@ public class StorageCategoryFragment extends DashboardFragment
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putParcelable(SELECTED_STORAGE_ENTRY_KEY, mSelectedStorageEntry);
super.onSaveInstanceState(outState);
}
private void onReceivedSizes() {
boolean stopLoading = false;
if (mStorageInfo != null) {

View File

@@ -17,8 +17,6 @@
package com.android.settings.deviceinfo;
import android.content.Context;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.AttributeSet;
import android.widget.ProgressBar;
@@ -26,6 +24,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settings.deviceinfo.storage.StorageUtils;
public class StorageItemPreference extends Preference {
public int userHandle;
@@ -49,7 +48,7 @@ public class StorageItemPreference extends Preference {
public void setStorageSize(long size, long total) {
mStorageSize = size;
setSummary(getStorageSummary(size));
setSummary(StorageUtils.getStorageSizeLabel(getContext(), size));
if (total == 0) {
mProgressPercent = 0;
@@ -77,11 +76,4 @@ public class StorageItemPreference extends Preference {
updateProgressBar();
super.onBindViewHolder(view);
}
private String getStorageSummary(long bytes) {
final Formatter.BytesResult result = Formatter.formatBytes(getContext().getResources(),
bytes, Formatter.FLAG_SHORTER);
return TextUtils.expandTemplate(getContext().getText(R.string.storage_size_large),
result.value, result.units).toString();
}
}

View File

@@ -18,25 +18,54 @@ package com.android.settings.deviceinfo.storage;
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.util.Log;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.utils.ThreadUtils;
/**
* Dialog asks if users want to empty trash files.
* TODO(b/189388449): Shows "Deleting..." and disables Trash category while deleting trash files.
*/
public class EmptyTrashFragment extends InstrumentedDialogFragment {
private static final String TAG = "EmptyTrashFragment";
private static final String TAG_EMPTY_TRASH = "empty_trash";
private final Fragment mParentFragment;
private final int mUserId;
private final long mTrashSize;
private final OnEmptyTrashCompleteListener mOnEmptyTrashCompleteListener;
/** The listener to receive empty trash complete callback event. */
public interface OnEmptyTrashCompleteListener {
/** The empty trash complete callback. */
void onEmptyTrashComplete();
}
public EmptyTrashFragment(Fragment parent, int userId, long trashSize,
OnEmptyTrashCompleteListener onEmptyTrashCompleteListener) {
super();
mParentFragment = parent;
setTargetFragment(mParentFragment, 0 /* requestCode */);
mUserId = userId;
mTrashSize = trashSize;
mOnEmptyTrashCompleteListener = onEmptyTrashCompleteListener;
}
/** Shows the empty trash dialog. */
public static void show(Fragment parent) {
final EmptyTrashFragment dialog = new EmptyTrashFragment();
dialog.setTargetFragment(parent, 0 /* requestCode */);
dialog.show(parent.getFragmentManager(), TAG_EMPTY_TRASH);
public void show() {
show(mParentFragment.getFragmentManager(), TAG_EMPTY_TRASH);
}
@Override
@@ -48,10 +77,38 @@ public class EmptyTrashFragment extends InstrumentedDialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
return builder.setTitle(R.string.storage_trash_dialog_title)
.setMessage(R.string.storage_trash_dialog_ask_message)
.setPositiveButton(R.string.storage_trash_dialog_confirm, (dialog, which) -> {
// TODO(170918505): Implement the logic in worker thread.
}).setNegativeButton(android.R.string.cancel, null)
.setMessage(getActivity().getString(R.string.storage_trash_dialog_ask_message,
StorageUtils.getStorageSizeLabel(getActivity(), mTrashSize)))
.setPositiveButton(R.string.storage_trash_dialog_confirm,
(dialog, which) -> emptyTrashAsync())
.setNegativeButton(android.R.string.cancel, null)
.create();
}
private void emptyTrashAsync() {
final Context context = getActivity();
final Context perUserContext;
try {
perUserContext = context.createPackageContextAsUser(
context.getApplicationContext().getPackageName(),
0 /* flags= */,
UserHandle.of(mUserId));
} catch (NameNotFoundException e) {
Log.e(TAG, "Not able to get Context for user ID " + mUserId);
return;
}
final Bundle trashQueryArgs = new Bundle();
trashQueryArgs.putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, MediaStore.MATCH_ONLY);
ThreadUtils.postOnBackgroundThread(() -> {
perUserContext.getContentResolver().delete(
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL),
trashQueryArgs);
if (mOnEmptyTrashCompleteListener == null) {
return;
}
ThreadUtils.postOnMainThread(
() -> mOnEmptyTrashCompleteListener.onEmptyTrashComplete());
});
}
}

View File

@@ -32,6 +32,7 @@ import android.os.UserManager;
import android.os.storage.VolumeInfo;
import android.util.Log;
import android.util.SparseArray;
import android.widget.Toast;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
@@ -64,7 +65,8 @@ import java.util.Map;
* categorization breakdown.
*/
public class StorageItemPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin {
PreferenceControllerMixin,
EmptyTrashFragment.OnEmptyTrashCompleteListener {
private static final String TAG = "StorageItemPreference";
private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo";
@@ -256,8 +258,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mGamesPreference.setVisible(privateStoragePreferencesVisible);
mDocumentsAndOtherPreference.setVisible(privateStoragePreferencesVisible);
mSystemPreference.setVisible(privateStoragePreferencesVisible);
// TODO(b/170918505): Shows trash category after trash category feature complete.
mTrashPreference.setVisible(false);
mTrashPreference.setVisible(privateStoragePreferencesVisible);
if (privateStoragePreferencesVisible) {
final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume);
@@ -460,13 +461,29 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
private void launchTrashIntent() {
final Intent intent = new Intent("android.settings.VIEW_TRASH");
if (intent.resolveActivity(mPackageManager) == null) {
EmptyTrashFragment.show(mFragment);
if (mPackageManager.resolveActivityAsUser(intent, 0 /* flags */, mUserId) == null) {
final long trashSize = mTrashPreference.getStorageSize();
if (trashSize > 0) {
new EmptyTrashFragment(mFragment, mUserId, trashSize,
this /* onEmptyTrashCompleteListener */).show();
} else {
Toast.makeText(mContext, R.string.storage_trash_dialog_empty_message,
Toast.LENGTH_SHORT).show();
}
} else {
mContext.startActivityAsUser(intent, new UserHandle(mUserId));
}
}
@Override
public void onEmptyTrashComplete() {
if (mTrashPreference == null) {
return;
}
mTrashPreference.setStorageSize(0, mTotalSize);
updatePrivateStorageCategoryPreferencesOrder();
}
private static long totalValues(StorageMeasurement.MeasurementDetails details, int userId,
String... keys) {
long total = 0;

View File

@@ -26,6 +26,8 @@ import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;
import android.widget.Toast;
@@ -115,6 +117,14 @@ public class StorageUtils {
.launch();
}
/** Returns size label of changing units. (e.g., 1kB, 2MB, 3GB) */
public static String getStorageSizeLabel(Context context, long bytes) {
final Formatter.BytesResult result = Formatter.formatBytes(context.getResources(),
bytes, Formatter.FLAG_SHORTER);
return TextUtils.expandTemplate(context.getText(R.string.storage_size_large),
result.value, result.units).toString();
}
/** An AsyncTask to unmount a specified volume. */
public static class UnmountTask extends AsyncTask<Void, Void, Exception> {
private final Context mContext;

View File

@@ -55,11 +55,14 @@ import java.util.List;
* implementation.
*/
@SearchIndexable
public class LocationSettings extends DashboardFragment {
public class LocationSettings extends DashboardFragment implements
LocationEnabler.LocationModeChangeListener {
private static final String TAG = "LocationSettings";
private static final String RECENT_LOCATION_ACCESS_PREF_KEY = "recent_location_access";
private LocationSwitchBarController mSwitchBarController;
private LocationEnabler mLocationEnabler;
@Override
public int getMetricsCategory() {
@@ -75,6 +78,7 @@ public class LocationSettings extends DashboardFragment {
switchBar.show();
mSwitchBarController = new LocationSwitchBarController(activity, switchBar,
getSettingsLifecycle());
mLocationEnabler = new LocationEnabler(getContext(), this, getSettingsLifecycle());
}
@Override
@@ -98,6 +102,13 @@ public class LocationSettings extends DashboardFragment {
return TAG;
}
@Override
public void onLocationModeChanged(int mode, boolean restricted) {
if (mLocationEnabler.isEnabled(mode)) {
scrollToPreference(RECENT_LOCATION_ACCESS_PREF_KEY);
}
}
static void addPreferencesSorted(List<Preference> prefs, PreferenceGroup container) {
// If there's some items to display, sort the items and add them to the container.
Collections.sort(prefs,

View File

@@ -109,24 +109,30 @@ public class LocationSettingsFooterPreferenceControllerTest {
assertThat(mController.isAvailable()).isTrue();
}
/**
* Display the footer even without the injected string.
*/
@Test
public void isAvailable_noSystemApp_returnsFalse() {
public void isAvailable_noSystemApp_returnsTrue() {
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
testResolveInfos.add(
getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true));
when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
.thenReturn(testResolveInfos);
assertThat(mController.isAvailable()).isFalse();
assertThat(mController.isAvailable()).isTrue();
}
/**
* Display the footer even without the injected string.
*/
@Test
public void isAvailable_noRequiredMetadata_returnsFalse() {
public void isAvailable_noRequiredMetadata_returnsTrue() {
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
testResolveInfos.add(
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ false));
when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
.thenReturn(testResolveInfos);
assertThat(mController.isAvailable()).isFalse();
assertThat(mController.isAvailable()).isTrue();
}
@Test
@@ -154,7 +160,8 @@ public class LocationSettingsFooterPreferenceControllerTest {
mController.onLocationModeChanged(/* mode= */ 0, /* restricted= */ false);
ArgumentCaptor<CharSequence> title = ArgumentCaptor.forClass(CharSequence.class);
verify(mFooterPreference, times(2)).setTitle(title.capture());
assertThat(title.getValue().toString()).isEqualTo(
assertThat(title.getValue().toString()).contains(
Html.fromHtml(mContext.getString(
R.string.location_settings_footer_location_off)).toString());
}
@@ -171,7 +178,7 @@ public class LocationSettingsFooterPreferenceControllerTest {
mController.onLocationModeChanged(/* mode= */ 1, /* restricted= */ false);
ArgumentCaptor<CharSequence> title = ArgumentCaptor.forClass(CharSequence.class);
verify(mFooterPreference, times(2)).setTitle(title.capture());
assertThat(title.getValue().toString()).isNotEqualTo(
assertThat(title.getValue().toString()).doesNotContain(
Html.fromHtml(mContext.getString(
R.string.location_settings_footer_location_off)).toString());
}