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

Commit d2be882d authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #3114356: Storage visualization in Manage Apps is confusing

Also fixes issue #3097388: If you launch Manage Applications when SD
card app info isn't available, incomplete information gets cached

Change-Id: If3377a965653590e5bc1df25e38764a83e96b820
parent 916adce0
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -43,9 +43,11 @@
                android:layout_height="wrap_content"
                android:layout_marginTop="-5dp"
                android:orientation="horizontal"
                android:clipChildren="false"
                android:clipToPadding="false"
                android:paddingTop="30dp"
                android:paddingLeft="2dp"
                android:paddingRight="2dp"
                android:paddingLeft="4dp"
                android:paddingRight="4dp"
                android:paddingBottom="1dp">
            <TextView android:id="@+id/usedStorageText"
                android:layout_width="0px"
@@ -58,8 +60,11 @@
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="0"
                android:layout_marginTop="-23dp"
                android:textAppearance="?android:attr/textAppearanceSmallInverse"
                android:textColor="#000"
                android:textColor="#ccc"
                android:shadowColor="#000"
                android:shadowRadius="5"
                android:textStyle="bold"
                android:singleLine="true"
                android:text="@string/internal_storage" />
+8 −3
Original line number Diff line number Diff line
@@ -41,9 +41,11 @@
            android:layout_height="wrap_content"
            android:layout_marginTop="-5dp"
            android:orientation="horizontal"
            android:clipChildren="false"
            android:clipToPadding="false"
            android:paddingTop="30dp"
            android:paddingLeft="2dp"
            android:paddingRight="2dp"
            android:paddingLeft="4dp"
            android:paddingRight="4dp"
            android:paddingBottom="1dp">
        <TextView android:id="@+id/foregroundText"
            android:layout_width="0px"
@@ -58,8 +60,11 @@
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:layout_marginTop="-23dp"
            android:textAppearance="?android:attr/textAppearanceSmallInverse"
            android:textColor="#000"
            android:textColor="#ccc"
            android:shadowColor="#000"
            android:shadowRadius="5"
            android:textStyle="bold"
            android:singleLine="true"
            android:text="@string/memory" />
+77 −19
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.os.SystemClock;
import android.text.format.Formatter;
import android.util.Log;

import java.io.File;
import java.text.Collator;
import java.text.Normalizer;
import java.text.Normalizer.Form;
@@ -66,14 +67,17 @@ public class ApplicationsState {
    }

    public static class AppEntry {
        final String label;
        final File apkFile;
        final long id;
        String label;
        long size;
        
        long cacheSize;
        long codeSize;
        long dataSize;

        boolean mounted;
        
        String getNormalizedLabel() {
            if (normalizedLabel != null) {
                return normalizedLabel;
@@ -92,12 +96,47 @@ public class ApplicationsState {
        String normalizedLabel;

        AppEntry(Context context, ApplicationInfo info, long id) {
            CharSequence label = info.loadLabel(context.getPackageManager());
            this.label = label != null ? label.toString() : info.packageName;
            apkFile = new File(info.sourceDir);
            this.id = id;
            this.info = info;
            this.size = SIZE_UNKNOWN;
            this.sizeStale = true;
            ensureLabel(context);
        }
        
        void ensureLabel(Context context) {
            if (this.label == null || !this.mounted) {
                if (!this.apkFile.exists()) {
                    this.mounted = false;
                    this.label = info.packageName;
                } else {
                    this.mounted = true;
                    CharSequence label = info.loadLabel(context.getPackageManager());
                    this.label = label != null ? label.toString() : info.packageName;
                }
            }
        }
        
        boolean ensureIconLocked(Context context, PackageManager pm) {
            if (this.icon == null) {
                if (this.apkFile.exists()) {
                    this.icon = this.info.loadIcon(pm);
                    return true;
                } else {
                    this.mounted = false;
                    this.icon = context.getResources().getDrawable(
                            com.android.internal.R.drawable.sym_app_on_sd_unavailable_icon);
                }
            } else if (!this.mounted) {
                // If the app wasn't mounted but is now mounted, reload
                // its icon.
                if (this.apkFile.exists()) {
                    this.mounted = true;
                    this.icon = this.info.loadIcon(pm);
                    return true;
                }
            }
            return false;
        }
    }

@@ -217,9 +256,11 @@ public class ApplicationsState {
                     return;
                 }
                 boolean avail = Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr);
                 if (avail) {
                     for (String pkgName : pkgList) {
                     if (avail) addPackage(pkgName);
                     else removePackage(pkgName);
                         removePackage(pkgName);
                         addPackage(pkgName);
                     }
                 }
             }
         }
