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