OSDN Git Service

Move StorageMeasurement to SettingsLib
authorTony Mantler <nicoya@google.com>
Thu, 23 Apr 2015 22:19:40 +0000 (15:19 -0700)
committerTony Mantler <nicoya@google.com>
Thu, 23 Apr 2015 22:23:44 +0000 (15:23 -0700)
Change-Id: I00335fe896ef1bae11c382592eea2a354269818a

src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
src/com/android/settings/deviceinfo/StorageMeasurement.java [deleted file]

index 00fb094..492051d 100644 (file)
@@ -57,9 +57,10 @@ import com.android.settings.Settings.StorageUseActivity;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
 import com.android.settings.applications.ManageApplications;
-import com.android.settings.deviceinfo.StorageMeasurement.MeasurementDetails;
-import com.android.settings.deviceinfo.StorageMeasurement.MeasurementReceiver;
 import com.android.settings.deviceinfo.StorageSettings.MountTask;
+import com.android.settingslib.deviceinfo.StorageMeasurement;
+import com.android.settingslib.deviceinfo.StorageMeasurement.MeasurementDetails;
+import com.android.settingslib.deviceinfo.StorageMeasurement.MeasurementReceiver;
 import com.google.android.collect.Lists;
 
 import java.io.File;
diff --git a/src/com/android/settings/deviceinfo/StorageMeasurement.java b/src/com/android/settings/deviceinfo/StorageMeasurement.java
deleted file mode 100644 (file)
index b6c35e3..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * 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.app.ActivityManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageStatsObserver;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageStats;
-import android.content.pm.UserInfo;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.storage.StorageVolume;
-import android.os.storage.VolumeInfo;
-import android.util.Log;
-import android.util.SparseLongArray;
-
-import com.android.internal.app.IMediaContainerService;
-import com.android.internal.util.ArrayUtils;
-import com.google.android.collect.Sets;
-
-import java.io.File;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Utility for measuring the disk usage of internal storage or a physical
- * {@link StorageVolume}. Connects with a remote {@link IMediaContainerService}
- * and delivers results to {@link MeasurementReceiver}.
- */
-public class StorageMeasurement {
-    private static final String TAG = "StorageMeasurement";
-
-    private static final boolean LOCAL_LOGV = true;
-    static final boolean LOGV = LOCAL_LOGV && Log.isLoggable(TAG, Log.VERBOSE);
-
-    private static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
-
-    public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
-            DEFAULT_CONTAINER_PACKAGE, "com.android.defcontainer.DefaultContainerService");
-
-    /** Media types to measure on external storage. */
-    private static final Set<String> sMeasureMediaTypes = Sets.newHashSet(
-            Environment.DIRECTORY_DCIM, Environment.DIRECTORY_MOVIES,
-            Environment.DIRECTORY_PICTURES, Environment.DIRECTORY_MUSIC,
-            Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS,
-            Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS,
-            Environment.DIRECTORY_DOWNLOADS, Environment.DIRECTORY_ANDROID);
-
-    public static class MeasurementDetails {
-        /**
-         * Total apps disk usage.
-         * <p>
-         * When measuring internal storage, this value includes the code size of
-         * all apps (regardless of install status for current user), and
-         * internal disk used by the current user's apps. When the device
-         * emulates external storage, this value also includes emulated storage
-         * used by the current user's apps.
-         * <p>
-         * When measuring a physical {@link StorageVolume}, this value includes
-         * usage by all apps on that volume.
-         */
-        public long appsSize;
-
-        /**
-         * Total cache disk usage by apps.
-         */
-        public long cacheSize;
-
-        /**
-         * Total media disk usage, categorized by types such as
-         * {@link Environment#DIRECTORY_MUSIC}.
-         * <p>
-         * When measuring internal storage, this reflects media on emulated
-         * storage for the current user.
-         * <p>
-         * When measuring a physical {@link StorageVolume}, this reflects media
-         * on that volume.
-         */
-        public HashMap<String, Long> mediaSize = new HashMap<>();
-
-        /**
-         * Misc external disk usage for the current user, unaccounted in
-         * {@link #mediaSize}.
-         */
-        public long miscSize;
-
-        /**
-         * Total disk usage for users, which is only meaningful for emulated
-         * internal storage. Key is {@link UserHandle}.
-         */
-        public SparseLongArray usersSize = new SparseLongArray();
-    }
-
-    public interface MeasurementReceiver {
-        public void onDetailsChanged(MeasurementDetails details);
-    }
-
-    private WeakReference<MeasurementReceiver> mReceiver;
-
-    private final Context mContext;
-
-    private final VolumeInfo mVolume;
-    private final VolumeInfo mSharedVolume;
-
-    private final MainHandler mMainHandler;
-    private final MeasurementHandler mMeasurementHandler;
-
-    public StorageMeasurement(Context context, VolumeInfo volume, VolumeInfo sharedVolume) {
-        mContext = context.getApplicationContext();
-
-        mVolume = volume;
-        mSharedVolume = sharedVolume;
-
-        // Start the thread that will measure the disk usage.
-        final HandlerThread handlerThread = new HandlerThread("MemoryMeasurement");
-        handlerThread.start();
-
-        mMainHandler = new MainHandler();
-        mMeasurementHandler = new MeasurementHandler(handlerThread.getLooper());
-    }
-
-    public void setReceiver(MeasurementReceiver receiver) {
-        if (mReceiver == null || mReceiver.get() == null) {
-            mReceiver = new WeakReference<MeasurementReceiver>(receiver);
-        }
-    }
-
-    public void forceMeasure() {
-        invalidate();
-        measure();
-    }
-
-    public void measure() {
-        if (!mMeasurementHandler.hasMessages(MeasurementHandler.MSG_MEASURE)) {
-            mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_MEASURE);
-        }
-    }
-
-    public void onDestroy() {
-        mReceiver = null;
-        mMeasurementHandler.removeMessages(MeasurementHandler.MSG_MEASURE);
-        mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_DISCONNECT);
-    }
-
-    private void invalidate() {
-        mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_INVALIDATE);
-    }
-
-    private static class StatsObserver extends IPackageStatsObserver.Stub {
-        private final boolean mIsPrivate;
-        private final MeasurementDetails mDetails;
-        private final int mCurrentUser;
-        private final Message mFinished;
-
-        private int mRemaining;
-
-        public StatsObserver(boolean isPrivate, MeasurementDetails details, int currentUser,
-                Message finished, int remaining) {
-            mIsPrivate = isPrivate;
-            mDetails = details;
-            mCurrentUser = currentUser;
-            mFinished = finished;
-            mRemaining = remaining;
-        }
-
-        @Override
-        public void onGetStatsCompleted(PackageStats stats, boolean succeeded) {
-            synchronized (mDetails) {
-                if (succeeded) {
-                    addStatsLocked(stats);
-                }
-                if (--mRemaining == 0) {
-                    mFinished.sendToTarget();
-                }
-            }
-        }
-
-        private void addStatsLocked(PackageStats stats) {
-            if (mIsPrivate) {
-                long codeSize = stats.codeSize;
-                long dataSize = stats.dataSize;
-                long cacheSize = stats.cacheSize;
-                if (Environment.isExternalStorageEmulated()) {
-                    // Include emulated storage when measuring internal. OBB is
-                    // shared on emulated storage, so treat as code.
-                    codeSize += stats.externalCodeSize + stats.externalObbSize;
-                    dataSize += stats.externalDataSize + stats.externalMediaSize;
-                    cacheSize += stats.externalCacheSize;
-                }
-
-                // Count code and data for current user
-                if (stats.userHandle == mCurrentUser) {
-                    mDetails.appsSize += codeSize;
-                    mDetails.appsSize += dataSize;
-                }
-
-                // User summary only includes data (code is only counted once
-                // for the current user)
-                addValue(mDetails.usersSize, stats.userHandle, dataSize);
-
-                // Include cache for all users
-                mDetails.cacheSize += cacheSize;
-
-            } else {
-                // Physical storage; only count external sizes
-                mDetails.appsSize += stats.externalCodeSize + stats.externalDataSize
-                        + stats.externalMediaSize + stats.externalObbSize;
-                mDetails.cacheSize += stats.externalCacheSize;
-            }
-        }
-    }
-
-    private class MainHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            final MeasurementDetails details = (MeasurementDetails) msg.obj;
-            final MeasurementReceiver receiver = (mReceiver != null) ? mReceiver.get() : null;
-            if (receiver != null) {
-                receiver.onDetailsChanged(details);
-            }
-        }
-    }
-
-    private class MeasurementHandler extends Handler {
-        public static final int MSG_MEASURE = 1;
-        public static final int MSG_CONNECTED = 2;
-        public static final int MSG_DISCONNECT = 3;
-        public static final int MSG_COMPLETED = 4;
-        public static final int MSG_INVALIDATE = 5;
-
-        private Object mLock = new Object();
-
-        private IMediaContainerService mDefaultContainer;
-
-        private volatile boolean mBound = false;
-
-        private MeasurementDetails mCached;
-
-        private final ServiceConnection mDefContainerConn = new ServiceConnection() {
-            @Override
-            public void onServiceConnected(ComponentName name, IBinder service) {
-                final IMediaContainerService imcs = IMediaContainerService.Stub.asInterface(
-                        service);
-                mDefaultContainer = imcs;
-                mBound = true;
-                sendMessage(obtainMessage(MSG_CONNECTED, imcs));
-            }
-
-            @Override
-            public void onServiceDisconnected(ComponentName name) {
-                mBound = false;
-                removeMessages(MSG_CONNECTED);
-            }
-        };
-
-        public MeasurementHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_MEASURE: {
-                    if (mCached != null) {
-                        mMainHandler.obtainMessage(0, mCached).sendToTarget();
-                        break;
-                    }
-
-                    synchronized (mLock) {
-                        if (mBound) {
-                            removeMessages(MSG_DISCONNECT);
-                            sendMessage(obtainMessage(MSG_CONNECTED, mDefaultContainer));
-                        } else {
-                            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
-                            mContext.bindServiceAsUser(service, mDefContainerConn,
-                                    Context.BIND_AUTO_CREATE, UserHandle.OWNER);
-                        }
-                    }
-                    break;
-                }
-                case MSG_CONNECTED: {
-                    final IMediaContainerService imcs = (IMediaContainerService) msg.obj;
-                    measureExactStorage(imcs);
-                    break;
-                }
-                case MSG_DISCONNECT: {
-                    synchronized (mLock) {
-                        if (mBound) {
-                            mBound = false;
-                            mContext.unbindService(mDefContainerConn);
-                        }
-                    }
-                    break;
-                }
-                case MSG_COMPLETED: {
-                    mCached = (MeasurementDetails) msg.obj;
-                    mMainHandler.obtainMessage(0, mCached).sendToTarget();
-                    break;
-                }
-                case MSG_INVALIDATE: {
-                    mCached = null;
-                    break;
-                }
-            }
-        }
-    }
-
-    private void measureExactStorage(IMediaContainerService imcs) {
-        final UserManager userManager = mContext.getSystemService(UserManager.class);
-        final PackageManager packageManager = mContext.getPackageManager();
-
-        final List<UserInfo> users = userManager.getUsers();
-        final int currentUser = ActivityManager.getCurrentUser();
-
-        final MeasurementDetails details = new MeasurementDetails();
-        final Message finished = mMeasurementHandler.obtainMessage(MeasurementHandler.MSG_COMPLETED,
-                details);
-
-        if (mSharedVolume != null && mSharedVolume.isMountedReadable()) {
-            final File basePath = mSharedVolume.getPathForUser(currentUser);
-
-            // Measure media types for emulated storage, or for primary physical
-            // external volume
-            for (String type : sMeasureMediaTypes) {
-                final File path = new File(basePath, type);
-                final long size = getDirectorySize(imcs, path);
-                details.mediaSize.put(type, size);
-            }
-
-            // Measure misc files not counted under media
-            details.miscSize = measureMisc(imcs, basePath);
-
-            if (mSharedVolume.getType() == VolumeInfo.TYPE_EMULATED) {
-                // Measure total emulated storage of all users; internal apps data
-                // will be spliced in later
-                for (UserInfo user : users) {
-                    final File userPath = mSharedVolume.getPathForUser(user.id);
-                    final long size = getDirectorySize(imcs, userPath);
-                    addValue(details.usersSize, user.id, size);
-                }
-            }
-        }
-
-        // Measure all apps hosted on this volume for all users
-        if (mVolume.getType() == VolumeInfo.TYPE_PRIVATE) {
-            final List<ApplicationInfo> apps = packageManager.getInstalledApplications(
-                    PackageManager.GET_UNINSTALLED_PACKAGES
-                    | PackageManager.GET_DISABLED_COMPONENTS);
-
-            final List<ApplicationInfo> volumeApps = new ArrayList<>();
-            for (ApplicationInfo app : apps) {
-                if (Objects.equals(app.volumeUuid, mVolume.getFsUuid())) {
-                    volumeApps.add(app);
-                }
-            }
-
-            final int count = users.size() * volumeApps.size();
-            if (count == 0) {
-                finished.sendToTarget();
-                return;
-            }
-
-            final StatsObserver observer = new StatsObserver(
-                    true, details, currentUser, finished, count);
-            for (UserInfo user : users) {
-                for (ApplicationInfo app : volumeApps) {
-                    packageManager.getPackageSizeInfo(app.packageName, user.id, observer);
-                }
-            }
-
-        } else {
-            finished.sendToTarget();
-            return;
-        }
-    }
-
-    private static long getDirectorySize(IMediaContainerService imcs, File path) {
-        try {
-            final long size = imcs.calculateDirectorySize(path.toString());
-            Log.d(TAG, "getDirectorySize(" + path + ") returned " + size);
-            return size;
-        } catch (Exception e) {
-            Log.w(TAG, "Could not read memory from default container service for " + path, e);
-            return 0;
-        }
-    }
-
-    private long measureMisc(IMediaContainerService imcs, File dir) {
-        final File[] files = dir.listFiles();
-        if (ArrayUtils.isEmpty(files)) return 0;
-
-        // Get sizes of all top level nodes except the ones already computed
-        long miscSize = 0;
-        for (File file : files) {
-            final String name = file.getName();
-            if (sMeasureMediaTypes.contains(name)) {
-                continue;
-            }
-
-            if (file.isFile()) {
-                miscSize += file.length();
-            } else if (file.isDirectory()) {
-                miscSize += getDirectorySize(imcs, file);
-            }
-        }
-        return miscSize;
-    }
-
-    private static void addValue(SparseLongArray array, int key, long value) {
-        array.put(key, array.get(key) + value);
-    }
-}