@@ -312,6 +353,13 @@ public class ApplicationsState {
            for (int i=0; i<mAppEntries.size(); i++) {
                mAppEntries.get(i).sizeStale = true;
            }
            for (int i=0; i<mApplications.size(); i++) {
                final ApplicationInfo info = mApplications.get(i);
                final AppEntry entry = mEntriesMap.get(info.packageName);
                if (entry != null) {
                    entry.info = info;
                }
            }
            mCurComputingSizePkg = null;
            if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
                mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
@@ -391,6 +439,7 @@ public class ApplicationsState {
            if (filter == null || filter.filterApp(info)) {
                synchronized (mEntriesMap) {
                    AppEntry entry = getEntryLocked(info);
                    entry.ensureLabel(mContext);
                    if (DEBUG) Log.i(TAG, "Using " + info.packageName + ": " + entry);
                    filteredApps.add(entry);
                }
@@ -438,9 +487,7 @@ public class ApplicationsState {
            return;
        }
        synchronized (entry) {
            if (entry.icon == null) {
                entry.icon = entry.info.loadIcon(mPm);
            }
            entry.ensureIconLocked(mContext, mPm);
        }
    }
    
@@ -453,6 +500,16 @@ public class ApplicationsState {
        }
    }

    long sumCacheSizes() {
        long sum = 0;
        synchronized (mEntriesMap) {
            for (int i=mAppEntries.size()-1; i>=0; i--) {
                sum += mAppEntries.get(i).cacheSize;
            }
        }
        return sum;
    }
    
    int indexOfApplicationInfoLocked(String pkgName) {
        for (int i=mApplications.size()-1; i>=0; i--) {
            if (mApplications.get(i).packageName.equals(pkgName)) {
@@ -630,7 +687,9 @@ public class ApplicationsState {
                    synchronized (mEntriesMap) {
                        for (int i=0; i<mAppEntries.size() && numDone<2; i++) {
                            AppEntry entry = mAppEntries.get(i);
                            if (entry.icon == null) {
                            if (entry.icon == null || !entry.mounted) {
                                synchronized (entry) {
                                    if (entry.ensureIconLocked(mContext, mPm)) {
                                        if (!mRunning) {
                                            mRunning = true;
                                            Message m = mMainHandler.obtainMessage(
@@ -638,8 +697,7 @@ public class ApplicationsState {
                                            mMainHandler.sendMessage(m);
                                        }
                                        numDone++;
                                synchronized (entry) {
                                    entry.icon = entry.info.loadIcon(mPm);
                                    }
                                }
                            }
                        }
+22 −10
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ import android.widget.LinearLayout;

public class LinearColorBar extends LinearLayout {
    static final int LEFT_COLOR = 0xffa0a0a0;
    static final int MIDDLE_COLOR = 0xff7070ff;
    static final int MIDDLE_COLOR = 0xffa0a0a0;
    static final int RIGHT_COLOR = 0xffa0c0a0;

    private float mRedRatio;
@@ -47,6 +47,7 @@ public class LinearColorBar extends LinearLayout {
                ? 2 : 1;
        mEdgeGradientPaint.setStrokeWidth(mLineWidth);
        mEdgeGradientPaint.setAntiAlias(true);
        
    }

    public void setRatios(float red, float yellow, float green) {
@@ -111,22 +112,33 @@ public class LinearColorBar extends LinearLayout {
            mColorPath.reset();
            mEdgePath.reset();
            if (indicatorLeft < indicatorRight) {
                final int midTopY = mRect.top;
                final int midBottomY = 0;
                final int xoff = 2;
                mColorPath.moveTo(indicatorLeft, mRect.top);
                mColorPath.lineTo(-1, 0);
                mColorPath.lineTo(width, 0);
                mColorPath.lineTo(indicatorRight, mRect.top);
                mColorPath.cubicTo(indicatorLeft, midBottomY,
                        -xoff, midTopY,
                        -xoff, 0);
                mColorPath.lineTo(width+xoff-1, 0);
                mColorPath.cubicTo(width+xoff-1, midTopY,
                        indicatorRight, midBottomY,
                        indicatorRight, mRect.top);
                mColorPath.close();
                float lineOffset = mLineWidth+.5f;
                mEdgePath.moveTo(indicatorLeft+lineOffset, mRect.top);
                mEdgePath.lineTo(-1+lineOffset, 0);
                mEdgePath.moveTo(indicatorRight-lineOffset, mRect.top);
                mEdgePath.lineTo(width-lineOffset, 0);
                final float lineOffset = mLineWidth+.5f;
                mEdgePath.moveTo(-xoff+lineOffset, 0);
                mEdgePath.cubicTo(-xoff+lineOffset, midTopY,
                        indicatorLeft+lineOffset, midBottomY,
                        indicatorLeft+lineOffset, mRect.top);
                mEdgePath.moveTo(width+xoff-1-lineOffset, 0);
                mEdgePath.cubicTo(width+xoff-1-lineOffset, midTopY,
                        indicatorRight-lineOffset, midBottomY,
                        indicatorRight-lineOffset, mRect.top);
            }
            mLastInterestingLeft = indicatorLeft;
            mLastInterestingRight = indicatorRight;
        }

        if (!mColorPath.isEmpty()) {
        if (!mEdgePath.isEmpty()) {
            canvas.drawPath(mEdgePath, mEdgeGradientPaint);
            canvas.drawPath(mColorPath, mColorGradientPaint);
        }
+18 −3
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.os.StatFs;
import android.provider.Settings;
import android.text.format.Formatter;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -43,6 +44,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
@@ -57,7 +59,6 @@ import android.widget.AdapterView.OnItemClickListener;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

final class CanBeOnSdCardChecker {
    final IPackageManager mPm;
@@ -677,6 +678,18 @@ public class ManageApplications extends TabActivity implements
        return true;
    }
    
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_SEARCH && event.isTracking()) {
            if (mCurView != VIEW_RUNNING) {
                ((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE))
                        .showSoftInputUnchecked(0, null);
            }
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        ApplicationsState.AppEntry entry = mApplicationsAdapter.getAppEntry(position);
@@ -738,8 +751,8 @@ public class ManageApplications extends TabActivity implements
            for (int i=0; i<N; i++) {
                ApplicationsState.AppEntry ae = mApplicationsAdapter.getAppEntry(i);
                appStorage += ae.codeSize + ae.dataSize;
                freeStorage += ae.cacheSize;
            }
            freeStorage += mApplicationsState.sumCacheSizes();
        }
        if (newLabel != null) {
            mStorageChartLabel.setText(newLabel);
@@ -831,6 +844,8 @@ public class ManageApplications extends TabActivity implements
        } else if (TAB_SDCARD.equalsIgnoreCase(tabId)) {
            newOption = FILTER_APPS_SDCARD;
        } else if (TAB_RUNNING.equalsIgnoreCase(tabId)) {
            ((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE))
                    .hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
            selectView(VIEW_RUNNING);
            return;
        } else {
Loading