1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.app;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
192b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.app.Activity;
202b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.content.res.Configuration;
212b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.os.Bundle;
222b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.os.Handler;
232b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.os.Message;
242b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.text.format.Formatter;
252b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.view.LayoutInflater;
262b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.view.View;
272b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.view.View.OnClickListener;
282b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.widget.FrameLayout;
292b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.widget.ProgressBar;
302b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.widget.TextView;
312b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport android.widget.Toast;
322b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin
33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.R;
348e565703e8d482421714383a8ad40a67929ce2daOwen Linimport com.android.gallery3d.common.Utils;
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaObject;
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaSet;
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.Path;
38a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.GLCanvas;
398e565703e8d482421714383a8ad40a67929ce2daOwen Linimport com.android.gallery3d.ui.CacheStorageUsageInfo;
4048ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Linimport com.android.gallery3d.ui.GLRoot;
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.GLView;
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.ManageCacheDrawer;
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.MenuExecutor;
44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.SelectionManager;
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.SlotView;
468e565703e8d482421714383a8ad40a67929ce2daOwen Linimport com.android.gallery3d.ui.SynchronizedHandler;
478e565703e8d482421714383a8ad40a67929ce2daOwen Linimport com.android.gallery3d.util.Future;
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.GalleryUtils;
498e565703e8d482421714383a8ad40a67929ce2daOwen Linimport com.android.gallery3d.util.ThreadPool.Job;
508e565703e8d482421714383a8ad40a67929ce2daOwen Linimport com.android.gallery3d.util.ThreadPool.JobContext;
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.ArrayList;
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class ManageCachePage extends ActivityState implements
558e565703e8d482421714383a8ad40a67929ce2daOwen Lin        SelectionManager.SelectionListener, MenuExecutor.ProgressListener,
568e565703e8d482421714383a8ad40a67929ce2daOwen Lin        EyePosition.EyePositionListener, OnClickListener {
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final String KEY_MEDIA_PATH = "media-path";
588e565703e8d482421714383a8ad40a67929ce2daOwen Lin
597817979db0c52ffeacb951625b1e821eba303285Ahbong Chang    @SuppressWarnings("unused")
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "ManageCachePage";
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int DATA_CACHE_SIZE = 256;
638e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private static final int MSG_REFRESH_STORAGE_INFO = 1;
648e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private static final int MSG_REQUEST_LAYOUT = 2;
658e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private static final int PROGRESS_BAR_MAX = 10000;
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
677260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin    private SlotView mSlotView;
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private MediaSet mMediaSet;
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected SelectionManager mSelectionManager;
7131cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    protected ManageCacheDrawer mSelectionDrawer;
72c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin    private AlbumSetDataLoader mAlbumSetDataAdapter;
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private EyePosition mEyePosition;
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // The eyes' position of the user, the origin is at the center of the
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // device and the unit is in pixels.
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private float mX;
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private float mY;
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private float mZ;
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private int mAlbumCountToMakeAvailableOffline;
838e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private View mFooterContent;
848e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private CacheStorageUsageInfo mCacheStorageInfo;
858e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private Future<Void> mUpdateStorageInfo;
868e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private Handler mHandler;
878e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private boolean mLayoutReady = false;
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
89915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu    @Override
90915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu    protected int getBackgroundColorId() {
91915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu        return R.color.cache_background;
92915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu    }
93915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private GLView mRootPane = new GLView() {
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        private float mMatrix[] = new float[16];
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
98ff951a85c3c9015ef7ccd8902e69ce88360a0cb8Chih-Chung Chang        protected void renderBackground(GLCanvas view) {
99915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu            view.clearBuffer(getBackgroundColor());
100ff951a85c3c9015ef7ccd8902e69ce88360a0cb8Chih-Chung Chang        }
101ff951a85c3c9015ef7ccd8902e69ce88360a0cb8Chih-Chung Chang
102ff951a85c3c9015ef7ccd8902e69ce88360a0cb8Chih-Chung Chang        @Override
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        protected void onLayout(
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                boolean changed, int left, int top, int right, int bottom) {
1058e565703e8d482421714383a8ad40a67929ce2daOwen Lin            // Hack: our layout depends on other components on the screen.
1068e565703e8d482421714383a8ad40a67929ce2daOwen Lin            // We assume the other components will complete before we get a change
1078e565703e8d482421714383a8ad40a67929ce2daOwen Lin            // to run a message in main thread.
1088e565703e8d482421714383a8ad40a67929ce2daOwen Lin            if (!mLayoutReady) {
1098e565703e8d482421714383a8ad40a67929ce2daOwen Lin                mHandler.sendEmptyMessage(MSG_REQUEST_LAYOUT);
1108e565703e8d482421714383a8ad40a67929ce2daOwen Lin                return;
1118e565703e8d482421714383a8ad40a67929ce2daOwen Lin            }
1128e565703e8d482421714383a8ad40a67929ce2daOwen Lin            mLayoutReady = false;
1138e565703e8d482421714383a8ad40a67929ce2daOwen Lin
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mEyePosition.resetPosition();
1158cab3e872dd95e55ba34fdb94269a0c5069e72aeRay Chen            int slotViewTop = mActivity.getGalleryActionBar().getHeight();
1168e565703e8d482421714383a8ad40a67929ce2daOwen Lin            int slotViewBottom = bottom - top;
1178e565703e8d482421714383a8ad40a67929ce2daOwen Lin
11828cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin            View footer = mActivity.findViewById(R.id.footer);
119bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            if (footer != null) {
1208e565703e8d482421714383a8ad40a67929ce2daOwen Lin                int location[] = {0, 0};
121bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang                footer.getLocationOnScreen(location);
1228e565703e8d482421714383a8ad40a67929ce2daOwen Lin                slotViewBottom = location[1];
1238e565703e8d482421714383a8ad40a67929ce2daOwen Lin            }
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
1257260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin            mSlotView.layout(0, slotViewTop, right - left, slotViewBottom);
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        protected void render(GLCanvas canvas) {
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            GalleryUtils.setViewPointMatrix(mMatrix,
132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        getWidth() / 2 + mX, getHeight() / 2 + mY, mZ);
133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            canvas.multiplyMatrix(mMatrix, 0);
134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            super.render(canvas);
135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            canvas.restore();
136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    };
138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
13931cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    @Override
140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onEyePositionChanged(float x, float y, float z) {
141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mRootPane.lockRendering();
142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mX = x;
143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mY = y;
144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mZ = z;
145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mRootPane.unlockRendering();
146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mRootPane.invalidate();
147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
149bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    private void onDown(int index) {
15031cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSelectionDrawer.setPressedIndex(index);
151bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    }
152bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
153bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    private void onUp() {
15431cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSelectionDrawer.setPressedIndex(-1);
155bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    }
156bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onSingleTapUp(int slotIndex) {
158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (targetSet == null) return; // Content is dirty, we shall reload soon
160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // ignore selection action if the target set does not support cache
162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // operation (like a local album).
163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if ((targetSet.getSupportedOperations()
164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                & MediaSet.SUPPORT_CACHE) == 0) {
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            showToastForLocalAlbum();
166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return;
167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Path path = targetSet.getPath();
170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        boolean isFullyCached =
171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                (targetSet.getCacheFlag() == MediaObject.CACHE_FLAG_FULL);
172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        boolean isSelected = mSelectionManager.isItemSelected(path);
173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (!isFullyCached) {
175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // We only count the media sets that will be made available offline
176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // in this session.
177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (isSelected) {
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                --mAlbumCountToMakeAvailableOffline;
179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                ++mAlbumCountToMakeAvailableOffline;
181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        long sizeOfTarget = targetSet.getCacheSize();
1858e565703e8d482421714383a8ad40a67929ce2daOwen Lin        mCacheStorageInfo.increaseTargetCacheSize(
1868e565703e8d482421714383a8ad40a67929ce2daOwen Lin                (isFullyCached ^ isSelected) ? -sizeOfTarget : sizeOfTarget);
1878e565703e8d482421714383a8ad40a67929ce2daOwen Lin        refreshCacheStorageInfo();
188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSelectionManager.toggle(path);
1907260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin        mSlotView.invalidate();
191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onCreate(Bundle data, Bundle restoreState) {
195766941ee72831a2c76defb4d826cab24d918e0dfBobby Georgescu        super.onCreate(data, restoreState);
1968e565703e8d482421714383a8ad40a67929ce2daOwen Lin        mCacheStorageInfo = new CacheStorageUsageInfo(mActivity);
197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        initializeViews();
198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        initializeData(data);
199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mEyePosition = new EyePosition(mActivity.getAndroidContext(), this);
2008e565703e8d482421714383a8ad40a67929ce2daOwen Lin        mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
2018e565703e8d482421714383a8ad40a67929ce2daOwen Lin            @Override
2028e565703e8d482421714383a8ad40a67929ce2daOwen Lin            public void handleMessage(Message message) {
2038e565703e8d482421714383a8ad40a67929ce2daOwen Lin                switch (message.what) {
2048e565703e8d482421714383a8ad40a67929ce2daOwen Lin                    case MSG_REFRESH_STORAGE_INFO:
2058e565703e8d482421714383a8ad40a67929ce2daOwen Lin                        refreshCacheStorageInfo();
2068e565703e8d482421714383a8ad40a67929ce2daOwen Lin                        break;
2078e565703e8d482421714383a8ad40a67929ce2daOwen Lin                    case MSG_REQUEST_LAYOUT: {
2088e565703e8d482421714383a8ad40a67929ce2daOwen Lin                        mLayoutReady = true;
2098e565703e8d482421714383a8ad40a67929ce2daOwen Lin                        removeMessages(MSG_REQUEST_LAYOUT);
2108e565703e8d482421714383a8ad40a67929ce2daOwen Lin                        mRootPane.requestLayout();
2118e565703e8d482421714383a8ad40a67929ce2daOwen Lin                        break;
2128e565703e8d482421714383a8ad40a67929ce2daOwen Lin                    }
2138e565703e8d482421714383a8ad40a67929ce2daOwen Lin                }
2148e565703e8d482421714383a8ad40a67929ce2daOwen Lin            }
2158e565703e8d482421714383a8ad40a67929ce2daOwen Lin        };
2168e565703e8d482421714383a8ad40a67929ce2daOwen Lin    }
2178e565703e8d482421714383a8ad40a67929ce2daOwen Lin
2188e565703e8d482421714383a8ad40a67929ce2daOwen Lin    @Override
2198e565703e8d482421714383a8ad40a67929ce2daOwen Lin    public void onConfigurationChanged(Configuration config) {
2208e565703e8d482421714383a8ad40a67929ce2daOwen Lin        // We use different layout resources for different configs
2218e565703e8d482421714383a8ad40a67929ce2daOwen Lin        initializeFooterViews();
2228e565703e8d482421714383a8ad40a67929ce2daOwen Lin        FrameLayout layout = (FrameLayout) ((Activity) mActivity).findViewById(R.id.footer);
2238e565703e8d482421714383a8ad40a67929ce2daOwen Lin        if (layout.getVisibility() == View.VISIBLE) {
2248e565703e8d482421714383a8ad40a67929ce2daOwen Lin            layout.removeAllViews();
2258e565703e8d482421714383a8ad40a67929ce2daOwen Lin            layout.addView(mFooterContent);
2268e565703e8d482421714383a8ad40a67929ce2daOwen Lin        }
227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onPause() {
231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super.onPause();
232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetDataAdapter.pause();
23331cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSelectionDrawer.pause();
234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mEyePosition.pause();
2358e565703e8d482421714383a8ad40a67929ce2daOwen Lin
2368e565703e8d482421714383a8ad40a67929ce2daOwen Lin        if (mUpdateStorageInfo != null) {
2378e565703e8d482421714383a8ad40a67929ce2daOwen Lin            mUpdateStorageInfo.cancel();
2388e565703e8d482421714383a8ad40a67929ce2daOwen Lin            mUpdateStorageInfo = null;
2398e565703e8d482421714383a8ad40a67929ce2daOwen Lin        }
2408e565703e8d482421714383a8ad40a67929ce2daOwen Lin        mHandler.removeMessages(MSG_REFRESH_STORAGE_INFO);
2418e565703e8d482421714383a8ad40a67929ce2daOwen Lin
2428e565703e8d482421714383a8ad40a67929ce2daOwen Lin        FrameLayout layout = (FrameLayout) ((Activity) mActivity).findViewById(R.id.footer);
2438e565703e8d482421714383a8ad40a67929ce2daOwen Lin        layout.removeAllViews();
2448e565703e8d482421714383a8ad40a67929ce2daOwen Lin        layout.setVisibility(View.INVISIBLE);
245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
2478e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private Job<Void> mUpdateStorageInfoJob = new Job<Void>() {
2488e565703e8d482421714383a8ad40a67929ce2daOwen Lin        @Override
2498e565703e8d482421714383a8ad40a67929ce2daOwen Lin        public Void run(JobContext jc) {
2508e565703e8d482421714383a8ad40a67929ce2daOwen Lin            mCacheStorageInfo.loadStorageInfo(jc);
2518e565703e8d482421714383a8ad40a67929ce2daOwen Lin            if (!jc.isCancelled()) {
2528e565703e8d482421714383a8ad40a67929ce2daOwen Lin                mHandler.sendEmptyMessage(MSG_REFRESH_STORAGE_INFO);
2538e565703e8d482421714383a8ad40a67929ce2daOwen Lin            }
2548e565703e8d482421714383a8ad40a67929ce2daOwen Lin            return null;
2558e565703e8d482421714383a8ad40a67929ce2daOwen Lin        }
2568e565703e8d482421714383a8ad40a67929ce2daOwen Lin    };
2578e565703e8d482421714383a8ad40a67929ce2daOwen Lin
258f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onResume() {
260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super.onResume();
261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        setContentPane(mRootPane);
262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetDataAdapter.resume();
26331cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSelectionDrawer.resume();
264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mEyePosition.resume();
2658e565703e8d482421714383a8ad40a67929ce2daOwen Lin        mUpdateStorageInfo = mActivity.getThreadPool().submit(mUpdateStorageInfoJob);
2668e565703e8d482421714383a8ad40a67929ce2daOwen Lin        FrameLayout layout = (FrameLayout) ((Activity) mActivity).findViewById(R.id.footer);
2678e565703e8d482421714383a8ad40a67929ce2daOwen Lin        layout.addView(mFooterContent);
2688e565703e8d482421714383a8ad40a67929ce2daOwen Lin        layout.setVisibility(View.VISIBLE);
269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
270f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void initializeData(Bundle data) {
272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String mediaPath = data.getString(ManageCachePage.KEY_MEDIA_PATH);
273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSelectionManager.setSourceMediaSet(mMediaSet);
275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // We will always be in selection mode in this page.
277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSelectionManager.setAutoLeaveSelectionMode(false);
278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSelectionManager.enterSelectionMode();
279f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
280c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin        mAlbumSetDataAdapter = new AlbumSetDataLoader(
281f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mActivity, mMediaSet, DATA_CACHE_SIZE);
28231cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSelectionDrawer.setModel(mAlbumSetDataAdapter);
283f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
284f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
285f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void initializeViews() {
28628cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin        Activity activity = mActivity;
2878e565703e8d482421714383a8ad40a67929ce2daOwen Lin
288f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSelectionManager = new SelectionManager(mActivity, true);
289f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSelectionManager.setSelectionListener(this);
290f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
2918e565703e8d482421714383a8ad40a67929ce2daOwen Lin        Config.ManageCachePage config = Config.ManageCachePage.get(activity);
29248ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin        mSlotView = new SlotView(mActivity, config.slotViewSpec);
29331cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSelectionDrawer = new ManageCacheDrawer(mActivity, mSelectionManager, mSlotView,
29431cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin                config.labelSpec, config.cachePinSize, config.cachePinMargin);
29531cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSlotView.setSlotRenderer(mSelectionDrawer);
2967260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin        mSlotView.setListener(new SlotView.SimpleListener() {
297f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            @Override
298bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            public void onDown(int index) {
299bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang                ManageCachePage.this.onDown(index);
300bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            }
301bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
302bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            @Override
30390fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang            public void onUp(boolean followedByLongPress) {
304bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang                ManageCachePage.this.onUp();
305bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            }
306bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
307bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            @Override
308f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            public void onSingleTapUp(int slotIndex) {
309f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                ManageCachePage.this.onSingleTapUp(slotIndex);
310f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
311f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        });
3127260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin        mRootPane.addComponent(mSlotView);
3138e565703e8d482421714383a8ad40a67929ce2daOwen Lin        initializeFooterViews();
3148e565703e8d482421714383a8ad40a67929ce2daOwen Lin    }
315f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
3168e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private void initializeFooterViews() {
31728cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin        Activity activity = mActivity;
318f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
3198e565703e8d482421714383a8ad40a67929ce2daOwen Lin        LayoutInflater inflater = activity.getLayoutInflater();
3208e565703e8d482421714383a8ad40a67929ce2daOwen Lin        mFooterContent = inflater.inflate(R.layout.manage_offline_bar, null);
321f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
3228e565703e8d482421714383a8ad40a67929ce2daOwen Lin        mFooterContent.findViewById(R.id.done).setOnClickListener(this);
3238e565703e8d482421714383a8ad40a67929ce2daOwen Lin        refreshCacheStorageInfo();
324f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
325f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
3268e565703e8d482421714383a8ad40a67929ce2daOwen Lin    @Override
3278e565703e8d482421714383a8ad40a67929ce2daOwen Lin    public void onClick(View view) {
3288e565703e8d482421714383a8ad40a67929ce2daOwen Lin        Utils.assertTrue(view.getId() == R.id.done);
32948ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin        GLRoot root = mActivity.getGLRoot();
33048ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin        root.lockRenderThread();
33148ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin        try {
33248ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin            ArrayList<Path> ids = mSelectionManager.getSelected(false);
33348ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin            if (ids.size() == 0) {
33448ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin                onBackPressed();
33548ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin                return;
33648ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin            }
33748ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin            showToast();
3388e565703e8d482421714383a8ad40a67929ce2daOwen Lin
33948ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin            MenuExecutor menuExecutor = new MenuExecutor(mActivity, mSelectionManager);
34048ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin            menuExecutor.startAction(R.id.action_toggle_full_caching,
34148ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin                    R.string.process_caching_requests, this);
34248ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin        } finally {
34348ba94ae713dbf57898cfa84ae69517da50cf7a0Owen Lin            root.unlockRenderThread();
344f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
345f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
346f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
347f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void showToast() {
348f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mAlbumCountToMakeAvailableOffline > 0) {
34928cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin            Activity activity = mActivity;
350f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Toast.makeText(activity, activity.getResources().getQuantityString(
351f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    R.plurals.make_albums_available_offline,
352f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mAlbumCountToMakeAvailableOffline),
353f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    Toast.LENGTH_SHORT).show();
354f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
355f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
356f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
357f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void showToastForLocalAlbum() {
35828cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin        Activity activity = mActivity;
359f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Toast.makeText(activity, activity.getResources().getString(
360f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            R.string.try_to_set_local_album_available_offline),
361f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Toast.LENGTH_SHORT).show();
362f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
363f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
3648e565703e8d482421714383a8ad40a67929ce2daOwen Lin    private void refreshCacheStorageInfo() {
3658e565703e8d482421714383a8ad40a67929ce2daOwen Lin        ProgressBar progressBar = (ProgressBar) mFooterContent.findViewById(R.id.progress);
3668e565703e8d482421714383a8ad40a67929ce2daOwen Lin        TextView status = (TextView) mFooterContent.findViewById(R.id.status);
3678e565703e8d482421714383a8ad40a67929ce2daOwen Lin        progressBar.setMax(PROGRESS_BAR_MAX);
3688e565703e8d482421714383a8ad40a67929ce2daOwen Lin        long totalBytes = mCacheStorageInfo.getTotalBytes();
3698e565703e8d482421714383a8ad40a67929ce2daOwen Lin        long usedBytes = mCacheStorageInfo.getUsedBytes();
3708e565703e8d482421714383a8ad40a67929ce2daOwen Lin        long expectedBytes = mCacheStorageInfo.getExpectedUsedBytes();
3718e565703e8d482421714383a8ad40a67929ce2daOwen Lin        long freeBytes = mCacheStorageInfo.getFreeBytes();
3728e565703e8d482421714383a8ad40a67929ce2daOwen Lin
37328cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin        Activity activity = mActivity;
3748e565703e8d482421714383a8ad40a67929ce2daOwen Lin        if (totalBytes == 0) {
3758e565703e8d482421714383a8ad40a67929ce2daOwen Lin            progressBar.setProgress(0);
3768e565703e8d482421714383a8ad40a67929ce2daOwen Lin            progressBar.setSecondaryProgress(0);
3778e565703e8d482421714383a8ad40a67929ce2daOwen Lin
3788e565703e8d482421714383a8ad40a67929ce2daOwen Lin            // TODO: get the string translated
3798e565703e8d482421714383a8ad40a67929ce2daOwen Lin            String label = activity.getString(R.string.free_space_format, "-");
3808e565703e8d482421714383a8ad40a67929ce2daOwen Lin            status.setText(label);
3818e565703e8d482421714383a8ad40a67929ce2daOwen Lin        } else {
3828e565703e8d482421714383a8ad40a67929ce2daOwen Lin            progressBar.setProgress((int) (usedBytes * PROGRESS_BAR_MAX / totalBytes));
3838e565703e8d482421714383a8ad40a67929ce2daOwen Lin            progressBar.setSecondaryProgress(
3848e565703e8d482421714383a8ad40a67929ce2daOwen Lin                    (int) (expectedBytes * PROGRESS_BAR_MAX / totalBytes));
3858e565703e8d482421714383a8ad40a67929ce2daOwen Lin            String label = activity.getString(R.string.free_space_format,
3868e565703e8d482421714383a8ad40a67929ce2daOwen Lin                    Formatter.formatFileSize(activity, freeBytes));
3878e565703e8d482421714383a8ad40a67929ce2daOwen Lin            status.setText(label);
3888e565703e8d482421714383a8ad40a67929ce2daOwen Lin        }
3898e565703e8d482421714383a8ad40a67929ce2daOwen Lin    }
3908e565703e8d482421714383a8ad40a67929ce2daOwen Lin
39131cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    @Override
392f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onProgressComplete(int result) {
393f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        onBackPressed();
394f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
395f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
39631cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    @Override
397f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onProgressUpdate(int index) {
398f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
399f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
40031cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    @Override
401f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onSelectionModeChange(int mode) {
402f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
403f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
40431cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    @Override
405f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onSelectionChange(Path path, boolean selected) {
406f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
407d759b7c1fc449f4f0ef91997738bbef1bbd96677Owen Lin
408d759b7c1fc449f4f0ef91997738bbef1bbd96677Owen Lin    @Override
409d759b7c1fc449f4f0ef91997738bbef1bbd96677Owen Lin    public void onConfirmDialogDismissed(boolean confirmed) {
410d759b7c1fc449f4f0ef91997738bbef1bbd96677Owen Lin    }
411d759b7c1fc449f4f0ef91997738bbef1bbd96677Owen Lin
412d759b7c1fc449f4f0ef91997738bbef1bbd96677Owen Lin    @Override
413d759b7c1fc449f4f0ef91997738bbef1bbd96677Owen Lin    public void onConfirmDialogShown() {
414d759b7c1fc449f4f0ef91997738bbef1bbd96677Owen Lin    }
415ba50b9420e64731fd5aa8b1410e1f36457a1635aBobby Georgescu
416ba50b9420e64731fd5aa8b1410e1f36457a1635aBobby Georgescu    @Override
417ba50b9420e64731fd5aa8b1410e1f36457a1635aBobby Georgescu    public void onProgressStart() {
418ba50b9420e64731fd5aa8b1410e1f36457a1635aBobby Georgescu    }
419f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
420