1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.data;
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
3d43ea8bb1b1afcb27c1c6c673c8ed2707bc70ff0Owen Linimport android.annotation.TargetApi;
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.Context;
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.media.MediaScannerConnection;
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.media.MediaScannerConnection.MediaScannerConnectionClient;
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.mtp.MtpObjectInfo;
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri;
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.os.Environment;
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.util.Log;
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.widget.Toast;
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
132b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.R;
14d43ea8bb1b1afcb27c1c6c673c8ed2707bc70ff0Owen Linimport com.android.gallery3d.common.ApiHelper;
1554d626f5b529508637c3117a28874bee35bb0fc8Yuli Huangimport com.android.gallery3d.util.BucketNames;
162b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.GalleryUtils;
172b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.io.File;
19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.ArrayList;
20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.List;
21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
22d43ea8bb1b1afcb27c1c6c673c8ed2707bc70ff0Owen Lin@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB_MR1)
23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class MtpContext implements MtpClient.Listener {
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "MtpContext";
25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private ScannerClient mScannerClient;
27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private Context mContext;
28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private MtpClient mClient;
29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final class ScannerClient implements MediaScannerConnectionClient {
31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        ArrayList<String> mPaths = new ArrayList<String>();
32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        MediaScannerConnection mScannerConnection;
33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        boolean mConnected;
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Object mLock = new Object();
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public ScannerClient(Context context) {
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mScannerConnection = new MediaScannerConnection(context, this);
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void scanPath(String path) {
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            synchronized (mLock) {
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (mConnected) {
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mScannerConnection.scanFile(path, null);
44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                } else {
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mPaths.add(path);
46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mScannerConnection.connect();
47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void onMediaScannerConnected() {
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            synchronized (mLock) {
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mConnected = true;
55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (!mPaths.isEmpty()) {
56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    for (String path : mPaths) {
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        mScannerConnection.scanFile(path, null);
58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    }
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mPaths.clear();
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void onScanCompleted(String path, Uri uri) {
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public MtpContext(Context context) {
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mContext = context;
71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mScannerClient = new ScannerClient(context);
72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mClient = new MtpClient(mContext);
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void pause() {
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mClient.removeListener(this);
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void resume() {
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mClient.addListener(this);
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        notifyDirty();
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
847817979db0c52ffeacb951625b1e821eba303285Ahbong Chang    @Override
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void deviceAdded(android.mtp.MtpDevice device) {
86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        notifyDirty();
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        showToast(R.string.camera_connected);
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
907817979db0c52ffeacb951625b1e821eba303285Ahbong Chang    @Override
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void deviceRemoved(android.mtp.MtpDevice device) {
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        notifyDirty();
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        showToast(R.string.camera_disconnected);
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void notifyDirty() {
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mContext.getContentResolver().notifyChange(Uri.parse("mtp://"), null);
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void showToast(final int msg) {
101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public MtpClient getMtpClient() {
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mClient;
106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public boolean copyFile(String deviceName, MtpObjectInfo objInfo) {
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (GalleryUtils.hasSpaceForSize(objInfo.getCompressedSize())) {
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            File dest = Environment.getExternalStorageDirectory();
11154d626f5b529508637c3117a28874bee35bb0fc8Yuli Huang            dest = new File(dest, BucketNames.IMPORTED);
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            dest.mkdirs();
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            String destPath = new File(dest, objInfo.getName()).getAbsolutePath();
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int objectId = objInfo.getObjectHandle();
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mClient.importFile(deviceName, objectId, destPath)) {
116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mScannerClient.scanPath(destPath);
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return true;
118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Log.w(TAG, "No space to import " + objInfo.getName() +
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    " whose size = " + objInfo.getCompressedSize());
122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return false;
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public boolean copyAlbum(String deviceName, String albumName,
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            List<MtpObjectInfo> children) {
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        File dest = Environment.getExternalStorageDirectory();
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        dest = new File(dest, albumName);
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        dest.mkdirs();
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int success = 0;
132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        for (MtpObjectInfo child : children) {
133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (!GalleryUtils.hasSpaceForSize(child.getCompressedSize())) continue;
134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            File importedFile = new File(dest, child.getName());
136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            String path = importedFile.getAbsolutePath();
137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mClient.importFile(deviceName, child.getObjectHandle(), path)) {
138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mScannerClient.scanPath(path);
139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                success++;
140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return success == children.size();
143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
145