• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
onCreate(Bundle savedInstanceState)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
setContentView(@ayoutRes int layoutResID)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
onDestroy()100     protected void onDestroy() {
101         mStorage.unregisterListener(mStorageListener);
102         super.onDestroy();
103     }
104 
getBackButton()105     protected Button getBackButton() {
106         return mBack;
107     }
108 
getNextButton()109     protected Button getNextButton() {
110         return mNext;
111     }
112 
getGlifLayout()113     protected GlifLayout getGlifLayout() {
114         return requireViewById(R.id.setup_wizard_layout);
115     }
116 
getProgressBar()117     protected ProgressBar getProgressBar() {
118         return requireViewById(R.id.storage_wizard_progress);
119     }
120 
setCurrentProgress(int progress)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 
setHeaderText(int resId, CharSequence... args)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 
setBodyText(int resId, CharSequence... args)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 
setAuxChecklist()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 
setBackButtonText(int resId, CharSequence... args)152     protected void setBackButtonText(int resId, CharSequence... args) {
153         mBack.setText(TextUtils.expandTemplate(getText(resId), args));
154         mBack.setVisibility(View.VISIBLE);
155     }
156 
setNextButtonText(int resId, CharSequence... args)157     protected void setNextButtonText(int resId, CharSequence... args) {
158         mNext.setText(TextUtils.expandTemplate(getText(resId), args));
159         mNext.setVisibility(View.VISIBLE);
160     }
161 
setIcon(int resId)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 
setKeepScreenOn(boolean keepScreenOn)169     protected void setKeepScreenOn(boolean keepScreenOn) {
170         getGlifLayout().setKeepScreenOn(keepScreenOn);
171     }
172 
onNavigateBack(View view)173     public void onNavigateBack(View view) {
174         throw new UnsupportedOperationException();
175     }
176 
onNavigateNext(View view)177     public void onNavigateNext(View view) {
178         throw new UnsupportedOperationException();
179     }
180 
copyStringExtra(Intent from, Intent to, String key)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 
copyBooleanExtra(Intent from, Intent to, String key)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
startActivity(Intent intent)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 
findFirstVolume(int type)208     protected VolumeInfo findFirstVolume(int type) {
209         return findFirstVolume(type, 1);
210     }
211 
findFirstVolume(int type, int attempts)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 
getDiskDescription()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 
getDiskShortDescription()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