blob: d4f93fa83cdf6d640aa5df2dd7e4a48d4595031b [file] [log] [blame]
/*
* Copyright (C) 2021 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.deviceinfo;
import android.app.ActivityManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.UserManager;
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.deviceinfo.storage.StorageEntry;
import com.android.settings.deviceinfo.storage.StorageRenameFragment;
import com.android.settings.deviceinfo.storage.StorageUtils;
import com.android.settings.deviceinfo.storage.StorageUtils.MountTask;
import com.android.settings.deviceinfo.storage.StorageUtils.UnmountTask;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
import java.util.Objects;
/**
* Handles the option menu on the Storage settings.
*/
public class VolumeOptionMenuController implements LifecycleObserver, OnCreateOptionsMenu,
OnPrepareOptionsMenu, OnOptionsItemSelected {
@VisibleForTesting
MenuItem mRename;
@VisibleForTesting
MenuItem mMount;
@VisibleForTesting
MenuItem mUnmount;
@VisibleForTesting
MenuItem mFormat;
@VisibleForTesting
MenuItem mFormatAsPortable;
@VisibleForTesting
MenuItem mFormatAsInternal;
@VisibleForTesting
MenuItem mMigrate;
@VisibleForTesting
MenuItem mFree;
@VisibleForTesting
MenuItem mForget;
private final Context mContext;
private final Fragment mFragment;
private final PackageManager mPackageManager;
private final StorageManager mStorageManager;
private StorageEntry mStorageEntry;
public VolumeOptionMenuController(Context context, Fragment parent, StorageEntry storageEntry) {
mContext = context;
mFragment = parent;
mPackageManager = context.getPackageManager();
mStorageManager = context.getSystemService(StorageManager.class);
mStorageEntry = storageEntry;
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.storage_volume, menu);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
mRename = menu.findItem(R.id.storage_rename);
mMount = menu.findItem(R.id.storage_mount);
mUnmount = menu.findItem(R.id.storage_unmount);
mFormat = menu.findItem(R.id.storage_format);
mFormatAsPortable = menu.findItem(R.id.storage_format_as_portable);
mFormatAsInternal = menu.findItem(R.id.storage_format_as_internal);
mMigrate = menu.findItem(R.id.storage_migrate);
mFree = menu.findItem(R.id.storage_free);
mForget = menu.findItem(R.id.storage_forget);
mRename.setVisible(false);
mMount.setVisible(false);
mUnmount.setVisible(false);
mFormat.setVisible(false);
mFormatAsPortable.setVisible(false);
mFormatAsInternal.setVisible(false);
mMigrate.setVisible(false);
mFree.setVisible(false);
mForget.setVisible(false);
if (mStorageEntry.isDiskInfoUnsupported()) {
mFormat.setVisible(true);
return;
}
if (mStorageEntry.isVolumeRecordMissed()) {
mForget.setVisible(true);
return;
}
if (mStorageEntry.isUnmounted()) {
mMount.setVisible(true);
return;
}
if (!mStorageEntry.isMounted()) {
return;
}
if (mStorageEntry.isPrivate()) {
if (!mStorageEntry.isDefaultInternalStorage()) {
mRename.setVisible(true);
mUnmount.setVisible(true);
mFormatAsPortable.setVisible(true);
}
// Only offer to migrate when not current storage.
final VolumeInfo primaryVolumeInfo = mPackageManager.getPrimaryStorageCurrentVolume();
final VolumeInfo selectedVolumeInfo = mStorageEntry.getVolumeInfo();
mMigrate.setVisible(primaryVolumeInfo != null
&& primaryVolumeInfo.getType() == VolumeInfo.TYPE_PRIVATE
&& !Objects.equals(selectedVolumeInfo, primaryVolumeInfo)
&& primaryVolumeInfo.isMountedWritable());
return;
}
if (mStorageEntry.isPublic()) {
mRename.setVisible(true);
mUnmount.setVisible(true);
mFormat.setVisible(true);
final DiskInfo diskInfo = mStorageManager.findDiskById(mStorageEntry.getDiskId());
mFormatAsInternal.setVisible(diskInfo != null
&& diskInfo.isAdoptable()
&& UserManager.get(mContext).isAdminUser()
&& !ActivityManager.isUserAMonkey());
return;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
if (!mFragment.isAdded()) {
return false;
}
final int menuId = menuItem.getItemId();
if (menuId == R.id.storage_mount) {
if (mStorageEntry.isUnmounted()) {
new MountTask(mFragment.getActivity(), mStorageEntry.getVolumeInfo()).execute();
return true;
}
return false;
}
if (menuId == R.id.storage_unmount) {
if (mStorageEntry.isMounted()) {
if (mStorageEntry.isPublic()) {
new UnmountTask(mFragment.getActivity(),
mStorageEntry.getVolumeInfo()).execute();
return true;
}
if (mStorageEntry.isPrivate() && !mStorageEntry.isDefaultInternalStorage()) {
final Bundle args = new Bundle();
args.putString(VolumeInfo.EXTRA_VOLUME_ID, mStorageEntry.getId());
new SubSettingLauncher(mContext)
.setDestination(PrivateVolumeUnmount.class.getCanonicalName())
.setTitleRes(R.string.storage_menu_unmount)
.setSourceMetricsCategory(SettingsEnums.DEVICEINFO_STORAGE)
.setArguments(args)
.launch();
return true;
}
}
return false;
}
if (menuId == R.id.storage_rename) {
if ((mStorageEntry.isPrivate() && !mStorageEntry.isDefaultInternalStorage())
|| mStorageEntry.isPublic()) {
StorageRenameFragment.show(mFragment, mStorageEntry.getVolumeInfo());
return true;
}
return false;
}
if (menuId == R.id.storage_format) {
if (mStorageEntry.isDiskInfoUnsupported() || mStorageEntry.isPublic()) {
StorageWizardFormatConfirm.showPublic(mFragment.getActivity(),
mStorageEntry.getDiskId());
return true;
}
return false;
}
if (menuId == R.id.storage_format_as_portable) {
if (mStorageEntry.isPrivate()) {
final Bundle args = new Bundle();
args.putString(VolumeInfo.EXTRA_VOLUME_ID, mStorageEntry.getId());
new SubSettingLauncher(mContext)
.setDestination(PrivateVolumeFormat.class.getCanonicalName())
.setTitleRes(R.string.storage_menu_format)
.setSourceMetricsCategory(SettingsEnums.DEVICEINFO_STORAGE)
.setArguments(args)
.launch();
return true;
}
return false;
}
if (menuId == R.id.storage_format_as_internal) {
if (mStorageEntry.isPublic()) {
StorageWizardFormatConfirm.showPrivate(mFragment.getActivity(),
mStorageEntry.getDiskId());
return true;
}
return false;
}
if (menuId == R.id.storage_migrate) {
if (mStorageEntry.isPrivate()) {
final Intent intent = new Intent(mContext, StorageWizardMigrateConfirm.class);
intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, mStorageEntry.getId());
mContext.startActivity(intent);
return true;
}
return false;
}
if (menuId == R.id.storage_forget) {
if (mStorageEntry.isVolumeRecordMissed()) {
StorageUtils.launchForgetMissingVolumeRecordFragment(mContext, mStorageEntry);
return true;
}
return false;
}
return false;
}
public void setSelectedStorageEntry(StorageEntry storageEntry) {
mStorageEntry = storageEntry;
}
}