Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7a9b8bb authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

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
parent d7d5754c
Loading
Loading
Loading
Loading
+41 −5
Original line number Diff line number Diff line
@@ -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<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);
            }
        }
    }
}