1547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler/* 2547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * Copyright (C) 2011 The Android Open Source Project 3547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * 4547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * Licensed under the Apache License, Version 2.0 (the "License"); 5547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * you may not use this file except in compliance with the License. 6547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * You may obtain a copy of the License at 7547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * 8547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * http://www.apache.org/licenses/LICENSE-2.0 9547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * 10547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * Unless required by applicable law or agreed to in writing, software 11547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * distributed under the License is distributed on an "AS IS" BASIS, 12547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * See the License for the specific language governing permissions and 14547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * limitations under the License. 15547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler */ 16547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 17547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerpackage com.android.settingslib.deviceinfo; 18547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 19547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.app.ActivityManager; 20547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.content.ComponentName; 21547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.content.Context; 22547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.content.Intent; 23547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.content.ServiceConnection; 24547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.content.pm.ApplicationInfo; 25547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.content.pm.IPackageStatsObserver; 26547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.content.pm.PackageManager; 27547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.content.pm.PackageStats; 28547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.content.pm.UserInfo; 29547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.Environment; 30547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.Handler; 31547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.HandlerThread; 32547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.IBinder; 33547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.Looper; 34547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.Message; 35547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.UserHandle; 36547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.UserManager; 37547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.storage.StorageVolume; 38547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.os.storage.VolumeInfo; 39547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.util.Log; 4047adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Banimport android.util.SparseArray; 41547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport android.util.SparseLongArray; 42547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 43547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport com.android.internal.app.IMediaContainerService; 44547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport com.android.internal.util.ArrayUtils; 45547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport com.google.android.collect.Sets; 46547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 47547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport java.io.File; 48547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport java.lang.ref.WeakReference; 49547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport java.util.ArrayList; 50547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport java.util.HashMap; 51547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport java.util.List; 52547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport java.util.Objects; 53547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerimport java.util.Set; 54547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 55547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler/** 56547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * Utility for measuring the disk usage of internal storage or a physical 57547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * {@link StorageVolume}. Connects with a remote {@link IMediaContainerService} 58547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * and delivers results to {@link MeasurementReceiver}. 59547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler */ 60547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantlerpublic class StorageMeasurement { 61547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private static final String TAG = "StorageMeasurement"; 62547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 63547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private static final boolean LOCAL_LOGV = true; 64547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler static final boolean LOGV = LOCAL_LOGV && Log.isLoggable(TAG, Log.VERBOSE); 65547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 66547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 67547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 68547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 69547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler DEFAULT_CONTAINER_PACKAGE, "com.android.defcontainer.DefaultContainerService"); 70547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 71547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler /** Media types to measure on external storage. */ 72547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private static final Set<String> sMeasureMediaTypes = Sets.newHashSet( 73547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler Environment.DIRECTORY_DCIM, Environment.DIRECTORY_MOVIES, 74547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler Environment.DIRECTORY_PICTURES, Environment.DIRECTORY_MUSIC, 75547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS, 76547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS, 77547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler Environment.DIRECTORY_DOWNLOADS, Environment.DIRECTORY_ANDROID); 78547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 79547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public static class MeasurementDetails { 809496a2da0500934353abb6042fab6661eb49555aTony Mantler public long totalSize; 819496a2da0500934353abb6042fab6661eb49555aTony Mantler public long availSize; 829496a2da0500934353abb6042fab6661eb49555aTony Mantler 83547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler /** 8447adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * Total apps disk usage per profiles of the current user. 85547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * <p> 86547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * When measuring internal storage, this value includes the code size of 8747adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * all apps (regardless of install status for the given profile), and 8847adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * internal disk used by the profile's apps. When the device 89547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * emulates external storage, this value also includes emulated storage 9047adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * used by the profile's apps. 91547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * <p> 92547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * When measuring a physical {@link StorageVolume}, this value includes 9347adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * usage by all apps on that volume and only for the primary profile. 9447adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * <p> 9547adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * Key is {@link UserHandle}. 96547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler */ 9747adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban public SparseLongArray appsSize = new SparseLongArray(); 98547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 99547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler /** 10047adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * Total cache disk usage by apps (over all users and profiles). 101547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler */ 102547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public long cacheSize; 103547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 104547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler /** 105547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * Total media disk usage, categorized by types such as 10647adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * {@link Environment#DIRECTORY_MUSIC} for every user profile of the current user. 107547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * <p> 108547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * When measuring internal storage, this reflects media on emulated 10947adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * storage for the respective profile. 110547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * <p> 111547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * When measuring a physical {@link StorageVolume}, this reflects media 112547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * on that volume. 11347adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * <p> 11447adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * Key of the {@link SparseArray} is {@link UserHandle}. 115547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler */ 11647adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban public SparseArray<HashMap<String, Long>> mediaSize = new SparseArray<>(); 117547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 118547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler /** 11947adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * Misc external disk usage for the current user's profiles, unaccounted in 12047adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban * {@link #mediaSize}. Key is {@link UserHandle}. 121547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler */ 12247adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban public SparseLongArray miscSize = new SparseLongArray(); 123547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 124547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler /** 125547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * Total disk usage for users, which is only meaningful for emulated 126547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler * internal storage. Key is {@link UserHandle}. 127547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler */ 128547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public SparseLongArray usersSize = new SparseLongArray(); 129547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 130547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 131547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public interface MeasurementReceiver { 1329496a2da0500934353abb6042fab6661eb49555aTony Mantler void onDetailsChanged(MeasurementDetails details); 133547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 134547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 135547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private WeakReference<MeasurementReceiver> mReceiver; 136547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 137547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final Context mContext; 138547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 139547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final VolumeInfo mVolume; 140547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final VolumeInfo mSharedVolume; 141547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 142547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final MainHandler mMainHandler; 143547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final MeasurementHandler mMeasurementHandler; 144547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 145547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public StorageMeasurement(Context context, VolumeInfo volume, VolumeInfo sharedVolume) { 146547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mContext = context.getApplicationContext(); 147547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 148547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mVolume = volume; 149547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mSharedVolume = sharedVolume; 150547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 151547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // Start the thread that will measure the disk usage. 152547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final HandlerThread handlerThread = new HandlerThread("MemoryMeasurement"); 153547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler handlerThread.start(); 154547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 155547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mMainHandler = new MainHandler(); 156547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mMeasurementHandler = new MeasurementHandler(handlerThread.getLooper()); 157547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 158547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 159547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public void setReceiver(MeasurementReceiver receiver) { 160547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (mReceiver == null || mReceiver.get() == null) { 161547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mReceiver = new WeakReference<MeasurementReceiver>(receiver); 162547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 163547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 164547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 165547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public void forceMeasure() { 166547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler invalidate(); 167547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler measure(); 168547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 169547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 170547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public void measure() { 171547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (!mMeasurementHandler.hasMessages(MeasurementHandler.MSG_MEASURE)) { 172547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_MEASURE); 173547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 174547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 175547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 176547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public void onDestroy() { 177547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mReceiver = null; 178547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mMeasurementHandler.removeMessages(MeasurementHandler.MSG_MEASURE); 179547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_DISCONNECT); 180547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 181547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 182547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private void invalidate() { 183547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_INVALIDATE); 184547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 185547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 186547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private static class StatsObserver extends IPackageStatsObserver.Stub { 187547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final boolean mIsPrivate; 188547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final MeasurementDetails mDetails; 189547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final int mCurrentUser; 190547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final Message mFinished; 191547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 192547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private int mRemaining; 193547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 194547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public StatsObserver(boolean isPrivate, MeasurementDetails details, int currentUser, 19547adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban List<UserInfo> profiles, Message finished, int remaining) { 196547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mIsPrivate = isPrivate; 197547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mDetails = details; 198547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mCurrentUser = currentUser; 19947adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban if (isPrivate) { 20047adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban // Add the profile ids as keys to detail's app sizes. 20147adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban for (UserInfo userInfo : profiles) { 20247adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban mDetails.appsSize.put(userInfo.id, 0); 20347adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban } 20447adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban } 205547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mFinished = finished; 206547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mRemaining = remaining; 207547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 208547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 209547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler @Override 210547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public void onGetStatsCompleted(PackageStats stats, boolean succeeded) { 211547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler synchronized (mDetails) { 212547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (succeeded) { 213547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler addStatsLocked(stats); 214547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 215547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (--mRemaining == 0) { 216547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mFinished.sendToTarget(); 217547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 218547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 219547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 220547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 221547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private void addStatsLocked(PackageStats stats) { 222547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (mIsPrivate) { 223547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler long codeSize = stats.codeSize; 224547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler long dataSize = stats.dataSize; 225547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler long cacheSize = stats.cacheSize; 226547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (Environment.isExternalStorageEmulated()) { 227547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // Include emulated storage when measuring internal. OBB is 228547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // shared on emulated storage, so treat as code. 229547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler codeSize += stats.externalCodeSize + stats.externalObbSize; 230547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler dataSize += stats.externalDataSize + stats.externalMediaSize; 231547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler cacheSize += stats.externalCacheSize; 232547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 233547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 23447adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban // Count code and data for current user's profiles (keys prepared in constructor) 23547adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban addValueIfKeyExists(mDetails.appsSize, stats.userHandle, codeSize + dataSize); 236547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 237547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // User summary only includes data (code is only counted once 238547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // for the current user) 239547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler addValue(mDetails.usersSize, stats.userHandle, dataSize); 240547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 241547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // Include cache for all users 242547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mDetails.cacheSize += cacheSize; 243547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 244547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } else { 245547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // Physical storage; only count external sizes 24647adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban addValue(mDetails.appsSize, mCurrentUser, 24747adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban stats.externalCodeSize + stats.externalDataSize 24847adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban + stats.externalMediaSize + stats.externalObbSize); 249547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mDetails.cacheSize += stats.externalCacheSize; 250547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 251547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 252547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 253547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 254547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private class MainHandler extends Handler { 255547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler @Override 256547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public void handleMessage(Message msg) { 257547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final MeasurementDetails details = (MeasurementDetails) msg.obj; 258547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final MeasurementReceiver receiver = (mReceiver != null) ? mReceiver.get() : null; 259547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (receiver != null) { 260547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler receiver.onDetailsChanged(details); 261547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 262547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 263547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 264547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 265547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private class MeasurementHandler extends Handler { 266547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public static final int MSG_MEASURE = 1; 267547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public static final int MSG_CONNECTED = 2; 268547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public static final int MSG_DISCONNECT = 3; 269547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public static final int MSG_COMPLETED = 4; 270547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public static final int MSG_INVALIDATE = 5; 271547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 272547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private Object mLock = new Object(); 273547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 274547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private IMediaContainerService mDefaultContainer; 275547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 276547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private volatile boolean mBound = false; 277547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 278547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private MeasurementDetails mCached; 279547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 280547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private final ServiceConnection mDefContainerConn = new ServiceConnection() { 281547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler @Override 282547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public void onServiceConnected(ComponentName name, IBinder service) { 283547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final IMediaContainerService imcs = IMediaContainerService.Stub.asInterface( 284547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler service); 285547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mDefaultContainer = imcs; 286547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mBound = true; 287547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler sendMessage(obtainMessage(MSG_CONNECTED, imcs)); 288547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 289547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 290547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler @Override 291547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public void onServiceDisconnected(ComponentName name) { 292547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mBound = false; 293547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler removeMessages(MSG_CONNECTED); 294547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 295547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler }; 296547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 297547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public MeasurementHandler(Looper looper) { 298547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler super(looper); 299547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 300547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 301547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler @Override 302547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler public void handleMessage(Message msg) { 303547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler switch (msg.what) { 304547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler case MSG_MEASURE: { 305547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (mCached != null) { 306547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mMainHandler.obtainMessage(0, mCached).sendToTarget(); 307547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler break; 308547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 309547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 310547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler synchronized (mLock) { 311547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (mBound) { 312547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler removeMessages(MSG_DISCONNECT); 313547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler sendMessage(obtainMessage(MSG_CONNECTED, mDefaultContainer)); 314547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } else { 315547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 316547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mContext.bindServiceAsUser(service, mDefContainerConn, 317547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler Context.BIND_AUTO_CREATE, UserHandle.OWNER); 318547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 319547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 320547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler break; 321547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 322547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler case MSG_CONNECTED: { 323547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final IMediaContainerService imcs = (IMediaContainerService) msg.obj; 324547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler measureExactStorage(imcs); 325547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler break; 326547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 327547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler case MSG_DISCONNECT: { 328547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler synchronized (mLock) { 329547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (mBound) { 330547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mBound = false; 331547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mContext.unbindService(mDefContainerConn); 332547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 333547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 334547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler break; 335547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 336547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler case MSG_COMPLETED: { 337547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mCached = (MeasurementDetails) msg.obj; 338547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mMainHandler.obtainMessage(0, mCached).sendToTarget(); 339547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler break; 340547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 341547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler case MSG_INVALIDATE: { 342547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler mCached = null; 343547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler break; 344547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 345547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 346547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 347547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 348547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 349547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private void measureExactStorage(IMediaContainerService imcs) { 350547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final UserManager userManager = mContext.getSystemService(UserManager.class); 351547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final PackageManager packageManager = mContext.getPackageManager(); 352547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 353547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final List<UserInfo> users = userManager.getUsers(); 35447adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban final List<UserInfo> currentProfiles = userManager.getEnabledProfiles( 35547adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban ActivityManager.getCurrentUser()); 356547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 357547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final MeasurementDetails details = new MeasurementDetails(); 358547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final Message finished = mMeasurementHandler.obtainMessage(MeasurementHandler.MSG_COMPLETED, 359547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler details); 360547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 361ca2954830c017c49523d5e2c7cb5916c76a52375Tony Mantler if (mVolume == null || !mVolume.isMountedReadable()) { 362ca2954830c017c49523d5e2c7cb5916c76a52375Tony Mantler finished.sendToTarget(); 363ca2954830c017c49523d5e2c7cb5916c76a52375Tony Mantler return; 364ca2954830c017c49523d5e2c7cb5916c76a52375Tony Mantler } 365ca2954830c017c49523d5e2c7cb5916c76a52375Tony Mantler 366547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (mSharedVolume != null && mSharedVolume.isMountedReadable()) { 36747adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban for (UserInfo currentUserInfo : currentProfiles) { 36847adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban final int userId = currentUserInfo.id; 36947adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban final File basePath = mSharedVolume.getPathForUser(userId); 37047adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban HashMap<String, Long> mediaMap = new HashMap<>(sMeasureMediaTypes.size()); 37147adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban details.mediaSize.put(userId, mediaMap); 37247adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban 37347adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban // Measure media types for emulated storage, or for primary physical 37447adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban // external volume 37547adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban for (String type : sMeasureMediaTypes) { 37647adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban final File path = new File(basePath, type); 37747adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban final long size = getDirectorySize(imcs, path); 37847adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban mediaMap.put(type, size); 37947adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban } 380547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 38147adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban // Measure misc files not counted under media 38247adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban addValue(details.miscSize, userId, measureMisc(imcs, basePath)); 38347adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban } 384547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 385547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (mSharedVolume.getType() == VolumeInfo.TYPE_EMULATED) { 386547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // Measure total emulated storage of all users; internal apps data 387547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // will be spliced in later 388547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler for (UserInfo user : users) { 389547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final File userPath = mSharedVolume.getPathForUser(user.id); 390547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final long size = getDirectorySize(imcs, userPath); 391547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler addValue(details.usersSize, user.id, size); 392547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 393547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 394547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 395547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 3969496a2da0500934353abb6042fab6661eb49555aTony Mantler final File file = mVolume.getPath(); 397ca2954830c017c49523d5e2c7cb5916c76a52375Tony Mantler if (file != null) { 398ca2954830c017c49523d5e2c7cb5916c76a52375Tony Mantler details.totalSize = file.getTotalSpace(); 399ca2954830c017c49523d5e2c7cb5916c76a52375Tony Mantler details.availSize = file.getFreeSpace(); 400ca2954830c017c49523d5e2c7cb5916c76a52375Tony Mantler } 4019496a2da0500934353abb6042fab6661eb49555aTony Mantler 402547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // Measure all apps hosted on this volume for all users 403547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (mVolume.getType() == VolumeInfo.TYPE_PRIVATE) { 404547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final List<ApplicationInfo> apps = packageManager.getInstalledApplications( 405547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler PackageManager.GET_UNINSTALLED_PACKAGES 406547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler | PackageManager.GET_DISABLED_COMPONENTS); 407547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 408547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final List<ApplicationInfo> volumeApps = new ArrayList<>(); 409547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler for (ApplicationInfo app : apps) { 410547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (Objects.equals(app.volumeUuid, mVolume.getFsUuid())) { 411547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler volumeApps.add(app); 412547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 413547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 414547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 415547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final int count = users.size() * volumeApps.size(); 416547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (count == 0) { 417547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler finished.sendToTarget(); 418547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler return; 419547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 420547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 42147adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban final StatsObserver observer = new StatsObserver(true, details, 42247adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban ActivityManager.getCurrentUser(), currentProfiles, finished, count); 423547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler for (UserInfo user : users) { 424547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler for (ApplicationInfo app : volumeApps) { 425547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler packageManager.getPackageSizeInfo(app.packageName, user.id, observer); 426547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 427547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 428547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 429547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } else { 430547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler finished.sendToTarget(); 431547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler return; 432547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 433547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 434547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 435547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private static long getDirectorySize(IMediaContainerService imcs, File path) { 436547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler try { 437547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final long size = imcs.calculateDirectorySize(path.toString()); 438547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler Log.d(TAG, "getDirectorySize(" + path + ") returned " + size); 439547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler return size; 440547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } catch (Exception e) { 441547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler Log.w(TAG, "Could not read memory from default container service for " + path, e); 442547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler return 0; 443547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 444547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 445547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 446547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private long measureMisc(IMediaContainerService imcs, File dir) { 447547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final File[] files = dir.listFiles(); 448547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (ArrayUtils.isEmpty(files)) return 0; 449547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 450547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler // Get sizes of all top level nodes except the ones already computed 451547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler long miscSize = 0; 452547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler for (File file : files) { 453547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler final String name = file.getName(); 454547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (sMeasureMediaTypes.contains(name)) { 455547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler continue; 456547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 457547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 458547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler if (file.isFile()) { 459547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler miscSize += file.length(); 460547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } else if (file.isDirectory()) { 461547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler miscSize += getDirectorySize(imcs, file); 462547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 463547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 464547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler return miscSize; 465547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 466547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler 467547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler private static void addValue(SparseLongArray array, int key, long value) { 468547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler array.put(key, array.get(key) + value); 469547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler } 47047adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban 47147adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban private static void addValueIfKeyExists(SparseLongArray array, int key, long value) { 47247adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban final int index = array.indexOfKey(key); 47347adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban if (index >= 0) { 47447adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban array.put(key, array.valueAt(index) + value); 47547adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban } 47647adcb9feadfe8230b6c95b096d7a8653c358507Zoltan Szatmary-Ban } 477547e4caebe0aac21d0856de96e121b8bf63fd9bdTony Mantler} 478