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 Original line Diff line number Diff line
@@ -25,6 +25,8 @@
    <color name="memory_dcim">#793A7F</color>
    <color name="memory_dcim">#793A7F</color>
    <color name="memory_music">#8E562A</color>
    <color name="memory_music">#8E562A</color>
    <color name="memory_misc">#7C3030</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_background">#ff9a9a9a</color>
    <color name="crypt_keeper_clock_foreground">#ff666666</color>
    <color name="crypt_keeper_clock_foreground">#ff666666</color>
+1 −0
Original line number Original line Diff line number Diff line
@@ -103,6 +103,7 @@ public class Settings extends PreferenceActivity
            R.id.device_section,
            R.id.device_section,
            R.id.sound_settings,
            R.id.sound_settings,
            R.id.display_settings,
            R.id.display_settings,
            R.id.storage_settings,
            R.id.application_settings,
            R.id.application_settings,
            R.id.personal_section,
            R.id.personal_section,
            R.id.security_settings,
            R.id.security_settings,
+3 −2
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.Activity;
import android.app.ListActivity;
import android.app.ListActivity;
import android.content.Context;
import android.content.Context;
import android.os.Bundle;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.storage.StorageVolume;
import android.os.storage.StorageVolume;
import android.text.format.Formatter;
import android.text.format.Formatter;
import android.util.Log;
import android.util.Log;
@@ -193,8 +194,8 @@ public class MiscFilesHandler extends ListActivity {
            mContext = activity;
            mContext = activity;
            final StorageVolume storageVolume = activity.getIntent().getParcelableExtra(
            final StorageVolume storageVolume = activity.getIntent().getParcelableExtra(
                    StorageVolume.EXTRA_STORAGE_VOLUME);
                    StorageVolume.EXTRA_STORAGE_VOLUME);
            StorageMeasurement mMeasurement = 
            StorageMeasurement mMeasurement = StorageMeasurement.getInstance(
                StorageMeasurement.getInstance(activity, storageVolume, false /*Unused as a key*/);
                    activity, storageVolume, new UserHandle(UserHandle.USER_CURRENT), false);
            if (mMeasurement == null) return;
            if (mMeasurement == null) return;
            mData = (ArrayList<StorageMeasurement.FileInfo>) mMeasurement.mFileInfoForMisc;
            mData = (ArrayList<StorageMeasurement.FileInfo>) mMeasurement.mFileInfoForMisc;
            if (mData != null) {
            if (mData != null) {
+65 −0
Original line number Original line 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 Original line Diff line number Diff line
@@ -32,18 +32,21 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.storage.StorageVolume;
import android.os.storage.StorageVolume;
import android.util.Log;
import android.util.Log;
import android.util.Pair;


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


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


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


    private final MeasurementHandler mHandler;
    private final MeasurementHandler mHandler;


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


    private volatile WeakReference<MeasurementReceiver> mReceiver;
    private volatile WeakReference<MeasurementReceiver> mReceiver;


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


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

    private boolean mIncludeAppCodeSize = true;


    List<FileInfo> mFileInfoForMisc;
    List<FileInfo> mFileInfoForMisc;


    public interface MeasurementReceiver {
    public interface MeasurementReceiver {
        public void updateApproximate(Bundle bundle);
        public void updateApproximate(StorageMeasurement meas, Bundle bundle);
        public void updateExact(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;
        mStorageVolume = storageVolume;
        mUser = Preconditions.checkNotNull(user);
        mIsInternal = storageVolume == null;
        mIsInternal = storageVolume == null;
        mIsPrimary = !mIsInternal && isPrimary;
        mIsPrimary = !mIsInternal && isPrimary;


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


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

    /**
    /**
     * Get the singleton of the StorageMeasurement class. The application
     * Get the singleton of the StorageMeasurement class. The application
     * context is used to avoid leaking activities.
     * context is used to avoid leaking activities.
     * @param storageVolume The {@link StorageVolume} that will be measured
     * @param storageVolume The {@link StorageVolume} that will be measured
     * @param isPrimary true when this storage volume is the primary volume
     * @param isPrimary true when this storage volume is the primary volume
     */
     */
    public static StorageMeasurement getInstance(Context context, StorageVolume storageVolume,
    public static StorageMeasurement getInstance(
            boolean isPrimary) {
            Context context, StorageVolume storageVolume, UserHandle user, boolean isPrimary) {
        if (storageVolume == null) {
        final Pair<StorageVolume, UserHandle> key = new Pair<StorageVolume, UserHandle>(
            if (sInternalInstance == null) {
                storageVolume, user);
                sInternalInstance =
        synchronized (sInstances) {
                    new StorageMeasurement(context.getApplicationContext(), storageVolume, isPrimary);
            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) {
    public void setReceiver(MeasurementReceiver receiver) {
@@ -178,7 +189,7 @@ public class StorageMeasurement {
        bundle.putLong(TOTAL_SIZE, mTotalSize);
        bundle.putLong(TOTAL_SIZE, mTotalSize);
        bundle.putLong(AVAIL_SIZE, mAvailSize);
        bundle.putLong(AVAIL_SIZE, mAvailSize);


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


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


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


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


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