OSDN Git Service

Merge "Changed the text input type of APN name to plain text"
[android-x86/packages-apps-Settings.git] / src / com / android / settings / deviceinfo / Memory.java
1 /*
2  * Copyright (C) 2008 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 android.app.ActivityManager;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.content.BroadcastReceiver;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.content.DialogInterface.OnCancelListener;
28 import android.content.pm.ApplicationInfo;
29 import android.content.res.Resources;
30 import android.os.Bundle;
31 import android.os.IBinder;
32 import android.os.RemoteException;
33 import android.os.Environment;
34 import android.os.storage.IMountService;
35 import android.os.ServiceManager;
36 import android.os.StatFs;
37 import android.os.storage.StorageManager;
38 import android.os.storage.StorageEventListener;
39 import android.preference.Preference;
40 import android.preference.PreferenceActivity;
41 import android.preference.PreferenceGroup;
42 import android.preference.PreferenceScreen;
43 import android.text.format.Formatter;
44 import android.util.Log;
45 import android.widget.Toast;
46
47 import com.android.settings.R;
48
49 import java.io.File;
50 import java.util.List;
51
52 public class Memory extends PreferenceActivity implements OnCancelListener {
53     private static final String TAG = "Memory";
54     private static final boolean localLOGV = false;
55
56     private static final String MEMORY_SD_SIZE = "memory_sd_size";
57
58     private static final String MEMORY_SD_AVAIL = "memory_sd_avail";
59
60     private static final String MEMORY_SD_MOUNT_TOGGLE = "memory_sd_mount_toggle";
61
62     private static final String MEMORY_SD_FORMAT = "memory_sd_format";
63
64     private static final String MEMORY_SD_GROUP = "memory_sd";
65
66     private static final int DLG_CONFIRM_UNMOUNT = 1;
67     private static final int DLG_ERROR_UNMOUNT = 2;
68
69     private Resources mRes;
70
71     private Preference mSdSize;
72     private Preference mSdAvail;
73     private Preference mSdMountToggle;
74     private Preference mSdFormat;
75     private PreferenceGroup mSdMountPreferenceGroup;
76
77     boolean mSdMountToggleAdded = true;
78     
79     // Access using getMountService()
80     private IMountService mMountService = null;
81
82     private StorageManager mStorageManager = null;
83
84     @Override
85     protected void onCreate(Bundle icicle) {
86         super.onCreate(icicle);
87
88         if (mStorageManager == null) {
89             mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
90             mStorageManager.registerListener(mStorageListener);
91         }
92
93         addPreferencesFromResource(R.xml.device_info_memory);
94         
95         mRes = getResources();
96         mSdSize = findPreference(MEMORY_SD_SIZE);
97         mSdAvail = findPreference(MEMORY_SD_AVAIL);
98         mSdMountToggle = findPreference(MEMORY_SD_MOUNT_TOGGLE);
99         mSdFormat = findPreference(MEMORY_SD_FORMAT);
100
101         mSdMountPreferenceGroup = (PreferenceGroup)findPreference(MEMORY_SD_GROUP);
102     }
103     
104     @Override
105     protected void onResume() {
106         super.onResume();
107         
108         IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
109         intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
110         intentFilter.addDataScheme("file");
111         registerReceiver(mReceiver, intentFilter);
112
113         updateMemoryStatus();
114     }
115
116     StorageEventListener mStorageListener = new StorageEventListener() {
117
118         @Override
119         public void onStorageStateChanged(String path, String oldState, String newState) {
120             Log.i(TAG, "Received storage state changed notification that " +
121                     path + " changed state from " + oldState +
122                     " to " + newState);
123             updateMemoryStatus();
124         }
125     };
126     
127     @Override
128     protected void onPause() {
129         super.onPause();
130         unregisterReceiver(mReceiver);
131     }
132
133     @Override
134     protected void onDestroy() {
135         if (mStorageManager != null && mStorageListener != null) {
136             mStorageManager.unregisterListener(mStorageListener);
137         }
138         super.onDestroy();
139     }
140
141     private synchronized IMountService getMountService() {
142        if (mMountService == null) {
143            IBinder service = ServiceManager.getService("mount");
144            if (service != null) {
145                mMountService = IMountService.Stub.asInterface(service);
146            } else {
147                Log.e(TAG, "Can't get mount service");
148            }
149        }
150        return mMountService;
151     }
152     
153     @Override
154     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
155         if (preference == mSdMountToggle) {
156             String status = Environment.getExternalStorageState();
157             if (status.equals(Environment.MEDIA_MOUNTED)) {
158                 unmount();
159             } else {
160                 mount();
161             }
162             return true;
163         } else if (preference == mSdFormat) {
164             Intent intent = new Intent(Intent.ACTION_VIEW);
165             intent.setClass(this, com.android.settings.MediaFormat.class);
166             startActivity(intent);
167             return true;
168         }
169         
170         return false;
171     }
172      
173     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
174         @Override
175         public void onReceive(Context context, Intent intent) {
176             updateMemoryStatus();
177         }
178     };
179
180     @Override
181     public Dialog onCreateDialog(int id, Bundle args) {
182         switch (id) {
183         case DLG_CONFIRM_UNMOUNT:
184             return new AlertDialog.Builder(this)
185                     .setTitle(R.string.dlg_confirm_unmount_title)
186                     .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
187                         public void onClick(DialogInterface dialog, int which) {
188                             doUnmount(true);
189                         }})
190                     .setNegativeButton(R.string.cancel, null)
191                     .setMessage(R.string.dlg_confirm_unmount_text)
192                     .setOnCancelListener(this)
193                     .create();
194         case DLG_ERROR_UNMOUNT:
195             return new AlertDialog.Builder(this                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            )
196             .setTitle(R.string.dlg_error_unmount_title)
197             .setNeutralButton(R.string.dlg_ok, null)
198             .setMessage(R.string.dlg_error_unmount_text)
199             .setOnCancelListener(this)
200             .create();
201         }
202         return null;
203     }
204
205     private void doUnmount(boolean force) {
206         // Present a toast here
207         Toast.makeText(this, R.string.unmount_inform_text, Toast.LENGTH_SHORT).show();
208         IMountService mountService = getMountService();
209         String extStoragePath = Environment.getExternalStorageDirectory().toString();
210         try {
211             mSdMountToggle.setEnabled(false);
212             mSdMountToggle.setTitle(mRes.getString(R.string.sd_ejecting_title));
213             mSdMountToggle.setSummary(mRes.getString(R.string.sd_ejecting_summary));
214             mountService.unmountVolume(extStoragePath, force);
215         } catch (RemoteException e) {
216             // Informative dialog to user that
217             // unmount failed.
218             showDialogInner(DLG_ERROR_UNMOUNT);
219         }
220     }
221
222     private void showDialogInner(int id) {
223         removeDialog(id);
224         showDialog(id);
225     }
226
227     private boolean hasAppsAccessingStorage() throws RemoteException {
228         String extStoragePath = Environment.getExternalStorageDirectory().toString();
229         IMountService mountService = getMountService();
230         int stUsers[] = mountService.getStorageUsers(extStoragePath);
231         if (stUsers != null && stUsers.length > 0) {
232             return true;
233         }
234         ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
235         List<ApplicationInfo> list = am.getRunningExternalApplications();
236         if (list != null && list.size() > 0) {
237             return true;
238         }
239         return false;
240     }
241
242     private void unmount() {
243         // Check if external media is in use.
244         try {
245            if (hasAppsAccessingStorage()) {
246                if (localLOGV) Log.i(TAG, "Do have storage users accessing media");
247                // Present dialog to user
248                showDialogInner(DLG_CONFIRM_UNMOUNT);
249            } else {
250                doUnmount(true);
251            }
252         } catch (RemoteException e) {
253             // Very unlikely. But present an error dialog anyway
254             Log.e(TAG, "Is MountService running?");
255             showDialogInner(DLG_ERROR_UNMOUNT);
256         }
257     }
258
259     private void mount() {
260         IMountService mountService = getMountService();
261         try {
262             if (mountService != null) {
263                 mountService.mountVolume(Environment.getExternalStorageDirectory().toString());
264             } else {
265                 Log.e(TAG, "Mount service is null, can't mount");
266             }
267         } catch (RemoteException ex) {
268         }
269     }
270
271     private void updateMemoryStatus() {
272         String status = Environment.getExternalStorageState();
273         String readOnly = "";
274         if (status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
275             status = Environment.MEDIA_MOUNTED;
276             readOnly = mRes.getString(R.string.read_only);
277         }
278  
279         if (status.equals(Environment.MEDIA_MOUNTED)) {
280             if (!Environment.isExternalStorageRemovable()) {
281                 // This device has built-in storage that is not removable.
282                 // There is no reason for the user to unmount it.
283                 if (mSdMountToggleAdded) {
284                     mSdMountPreferenceGroup.removePreference(mSdMountToggle);
285                     mSdMountToggleAdded = false;
286                 }
287             }
288             try {
289                 File path = Environment.getExternalStorageDirectory();
290                 StatFs stat = new StatFs(path.getPath());
291                 long blockSize = stat.getBlockSize();
292                 long totalBlocks = stat.getBlockCount();
293                 long availableBlocks = stat.getAvailableBlocks();
294                 
295                 mSdSize.setSummary(formatSize(totalBlocks * blockSize));
296                 mSdAvail.setSummary(formatSize(availableBlocks * blockSize) + readOnly);
297
298                 mSdMountToggle.setEnabled(true);
299                 mSdMountToggle.setTitle(mRes.getString(R.string.sd_eject));
300                 mSdMountToggle.setSummary(mRes.getString(R.string.sd_eject_summary));
301
302             } catch (IllegalArgumentException e) {
303                 // this can occur if the SD card is removed, but we haven't received the 
304                 // ACTION_MEDIA_REMOVED Intent yet.
305                 status = Environment.MEDIA_REMOVED;
306             }
307             
308         } else {
309             mSdSize.setSummary(mRes.getString(R.string.sd_unavailable));
310             mSdAvail.setSummary(mRes.getString(R.string.sd_unavailable));
311
312
313             if (!Environment.isExternalStorageRemovable()) {
314                 if (status.equals(Environment.MEDIA_UNMOUNTED)) {
315                     if (!mSdMountToggleAdded) {
316                         mSdMountPreferenceGroup.addPreference(mSdMountToggle);
317                         mSdMountToggleAdded = true;
318                     }
319                 }
320             }
321
322             if (status.equals(Environment.MEDIA_UNMOUNTED) ||
323                 status.equals(Environment.MEDIA_NOFS) ||
324                 status.equals(Environment.MEDIA_UNMOUNTABLE) ) {
325                 mSdMountToggle.setEnabled(true);
326                 mSdMountToggle.setTitle(mRes.getString(R.string.sd_mount));
327                 mSdMountToggle.setSummary(mRes.getString(R.string.sd_mount_summary));
328             } else {
329                 mSdMountToggle.setEnabled(false);
330                 mSdMountToggle.setTitle(mRes.getString(R.string.sd_mount));
331                 mSdMountToggle.setSummary(mRes.getString(R.string.sd_insert_summary));
332             }
333         }
334
335         File path = Environment.getDataDirectory();
336         StatFs stat = new StatFs(path.getPath());
337         long blockSize = stat.getBlockSize();
338         long availableBlocks = stat.getAvailableBlocks();
339         findPreference("memory_internal_avail").setSummary(formatSize(availableBlocks * blockSize));
340     }
341     
342     private String formatSize(long size) {
343         return Formatter.formatFileSize(this, size);
344     }
345
346     public void onCancel(DialogInterface dialog) {
347         finish();
348     }
349     
350 }