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

Commit 90c8b20c authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Surface storage usage of other users.

Bring up separate StorageMeasurement sessions bound to other users
on device, and surface their total usage as teal colors.  Exclude
app code size when measuring secondary users.  Shift preferences to
using keys instead of fragile index ordering.

Bug: 7003520
Change-Id: I214d0b223e53955df71104502596743f049f2027
parent ca786f39
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@
    <color name="memory_dcim">#793A7F</color>
    <color name="memory_music">#8E562A</color>
    <color name="memory_misc">#7C3030</color>
    <color name="memory_user_light">#479392</color>
    <color name="memory_user_dark">#316665</color>

    <color name="crypt_keeper_clock_background">#ff9a9a9a</color>
    <color name="crypt_keeper_clock_foreground">#ff666666</color>
+1 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ public class Settings extends PreferenceActivity
            R.id.device_section,
            R.id.sound_settings,
            R.id.display_settings,
            R.id.storage_settings,
            R.id.application_settings,
            R.id.personal_section,
            R.id.security_settings,
+3 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.storage.StorageVolume;
import android.text.format.Formatter;
import android.util.Log;
@@ -193,8 +194,8 @@ public class MiscFilesHandler extends ListActivity {
            mContext = activity;
            final StorageVolume storageVolume = activity.getIntent().getParcelableExtra(
                    StorageVolume.EXTRA_STORAGE_VOLUME);
            StorageMeasurement mMeasurement = 
                StorageMeasurement.getInstance(activity, storageVolume, false /*Unused as a key*/);
            StorageMeasurement mMeasurement = StorageMeasurement.getInstance(
                    activity, storageVolume, new UserHandle(UserHandle.USER_CURRENT), false);
            if (mMeasurement == null) return;
            mData = (ArrayList<StorageMeasurement.FileInfo>) mMeasurement.mFileInfoForMisc;
            if (mData != null) {
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.deviceinfo;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.preference.Preference;

import com.android.settings.R;

public class StorageItemPreference extends Preference {

    private int mColor = Color.MAGENTA;

    public StorageItemPreference(Context context, String key, int titleRes, int colorRes) {
        this(context, key, context.getText(titleRes), colorRes);
    }

    public StorageItemPreference(Context context, String key, CharSequence title, int colorRes) {
        super(context);
        //setLayoutResource(R.layout.app_percentage_item);

        if (colorRes != 0) {
            mColor = context.getResources().getColor(colorRes);

            final Resources res = context.getResources();
            final int width = res.getDimensionPixelSize(R.dimen.device_memory_usage_button_width);
            final int height = res.getDimensionPixelSize(R.dimen.device_memory_usage_button_height);
            setIcon(createRectShape(width, height, mColor));
        }

        setKey(key);
        setTitle(title);
        setSummary(R.string.memory_calculating_size);
    }

    private static ShapeDrawable createRectShape(int width, int height, int color) {
        ShapeDrawable shape = new ShapeDrawable(new RectShape());
        shape.setIntrinsicHeight(height);
        shape.setIntrinsicWidth(width);
        shape.getPaint().setColor(color);
        return shape;
    }

    public int getColor() {
        return mColor;
    }
}
+48 −31
Original line number Diff line number Diff line
@@ -32,18 +32,21 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.storage.StorageVolume;
import android.util.Log;
import android.util.Pair;

import com.android.internal.app.IMediaContainerService;
import com.android.internal.util.Preconditions;
import com.google.android.collect.Maps;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Measure the memory for various systems.
@@ -86,9 +89,8 @@ public class StorageMeasurement {

    private final MeasurementHandler mHandler;

    private static Map<StorageVolume, StorageMeasurement> sInstances =
        new ConcurrentHashMap<StorageVolume, StorageMeasurement>();
    private static StorageMeasurement sInternalInstance;
    private static HashMap<Pair<StorageVolume, UserHandle>, StorageMeasurement>
            sInstances = Maps.newHashMap();

    private volatile WeakReference<MeasurementReceiver> mReceiver;

@@ -99,19 +101,24 @@ public class StorageMeasurement {
    private long mMiscSize;
    private long[] mMediaSizes = new long[StorageVolumePreferenceCategory.sMediaCategories.length];

    final private StorageVolume mStorageVolume;
    final private boolean mIsPrimary;
    final private boolean mIsInternal;
    private final StorageVolume mStorageVolume;
    private final UserHandle mUser;
    private final boolean mIsPrimary;
    private final boolean mIsInternal;

    private boolean mIncludeAppCodeSize = true;

    List<FileInfo> mFileInfoForMisc;

    public interface MeasurementReceiver {
        public void updateApproximate(Bundle bundle);
        public void updateExact(Bundle bundle);
        public void updateApproximate(StorageMeasurement meas, Bundle bundle);
        public void updateExact(StorageMeasurement meas, Bundle bundle);
    }

    private StorageMeasurement(Context context, StorageVolume storageVolume, boolean isPrimary) {
    private StorageMeasurement(
            Context context, StorageVolume storageVolume, UserHandle user, boolean isPrimary) {
        mStorageVolume = storageVolume;
        mUser = Preconditions.checkNotNull(user);
        mIsInternal = storageVolume == null;
        mIsPrimary = !mIsInternal && isPrimary;

@@ -121,29 +128,33 @@ public class StorageMeasurement {
        mHandler = new MeasurementHandler(context, handlerThread.getLooper());
    }

    public void setIncludeAppCodeSize(boolean include) {
        mIncludeAppCodeSize = include;
    }

    /**
     * Get the singleton of the StorageMeasurement class. The application
     * context is used to avoid leaking activities.
     * @param storageVolume The {@link StorageVolume} that will be measured
     * @param isPrimary true when this storage volume is the primary volume
     */
    public static StorageMeasurement getInstance(Context context, StorageVolume storageVolume,
            boolean isPrimary) {
        if (storageVolume == null) {
            if (sInternalInstance == null) {
                sInternalInstance =
                    new StorageMeasurement(context.getApplicationContext(), storageVolume, isPrimary);
    public static StorageMeasurement getInstance(
            Context context, StorageVolume storageVolume, UserHandle user, boolean isPrimary) {
        final Pair<StorageVolume, UserHandle> key = new Pair<StorageVolume, UserHandle>(
                storageVolume, user);
        synchronized (sInstances) {
            StorageMeasurement value = sInstances.get(key);
            if (value == null) {
                value = new StorageMeasurement(
                        context.getApplicationContext(), storageVolume, user, isPrimary);
                sInstances.put(key, value);
            }
            return sInternalInstance;
            return value;
        }
        if (sInstances.containsKey(storageVolume)) {
            return sInstances.get(storageVolume);
        } else {
            StorageMeasurement storageMeasurement =
                new StorageMeasurement(context.getApplicationContext(), storageVolume, isPrimary);
            sInstances.put(storageVolume, storageMeasurement);
            return storageMeasurement;
    }

    public UserHandle getUser() {
        return mUser;
    }

    public void setReceiver(MeasurementReceiver receiver) {
@@ -178,7 +189,7 @@ public class StorageMeasurement {
        bundle.putLong(TOTAL_SIZE, mTotalSize);
        bundle.putLong(AVAIL_SIZE, mAvailSize);

        receiver.updateApproximate(bundle);
        receiver.updateApproximate(this, bundle);
    }

    private void sendExactUpdate() {
@@ -198,7 +209,7 @@ public class StorageMeasurement {
        bundle.putLong(MISC_SIZE, mMiscSize);
        bundle.putLongArray(MEDIA_SIZES, mMediaSizes);

        receiver.updateExact(bundle);
        receiver.updateExact(this, bundle);
    }

    private class MeasurementHandler extends Handler {
@@ -265,7 +276,7 @@ public class StorageMeasurement {
                        } else {
                            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
                            context.bindService(service, mDefContainerConn,
                                    Context.BIND_AUTO_CREATE);
                                    Context.BIND_AUTO_CREATE, mUser.getIdentifier());
                        }
                    }
                    break;
@@ -327,13 +338,19 @@ public class StorageMeasurement {

                if (succeeded) {
                    if (mIsInternal) {
                        mAppsSizeForThisStatsObserver += stats.codeSize + stats.dataSize;
                        if (mIncludeAppCodeSize) {
                            mAppsSizeForThisStatsObserver += stats.codeSize;
                        }
                        mAppsSizeForThisStatsObserver += stats.dataSize;
                    } else if (!Environment.isExternalStorageEmulated()) {
                        mAppsSizeForThisStatsObserver += stats.externalObbSize +
                                stats.externalCodeSize + stats.externalDataSize +
                                stats.externalCacheSize + stats.externalMediaSize;
                    } else {
                        mAppsSizeForThisStatsObserver += stats.codeSize + stats.dataSize +
                        if (mIncludeAppCodeSize) {
                            mAppsSizeForThisStatsObserver += stats.codeSize;
                        }
                        mAppsSizeForThisStatsObserver += stats.dataSize +
                                stats.externalCodeSize + stats.externalDataSize +
                                stats.externalCacheSize + stats.externalMediaSize +
                                stats.externalObbSize;
Loading