1d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu/*
2d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * Copyright (C) 2013 The Android Open Source Project
3d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu *
4d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * Licensed under the Apache License, Version 2.0 (the "License");
5d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * you may not use this file except in compliance with the License.
6d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * You may obtain a copy of the License at
7d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu *
8d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu *      http://www.apache.org/licenses/LICENSE-2.0
9d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu *
10d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * Unless required by applicable law or agreed to in writing, software
11d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * distributed under the License is distributed on an "AS IS" BASIS,
12d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * See the License for the specific language governing permissions and
14d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * limitations under the License.
15d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu */
16d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
17d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescupackage com.android.gallery3d.ingest;
18d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
19d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.app.NotificationManager;
20d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.app.PendingIntent;
21d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.app.Service;
22d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.Context;
23d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.Intent;
24d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.media.MediaScannerConnection;
25d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.media.MediaScannerConnection.MediaScannerConnectionClient;
26d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.mtp.MtpDevice;
27d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.mtp.MtpDeviceInfo;
28d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.mtp.MtpObjectInfo;
29d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.net.Uri;
30d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.Binder;
31d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.IBinder;
32d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.SystemClock;
33d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.support.v4.app.NotificationCompat;
34d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.util.SparseBooleanArray;
35d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.widget.Adapter;
36d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
37d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport com.android.gallery3d.R;
38d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport com.android.gallery3d.app.NotificationIds;
39d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport com.android.gallery3d.data.MtpClient;
40d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport com.android.gallery3d.util.BucketNames;
41384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescuimport com.android.gallery3d.util.UsageStatistics;
42d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
43d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport java.util.ArrayList;
44d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport java.util.Collection;
45d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport java.util.List;
46d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
47d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescupublic class IngestService extends Service implements ImportTask.Listener,
48d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        MtpDeviceIndex.ProgressListener, MtpClient.Listener {
49d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
50d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public class LocalBinder extends Binder {
51d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        IngestService getService() {
52d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            return IngestService.this;
53d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
54d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
55d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
56d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private static final int PROGRESS_UPDATE_INTERVAL_MS = 180;
57d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
58d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private static MtpClient sClient;
59d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
60d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private final IBinder mBinder = new LocalBinder();
61d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private ScannerClient mScannerClient;
62d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private MtpDevice mDevice;
63d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private String mDevicePrettyName;
64d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private MtpDeviceIndex mIndex;
65d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private IngestActivity mClientActivity;
66d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private boolean mRedeliverImportFinish = false;
67384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu    private int mRedeliverImportFinishCount = 0;
68d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private Collection<MtpObjectInfo> mRedeliverObjectsNotImported;
69d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private boolean mRedeliverNotifyIndexChanged = false;
70c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    private boolean mRedeliverIndexFinish = false;
71d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private NotificationManager mNotificationManager;
72d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private NotificationCompat.Builder mNotificationBuilder;
73d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private long mLastProgressIndexTime = 0;
7413fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu    private boolean mNeedRelaunchNotification = false;
75d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
76d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
77d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public void onCreate() {
78d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        super.onCreate();
79d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mScannerClient = new ScannerClient(this);
80d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
81d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mNotificationBuilder = new NotificationCompat.Builder(this);
82d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mNotificationBuilder.setSmallIcon(android.R.drawable.stat_notify_sync) // TODO drawable
83d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                .setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, IngestActivity.class), 0));
84d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mIndex = MtpDeviceIndex.getInstance();
85d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mIndex.setProgressListener(this);
86d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
87d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (sClient == null) {
88d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            sClient = new MtpClient(getApplicationContext());
89d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
90d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        List<MtpDevice> devices = sClient.getDeviceList();
91d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (devices.size() > 0) {
92d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            setDevice(devices.get(0));
93d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
94d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        sClient.addListener(this);
95d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
96d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
97d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
98d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public void onDestroy() {
99d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        sClient.removeListener(this);
100d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mIndex.unsetProgressListener(this);
101d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        super.onDestroy();
102d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
103d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
104d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
105d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public IBinder onBind(Intent intent) {
106d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        return mBinder;
107d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
108d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
109d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private void setDevice(MtpDevice device) {
110d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mDevice == device) return;
111d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mRedeliverImportFinish = false;
112d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mRedeliverObjectsNotImported = null;
113d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mRedeliverNotifyIndexChanged = false;
114c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        mRedeliverIndexFinish = false;
115d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mDevice = device;
116d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mIndex.setDevice(mDevice);
117d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mDevice != null) {
118d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            MtpDeviceInfo deviceInfo = mDevice.getDeviceInfo();
119c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu            if (deviceInfo == null) {
120c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu                setDevice(null);
121c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu                return;
122c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu            } else {
123c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu                mDevicePrettyName = deviceInfo.getModel();
124c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu                mNotificationBuilder.setContentTitle(mDevicePrettyName);
125c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu                new Thread(mIndex.getIndexRunnable()).start();
126c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu            }
127d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        } else {
128d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mDevicePrettyName = null;
129d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
130d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mClientActivity != null) {
131d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mClientActivity.notifyIndexChanged();
132d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        } else {
133d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mRedeliverNotifyIndexChanged = true;
134d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
135d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
136d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
137d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    protected MtpDeviceIndex getIndex() {
138d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        return mIndex;
139d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
140d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
141d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    protected void setClientActivity(IngestActivity activity) {
142d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mClientActivity == activity) return;
143d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mClientActivity = activity;
14413fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu        if (mClientActivity == null) {
14513fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu            if (mNeedRelaunchNotification) {
14613fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu                mNotificationBuilder.setProgress(0, 0, false)
14713fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu                    .setContentText(getResources().getText(R.string.ingest_scanning_done));
14813fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu                mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_SCANNING,
14913fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu                    mNotificationBuilder.build());
15013fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu            }
15113fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu            return;
15213fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu        }
153d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mNotificationManager.cancel(NotificationIds.INGEST_NOTIFICATION_IMPORTING);
154d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mNotificationManager.cancel(NotificationIds.INGEST_NOTIFICATION_SCANNING);
155d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mRedeliverImportFinish) {
156384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu            mClientActivity.onImportFinish(mRedeliverObjectsNotImported,
157384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu                    mRedeliverImportFinishCount);
158d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mRedeliverImportFinish = false;
159d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mRedeliverObjectsNotImported = null;
160d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
161d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mRedeliverNotifyIndexChanged) {
162d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mClientActivity.notifyIndexChanged();
163d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mRedeliverNotifyIndexChanged = false;
164d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
165c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        if (mRedeliverIndexFinish) {
166c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu            mClientActivity.onIndexFinish();
167c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu            mRedeliverIndexFinish = false;
168c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
1691d6725c8074cc47949452a7236d37cbba8633585Bobby Georgescu        if (mDevice != null) {
1701d6725c8074cc47949452a7236d37cbba8633585Bobby Georgescu            mNeedRelaunchNotification = true;
1711d6725c8074cc47949452a7236d37cbba8633585Bobby Georgescu        }
172d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
173d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
174d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    protected void importSelectedItems(SparseBooleanArray selected, Adapter adapter) {
175d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        List<MtpObjectInfo> importHandles = new ArrayList<MtpObjectInfo>();
176d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        for (int i = 0; i < selected.size(); i++) {
177d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            if (selected.valueAt(i)) {
178d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                Object item = adapter.getItem(selected.keyAt(i));
179d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                if (item instanceof MtpObjectInfo) {
180d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    importHandles.add(((MtpObjectInfo) item));
181d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                }
182d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            }
183d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
184d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        ImportTask task = new ImportTask(mDevice, importHandles, BucketNames.IMPORTED, this);
185d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        task.setListener(this);
186d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        mNotificationBuilder.setProgress(0, 0, true)
187d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            .setContentText(getResources().getText(R.string.ingest_importing));
188d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        startForeground(NotificationIds.INGEST_NOTIFICATION_IMPORTING,
189d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    mNotificationBuilder.build());
190d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        new Thread(task).start();
191d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
192d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
193d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
194d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public void deviceAdded(MtpDevice device) {
195d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mDevice == null) {
196d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            setDevice(device);
197384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu            UsageStatistics.onEvent(UsageStatistics.COMPONENT_IMPORTER,
198384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu                    "DeviceConnected", null);
199d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
200d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
201d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
202d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
203d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public void deviceRemoved(MtpDevice device) {
204d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (device == mDevice) {
205d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            setDevice(null);
20613fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu            mNeedRelaunchNotification = false;
207568a8cf9ec253a635a36866efc0e3acebbba2a2eBobby Georgescu            mNotificationManager.cancel(NotificationIds.INGEST_NOTIFICATION_SCANNING);
208d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
209d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
210d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
211d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
212d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public void onImportProgress(int visitedCount, int totalCount,
213d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            String pathIfSuccessful) {
214d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (pathIfSuccessful != null) {
215d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mScannerClient.scanPath(pathIfSuccessful);
216d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
21713fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu        mNeedRelaunchNotification = false;
218d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mClientActivity != null) {
219d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mClientActivity.onImportProgress(visitedCount, totalCount, pathIfSuccessful);
220d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
221a7a73f3f8ea26835c376f38e75bcef12a25cac26Bobby Georgescu        mNotificationBuilder.setProgress(totalCount, visitedCount, false)
222a7a73f3f8ea26835c376f38e75bcef12a25cac26Bobby Georgescu            .setContentText(getResources().getText(R.string.ingest_importing));
223a7a73f3f8ea26835c376f38e75bcef12a25cac26Bobby Georgescu        mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_IMPORTING,
224a7a73f3f8ea26835c376f38e75bcef12a25cac26Bobby Georgescu                mNotificationBuilder.build());
225d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
226d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
227d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
228384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu    public void onImportFinish(Collection<MtpObjectInfo> objectsNotImported,
229384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu            int visitedCount) {
230c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        stopForeground(true);
23113fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu        mNeedRelaunchNotification = true;
232d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mClientActivity != null) {
233384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu            mClientActivity.onImportFinish(objectsNotImported, visitedCount);
234d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        } else {
235d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mRedeliverImportFinish = true;
236d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mRedeliverObjectsNotImported = objectsNotImported;
237384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu            mRedeliverImportFinishCount = visitedCount;
238d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mNotificationBuilder.setProgress(0, 0, false)
239d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                .setContentText(getResources().getText(R.string.import_complete));
240d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_IMPORTING,
241d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    mNotificationBuilder.build());
242d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
243384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu        UsageStatistics.onEvent(UsageStatistics.COMPONENT_IMPORTER,
244384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu                "ImportFinished", null, visitedCount);
245d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
246d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
247d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
248d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public void onObjectIndexed(MtpObjectInfo object, int numVisited) {
24913fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu        mNeedRelaunchNotification = false;
250d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mClientActivity != null) {
251d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mClientActivity.onObjectIndexed(object, numVisited);
252d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        } else {
253d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            // Throttle the updates to one every PROGRESS_UPDATE_INTERVAL_MS milliseconds
254d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            long currentTime = SystemClock.uptimeMillis();
255d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            if (currentTime > mLastProgressIndexTime + PROGRESS_UPDATE_INTERVAL_MS) {
256d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                mLastProgressIndexTime = currentTime;
257d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                mNotificationBuilder.setProgress(0, numVisited, true)
258d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                        .setContentText(getResources().getText(R.string.ingest_scanning));
259d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_SCANNING,
260d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                        mNotificationBuilder.build());
261d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            }
262d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
263d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
264d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
265d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
266d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public void onSorting() {
267d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mClientActivity != null) mClientActivity.onSorting();
268d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
269d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
270d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    @Override
271d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    public void onIndexFinish() {
27213fec90b6a03e21a88cb8b8425e65289904d4186Bobby Georgescu        mNeedRelaunchNotification = true;
273d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        if (mClientActivity != null) {
274d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mClientActivity.onIndexFinish();
275d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        } else {
276d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mNotificationBuilder.setProgress(0, 0, false)
277d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                .setContentText(getResources().getText(R.string.ingest_scanning_done));
278d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_SCANNING,
279d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    mNotificationBuilder.build());
280c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu            mRedeliverIndexFinish = true;
281d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
282d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
283d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
284d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    // Copied from old Gallery3d code
285d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    private static final class ScannerClient implements MediaScannerConnectionClient {
286d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        ArrayList<String> mPaths = new ArrayList<String>();
287d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        MediaScannerConnection mScannerConnection;
288d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        boolean mConnected;
289d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        Object mLock = new Object();
290d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
291d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        public ScannerClient(Context context) {
292d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            mScannerConnection = new MediaScannerConnection(context, this);
293d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
294d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
295d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        public void scanPath(String path) {
296d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            synchronized (mLock) {
297d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                if (mConnected) {
298d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    mScannerConnection.scanFile(path, null);
299d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                } else {
300d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    mPaths.add(path);
301d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    mScannerConnection.connect();
302d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                }
303d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            }
304d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
305d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
306d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        @Override
307d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        public void onMediaScannerConnected() {
308d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            synchronized (mLock) {
309d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                mConnected = true;
310d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                if (!mPaths.isEmpty()) {
311d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    for (String path : mPaths) {
312d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                        mScannerConnection.scanFile(path, null);
313d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    }
314d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                    mPaths.clear();
315d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu                }
316d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu            }
317d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
318d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu
319d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        @Override
320d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        public void onScanCompleted(String path, Uri uri) {
321d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu        }
322d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu    }
323d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu}
324