Guide user towards adoption when card is "empty".
When a newly inserted SD card is empty, we'd like to guide the user towards adopting it. Similarly, if the card contains personal media like photos, we'd like to guide the user towards using it as portable storage. Do this by quickly hunting around on the card for files under various well-known directories. Special logic to ignore bundled "helper" apps included from the SD card factory. Test: bit FrameworksCoreTests:android.os.EnvironmentTest Bug: 69128181 Exempt-From-Owner-Approval: I wrote the original code. Change-Id: I48323156dd4c3bb125fc9e66e17cc0384fe9c30c
This commit is contained in:
@@ -16,18 +16,26 @@
|
|||||||
|
|
||||||
package com.android.settings.deviceinfo;
|
package com.android.settings.deviceinfo;
|
||||||
|
|
||||||
|
import static com.android.settings.deviceinfo.StorageSettings.TAG;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.os.storage.DiskInfo;
|
import android.os.storage.DiskInfo;
|
||||||
import android.os.storage.VolumeInfo;
|
import android.os.storage.VolumeInfo;
|
||||||
|
import android.util.DebugUtils;
|
||||||
|
import android.util.Log;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class StorageWizardInit extends StorageWizardBase {
|
public class StorageWizardInit extends StorageWizardBase {
|
||||||
private RadioButton mRadioExternal;
|
private RadioButton mRadioExternal;
|
||||||
private RadioButton mRadioInternal;
|
private RadioButton mRadioInternal;
|
||||||
@@ -69,12 +77,15 @@ public class StorageWizardInit extends StorageWizardBase {
|
|||||||
mRadioExternal.setChecked(true);
|
mRadioExternal.setChecked(true);
|
||||||
onNavigateNext();
|
onNavigateNext();
|
||||||
finish();
|
finish();
|
||||||
}
|
} else if (!mIsPermittedToAdopt) {
|
||||||
|
// TODO: Show a message about why this is disabled for guest and
|
||||||
// TODO: Show a message about why this is disabled for guest and that only an admin user
|
// that only an admin user can adopt an sd card.
|
||||||
// can adopt an sd card.
|
|
||||||
if (!mIsPermittedToAdopt) {
|
|
||||||
mRadioInternal.setEnabled(false);
|
mRadioInternal.setEnabled(false);
|
||||||
|
} else if (mVolume != null && mVolume.getType() == VolumeInfo.TYPE_PUBLIC
|
||||||
|
&& mVolume.isMountedReadable()) {
|
||||||
|
// Device is mounted, so classify contents to possibly pick a
|
||||||
|
// recommended default operation.
|
||||||
|
new ClassifyTask().execute(mVolume.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,4 +132,29 @@ public class StorageWizardInit extends StorageWizardBase {
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task that classifies the contents of a mounted storage device, and sets a
|
||||||
|
* recommended default operation based on result.
|
||||||
|
*/
|
||||||
|
public class ClassifyTask extends AsyncTask<File, Void, Integer> {
|
||||||
|
@Override
|
||||||
|
protected Integer doInBackground(File... params) {
|
||||||
|
int classes = Environment.classifyExternalStorageDirectory(params[0]);
|
||||||
|
Log.v(TAG, "Classified " + params[0] + " as "
|
||||||
|
+ DebugUtils.flagsToString(Environment.class, "HAS_", classes));
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Integer classes) {
|
||||||
|
if (classes == 0) {
|
||||||
|
// Empty is strong signal for adopt
|
||||||
|
mRadioInternal.setChecked(true);
|
||||||
|
} else if ((classes & (Environment.HAS_PICTURES | Environment.HAS_DCIM)) != 0) {
|
||||||
|
// Photos is strong signal for portable
|
||||||
|
mRadioExternal.setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user