1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.deviceinfo; 18 19 import static android.os.storage.DiskInfo.EXTRA_DISK_ID; 20 import static android.os.storage.VolumeInfo.EXTRA_VOLUME_ID; 21 22 import static com.android.settings.deviceinfo.StorageSettings.TAG; 23 24 import android.annotation.LayoutRes; 25 import android.annotation.NonNull; 26 import android.app.Activity; 27 import android.content.Intent; 28 import android.graphics.drawable.Drawable; 29 import android.os.Bundle; 30 import android.os.SystemClock; 31 import android.os.storage.DiskInfo; 32 import android.os.storage.StorageEventListener; 33 import android.os.storage.StorageManager; 34 import android.os.storage.VolumeInfo; 35 import android.text.TextUtils; 36 import android.util.Log; 37 import android.view.LayoutInflater; 38 import android.view.View; 39 import android.widget.Button; 40 import android.widget.FrameLayout; 41 import android.widget.ProgressBar; 42 import android.widget.TextView; 43 44 import com.android.settings.R; 45 import com.android.settingslib.Utils; 46 import com.android.setupwizardlib.GlifLayout; 47 48 import java.text.NumberFormat; 49 import java.util.List; 50 import java.util.Objects; 51 52 public abstract class StorageWizardBase extends Activity { 53 protected static final String EXTRA_FORMAT_FORGET_UUID = "format_forget_uuid"; 54 protected static final String EXTRA_FORMAT_PRIVATE = "format_private"; 55 protected static final String EXTRA_FORMAT_SLOW = "format_slow"; 56 protected static final String EXTRA_MIGRATE_SKIP = "migrate_skip"; 57 58 protected StorageManager mStorage; 59 60 protected VolumeInfo mVolume; 61 protected DiskInfo mDisk; 62 63 private Button mBack; 64 private Button mNext; 65 66 @Override 67 protected void onCreate(Bundle savedInstanceState) { 68 super.onCreate(savedInstanceState); 69 70 mStorage = getSystemService(StorageManager.class); 71 72 final String volumeId = getIntent().getStringExtra(EXTRA_VOLUME_ID); 73 if (!TextUtils.isEmpty(volumeId)) { 74 mVolume = mStorage.findVolumeById(volumeId); 75 } 76 77 final String diskId = getIntent().getStringExtra(EXTRA_DISK_ID); 78 if (!TextUtils.isEmpty(diskId)) { 79 mDisk = mStorage.findDiskById(diskId); 80 } else if (mVolume != null) { 81 mDisk = mVolume.getDisk(); 82 } 83 84 if (mDisk != null) { 85 mStorage.registerListener(mStorageListener); 86 } 87 } 88 89 @Override 90 public void setContentView(@LayoutRes int layoutResID) { 91 super.setContentView(layoutResID); 92 93 mBack = requireViewById(R.id.storage_back_button); 94 mNext = requireViewById(R.id.storage_next_button); 95 96 setIcon(com.android.internal.R.drawable.ic_sd_card_48dp); 97 } 98 99 @Override 100 protected void onDestroy() { 101 mStorage.unregisterListener(mStorageListener); 102 super.onDestroy(); 103 } 104 105 protected Button getBackButton() { 106 return mBack; 107 } 108 109 protected Button getNextButton() { 110 return mNext; 111 } 112 113 protected GlifLayout getGlifLayout() { 114 return requireViewById(R.id.setup_wizard_layout); 115 } 116 117 protected ProgressBar getProgressBar() { 118 return requireViewById(R.id.storage_wizard_progress); 119 } 120 121 protected void setCurrentProgress(int progress) { 122 getProgressBar().setProgress(progress); 123 ((TextView) requireViewById(R.id.storage_wizard_progress_summary)).setText( 124 NumberFormat.getPercentInstance().format((double) progress / 100)); 125 } 126 127 protected void setHeaderText(int resId, CharSequence... args) { 128 final CharSequence headerText = TextUtils.expandTemplate(getText(resId), args); 129 getGlifLayout().setHeaderText(headerText); 130 setTitle(headerText); 131 } 132 133 protected void setBodyText(int resId, CharSequence... args) { 134 final TextView body = requireViewById(R.id.storage_wizard_body); 135 body.setText(TextUtils.expandTemplate(getText(resId), args)); 136 body.setVisibility(View.VISIBLE); 137 } 138 139 protected void setAuxChecklist() { 140 final FrameLayout aux = requireViewById(R.id.storage_wizard_aux); 141 aux.addView(LayoutInflater.from(aux.getContext()) 142 .inflate(R.layout.storage_wizard_checklist, aux, false)); 143 aux.setVisibility(View.VISIBLE); 144 145 // Customize string based on disk 146 ((TextView) aux.requireViewById(R.id.storage_wizard_migrate_v2_checklist_media)) 147 .setText(TextUtils.expandTemplate( 148 getText(R.string.storage_wizard_migrate_v2_checklist_media), 149 getDiskShortDescription())); 150 } 151 152 protected void setBackButtonText(int resId, CharSequence... args) { 153 mBack.setText(TextUtils.expandTemplate(getText(resId), args)); 154 mBack.setVisibility(View.VISIBLE); 155 } 156 157 protected void setNextButtonText(int resId, CharSequence... args) { 158 mNext.setText(TextUtils.expandTemplate(getText(resId), args)); 159 mNext.setVisibility(View.VISIBLE); 160 } 161 162 protected void setIcon(int resId) { 163 final GlifLayout layout = getGlifLayout(); 164 final Drawable icon = getDrawable(resId).mutate(); 165 icon.setTint(Utils.getColorAccent(layout.getContext())); 166 layout.setIcon(icon); 167 } 168 169 protected void setKeepScreenOn(boolean keepScreenOn) { 170 getGlifLayout().setKeepScreenOn(keepScreenOn); 171 } 172 173 public void onNavigateBack(View view) { 174 throw new UnsupportedOperationException(); 175 } 176 177 public void onNavigateNext(View view) { 178 throw new UnsupportedOperationException(); 179 } 180 181 private void copyStringExtra(Intent from, Intent to, String key) { 182 if (from.hasExtra(key) && !to.hasExtra(key)) { 183 to.putExtra(key, from.getStringExtra(key)); 184 } 185 } 186 187 private void copyBooleanExtra(Intent from, Intent to, String key) { 188 if (from.hasExtra(key) && !to.hasExtra(key)) { 189 to.putExtra(key, from.getBooleanExtra(key, false)); 190 } 191 } 192 193 @Override 194 public void startActivity(Intent intent) { 195 final Intent from = getIntent(); 196 final Intent to = intent; 197 198 copyStringExtra(from, to, EXTRA_DISK_ID); 199 copyStringExtra(from, to, EXTRA_VOLUME_ID); 200 copyStringExtra(from, to, EXTRA_FORMAT_FORGET_UUID); 201 copyBooleanExtra(from, to, EXTRA_FORMAT_PRIVATE); 202 copyBooleanExtra(from, to, EXTRA_FORMAT_SLOW); 203 copyBooleanExtra(from, to, EXTRA_MIGRATE_SKIP); 204 205 super.startActivity(intent); 206 } 207 208 protected VolumeInfo findFirstVolume(int type) { 209 return findFirstVolume(type, 1); 210 } 211 212 protected VolumeInfo findFirstVolume(int type, int attempts) { 213 while (true) { 214 final List<VolumeInfo> vols = mStorage.getVolumes(); 215 for (VolumeInfo vol : vols) { 216 if (Objects.equals(mDisk.getId(), vol.getDiskId()) && (vol.getType() == type) 217 && (vol.getState() == VolumeInfo.STATE_MOUNTED)) { 218 return vol; 219 } 220 } 221 222 if (--attempts > 0) { 223 Log.w(TAG, "Missing mounted volume of type " + type + " hosted by disk " 224 + mDisk.getId() + "; trying again"); 225 SystemClock.sleep(250); 226 } else { 227 return null; 228 } 229 } 230 } 231 232 protected @NonNull CharSequence getDiskDescription() { 233 if (mDisk != null) { 234 return mDisk.getDescription(); 235 } else if (mVolume != null) { 236 return mVolume.getDescription(); 237 } else { 238 return getText(R.string.unknown); 239 } 240 } 241 242 protected @NonNull CharSequence getDiskShortDescription() { 243 if (mDisk != null) { 244 return mDisk.getShortDescription(); 245 } else if (mVolume != null) { 246 return mVolume.getDescription(); 247 } else { 248 return getText(R.string.unknown); 249 } 250 } 251 252 private final StorageEventListener mStorageListener = new StorageEventListener() { 253 @Override 254 public void onDiskDestroyed(DiskInfo disk) { 255 // We know mDisk != null. 256 if (mDisk.id.equals(disk.id)) { 257 finish(); 258 } 259 } 260 }; 261 } 262