| /* |
| * Copyright (C) 2015 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 static android.os.storage.DiskInfo.EXTRA_DISK_ID; |
| import static android.os.storage.VolumeInfo.EXTRA_VOLUME_ID; |
| |
| import static com.android.settings.deviceinfo.StorageSettings.TAG; |
| |
| import android.annotation.LayoutRes; |
| import android.annotation.NonNull; |
| import android.content.Intent; |
| import android.content.res.Resources.Theme; |
| import android.graphics.drawable.Drawable; |
| import android.os.Bundle; |
| import android.os.SystemClock; |
| import android.os.storage.DiskInfo; |
| import android.os.storage.StorageEventListener; |
| import android.os.storage.StorageManager; |
| import android.os.storage.VolumeInfo; |
| import android.text.TextUtils; |
| import android.util.Log; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.widget.FrameLayout; |
| import android.widget.ProgressBar; |
| import android.widget.TextView; |
| |
| import androidx.fragment.app.FragmentActivity; |
| |
| import com.android.settings.R; |
| import com.android.settingslib.Utils; |
| |
| import com.google.android.setupcompat.template.FooterBarMixin; |
| import com.google.android.setupcompat.template.FooterButton; |
| import com.google.android.setupdesign.GlifLayout; |
| |
| import java.text.NumberFormat; |
| import java.util.List; |
| import java.util.Objects; |
| |
| public abstract class StorageWizardBase extends FragmentActivity { |
| protected static final String EXTRA_FORMAT_FORGET_UUID = "format_forget_uuid"; |
| protected static final String EXTRA_FORMAT_PRIVATE = "format_private"; |
| protected static final String EXTRA_FORMAT_SLOW = "format_slow"; |
| protected static final String EXTRA_MIGRATE_SKIP = "migrate_skip"; |
| |
| protected StorageManager mStorage; |
| |
| protected VolumeInfo mVolume; |
| protected DiskInfo mDisk; |
| |
| private FooterBarMixin mFooterBarMixin; |
| private FooterButton mBack; |
| private FooterButton mNext; |
| |
| @Override |
| protected void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| mStorage = getSystemService(StorageManager.class); |
| |
| final String volumeId = getIntent().getStringExtra(EXTRA_VOLUME_ID); |
| if (!TextUtils.isEmpty(volumeId)) { |
| mVolume = mStorage.findVolumeById(volumeId); |
| } |
| |
| final String diskId = getIntent().getStringExtra(EXTRA_DISK_ID); |
| if (!TextUtils.isEmpty(diskId)) { |
| mDisk = mStorage.findDiskById(diskId); |
| } else if (mVolume != null) { |
| mDisk = mVolume.getDisk(); |
| } |
| |
| if (mDisk != null) { |
| mStorage.registerListener(mStorageListener); |
| } |
| } |
| |
| @Override |
| public void setContentView(@LayoutRes int layoutResID) { |
| super.setContentView(layoutResID); |
| |
| mFooterBarMixin = getGlifLayout().getMixin(FooterBarMixin.class); |
| mFooterBarMixin.setSecondaryButton( |
| new FooterButton.Builder(this) |
| .setText(R.string.wizard_back) |
| .setListener(this::onNavigateBack) |
| .setButtonType(FooterButton.ButtonType.OTHER) |
| .setTheme(R.style.SudGlifButton_Secondary) |
| .build() |
| ); |
| mFooterBarMixin.setPrimaryButton( |
| new FooterButton.Builder(this) |
| .setText(R.string.wizard_next) |
| .setListener(this::onNavigateNext) |
| .setButtonType(FooterButton.ButtonType.NEXT) |
| .setTheme(R.style.SudGlifButton_Primary) |
| .build() |
| ); |
| mBack = mFooterBarMixin.getSecondaryButton(); |
| mNext = mFooterBarMixin.getPrimaryButton(); |
| |
| setIcon(com.android.internal.R.drawable.ic_sd_card_48dp); |
| } |
| |
| @Override |
| protected void onDestroy() { |
| mStorage.unregisterListener(mStorageListener); |
| super.onDestroy(); |
| } |
| |
| @Override |
| protected void onApplyThemeResource(Theme theme, int resid, boolean first) { |
| theme.applyStyle(R.style.SetupWizardPartnerResource, true); |
| super.onApplyThemeResource(theme, resid, first); |
| } |
| |
| protected FooterButton getBackButton() { |
| return mBack; |
| } |
| |
| protected FooterButton getNextButton() { |
| return mNext; |
| } |
| |
| protected GlifLayout getGlifLayout() { |
| return requireViewById(R.id.setup_wizard_layout); |
| } |
| |
| protected ProgressBar getProgressBar() { |
| return requireViewById(R.id.storage_wizard_progress); |
| } |
| |
| protected void setCurrentProgress(int progress) { |
| getProgressBar().setProgress(progress); |
| ((TextView) requireViewById(R.id.storage_wizard_progress_summary)).setText( |
| NumberFormat.getPercentInstance().format((double) progress / 100)); |
| } |
| |
| protected void setHeaderText(int resId, CharSequence... args) { |
| final CharSequence headerText = TextUtils.expandTemplate(getText(resId), args); |
| getGlifLayout().setHeaderText(headerText); |
| setTitle(headerText); |
| } |
| |
| protected void setBodyText(int resId, CharSequence... args) { |
| final TextView body = requireViewById(R.id.storage_wizard_body); |
| body.setText(TextUtils.expandTemplate(getText(resId), args)); |
| body.setVisibility(View.VISIBLE); |
| } |
| |
| protected void setAuxChecklist() { |
| final FrameLayout aux = requireViewById(R.id.storage_wizard_aux); |
| aux.addView(LayoutInflater.from(aux.getContext()) |
| .inflate(R.layout.storage_wizard_checklist, aux, false)); |
| aux.setVisibility(View.VISIBLE); |
| |
| // Customize string based on disk |
| ((TextView) aux.requireViewById(R.id.storage_wizard_migrate_v2_checklist_media)) |
| .setText(TextUtils.expandTemplate( |
| getText(R.string.storage_wizard_migrate_v2_checklist_media), |
| getDiskShortDescription())); |
| } |
| |
| protected void setBackButtonText(int resId, CharSequence... args) { |
| mBack.setText(TextUtils.expandTemplate(getText(resId), args)); |
| mBack.setVisibility(View.VISIBLE); |
| } |
| |
| protected void setNextButtonText(int resId, CharSequence... args) { |
| mNext.setText(TextUtils.expandTemplate(getText(resId), args)); |
| mNext.setVisibility(View.VISIBLE); |
| } |
| |
| protected void setBackButtonVisibility(int visible) { |
| mBack.setVisibility(visible); |
| } |
| |
| protected void setNextButtonVisibility(int visible) { |
| mNext.setVisibility(visible); |
| } |
| |
| protected void setIcon(int resId) { |
| final GlifLayout layout = getGlifLayout(); |
| final Drawable icon = getDrawable(resId).mutate(); |
| icon.setTintList(Utils.getColorAccent(layout.getContext())); |
| layout.setIcon(icon); |
| } |
| |
| protected void setKeepScreenOn(boolean keepScreenOn) { |
| getGlifLayout().setKeepScreenOn(keepScreenOn); |
| } |
| |
| public void onNavigateBack(View view) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void onNavigateNext(View view) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| private void copyStringExtra(Intent from, Intent to, String key) { |
| if (from.hasExtra(key) && !to.hasExtra(key)) { |
| to.putExtra(key, from.getStringExtra(key)); |
| } |
| } |
| |
| private void copyBooleanExtra(Intent from, Intent to, String key) { |
| if (from.hasExtra(key) && !to.hasExtra(key)) { |
| to.putExtra(key, from.getBooleanExtra(key, false)); |
| } |
| } |
| |
| @Override |
| public void startActivity(Intent intent) { |
| final Intent from = getIntent(); |
| final Intent to = intent; |
| |
| copyStringExtra(from, to, EXTRA_DISK_ID); |
| copyStringExtra(from, to, EXTRA_VOLUME_ID); |
| copyStringExtra(from, to, EXTRA_FORMAT_FORGET_UUID); |
| copyBooleanExtra(from, to, EXTRA_FORMAT_PRIVATE); |
| copyBooleanExtra(from, to, EXTRA_FORMAT_SLOW); |
| copyBooleanExtra(from, to, EXTRA_MIGRATE_SKIP); |
| |
| super.startActivity(intent); |
| } |
| |
| protected VolumeInfo findFirstVolume(int type) { |
| return findFirstVolume(type, 1); |
| } |
| |
| protected VolumeInfo findFirstVolume(int type, int attempts) { |
| while (true) { |
| final List<VolumeInfo> vols = mStorage.getVolumes(); |
| for (VolumeInfo vol : vols) { |
| if (Objects.equals(mDisk.getId(), vol.getDiskId()) && (vol.getType() == type) |
| && (vol.getState() == VolumeInfo.STATE_MOUNTED)) { |
| return vol; |
| } |
| } |
| |
| if (--attempts > 0) { |
| Log.w(TAG, "Missing mounted volume of type " + type + " hosted by disk " |
| + mDisk.getId() + "; trying again"); |
| SystemClock.sleep(250); |
| } else { |
| return null; |
| } |
| } |
| } |
| |
| protected @NonNull CharSequence getDiskDescription() { |
| if (mDisk != null) { |
| return mDisk.getDescription(); |
| } else if (mVolume != null) { |
| return mVolume.getDescription(); |
| } else { |
| return getText(R.string.unknown); |
| } |
| } |
| |
| protected @NonNull CharSequence getDiskShortDescription() { |
| if (mDisk != null) { |
| return mDisk.getShortDescription(); |
| } else if (mVolume != null) { |
| return mVolume.getDescription(); |
| } else { |
| return getText(R.string.unknown); |
| } |
| } |
| |
| private final StorageEventListener mStorageListener = new StorageEventListener() { |
| @Override |
| public void onDiskDestroyed(DiskInfo disk) { |
| // We know mDisk != null. |
| if (mDisk.id.equals(disk.id)) { |
| finish(); |
| } |
| } |
| }; |
| } |