From e7a9b8bb200a1389472a766791bff2091b47a07c Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 6 Dec 2017 15:22:18 -0700 Subject: [PATCH] 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 --- .../deviceinfo/StorageWizardInit.java | 46 +++++++++++++++++-- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/com/android/settings/deviceinfo/StorageWizardInit.java b/src/com/android/settings/deviceinfo/StorageWizardInit.java index ffc07e520f3..05c7b152896 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardInit.java +++ b/src/com/android/settings/deviceinfo/StorageWizardInit.java @@ -16,18 +16,26 @@ package com.android.settings.deviceinfo; +import static com.android.settings.deviceinfo.StorageSettings.TAG; + import android.app.ActivityManager; import android.content.Intent; +import android.os.AsyncTask; import android.os.Bundle; +import android.os.Environment; import android.os.UserManager; import android.os.storage.DiskInfo; import android.os.storage.VolumeInfo; +import android.util.DebugUtils; +import android.util.Log; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.RadioButton; import com.android.settings.R; +import java.io.File; + public class StorageWizardInit extends StorageWizardBase { private RadioButton mRadioExternal; private RadioButton mRadioInternal; @@ -69,12 +77,15 @@ public class StorageWizardInit extends StorageWizardBase { mRadioExternal.setChecked(true); onNavigateNext(); finish(); - } - - // TODO: Show a message about why this is disabled for guest and that only an admin user - // can adopt an sd card. - if (!mIsPermittedToAdopt) { + } else if (!mIsPermittedToAdopt) { + // TODO: Show a message about why this is disabled for guest and + // that only an admin user can adopt an sd card. 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); } } + + /** + * Task that classifies the contents of a mounted storage device, and sets a + * recommended default operation based on result. + */ + public class ClassifyTask extends AsyncTask { + @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); + } + } + } }