1702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project/* //device/content/providers/media/src/com/android/providers/media/MediaScannerService.java
2702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project**
3702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project** Copyright 2007, The Android Open Source Project
4702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project**
5702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project** you may not use this file except in compliance with the License.
7702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project** You may obtain a copy of the License at
8702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project**
9702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project**
11702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project** See the License for the specific language governing permissions and
15702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project** limitations under the License.
16702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project*/
17702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
18702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectpackage com.android.providers.media;
19702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
20702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.app.Service;
21702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.content.ContentValues;
22702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.content.Context;
23702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.content.Intent;
24702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.media.IMediaScannerListener;
25702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.media.IMediaScannerService;
26702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.media.MediaScanner;
27702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.net.Uri;
28702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.os.Bundle;
29702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.os.Environment;
30702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.os.Handler;
31702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.os.IBinder;
32702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.os.Looper;
33702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.os.Message;
34702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.os.PowerManager;
35702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.os.Process;
363145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasaniimport android.os.UserManager;
37c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwoodimport android.os.storage.StorageManager;
38702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.provider.MediaStore;
39702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport android.util.Log;
40702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
413145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasaniimport com.android.internal.util.ArrayUtils;
423145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasani
43702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Projectimport java.io.File;
4410621774fbce4bf5f3e0d829226683f76bf8fdd5Marco Nelissenimport java.util.Arrays;
45702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
46ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkeypublic class MediaScannerService extends Service implements Runnable {
47702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    private static final String TAG = "MediaScannerService";
48702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
49702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    private volatile Looper mServiceLooper;
50702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    private volatile ServiceHandler mServiceHandler;
51702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
52d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood    private String[] mExternalStoragePaths;
53702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
54702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    private void openDatabase(String volumeName) {
55702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        try {
56702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            ContentValues values = new ContentValues();
57702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            values.put("name", volumeName);
58702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            getContentResolver().insert(Uri.parse("content://media/"), values);
59702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        } catch (IllegalArgumentException ex) {
60702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            Log.w(TAG, "failed to open media database");
61702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        }
62702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    }
63702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
64702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    private void scan(String[] directories, String volumeName) {
65815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen        Uri uri = Uri.parse("file://" + directories[0]);
66702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        // don't sleep while scanning
67702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        mWakeLock.acquire();
68702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
69702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        try {
70815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            ContentValues values = new ContentValues();
71815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            values.put(MediaStore.MEDIA_SCANNER_VOLUME, volumeName);
72815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            Uri scanUri = getContentResolver().insert(MediaStore.getMediaScannerUri(), values);
73702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
74815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_STARTED, uri));
75815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen
76815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            try {
77815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen                if (volumeName.equals(MediaProvider.EXTERNAL_VOLUME)) {
78815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen                    openDatabase(volumeName);
79815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen                }
80702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
81ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey                try (MediaScanner scanner = new MediaScanner(this, volumeName)) {
82ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey                    scanner.scanDirectories(directories);
83ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey                }
84815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            } catch (Exception e) {
85815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen                Log.e(TAG, "exception in MediaScanner.scan()", e);
86815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            }
87815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen
88815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            getContentResolver().delete(scanUri, null, null);
89702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
90815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen        } finally {
91815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_FINISHED, uri));
92815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen            mWakeLock.release();
93815d1fc6bd273236aa870ec00dad851febd6f504Marco Nelissen        }
94702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    }
95702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
96702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    @Override
97ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey    public void onCreate() {
98702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
99702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
100c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood        StorageManager storageManager = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
101c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood        mExternalStoragePaths = storageManager.getVolumePaths();
1024f2186758ee1c6eaa702bf1511b233b26143b631Mike Lockwood
103702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        // Start up the thread running the service.  Note that we create a
104702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        // separate thread because the service normally runs in the process's
105702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        // main thread, which we don't want to block.
106702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        Thread thr = new Thread(null, this, "MediaScannerService");
107702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        thr.start();
108702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    }
109702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
110702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    @Override
111ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey    public int onStartCommand(Intent intent, int flags, int startId) {
112702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        while (mServiceHandler == null) {
113702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            synchronized (this) {
114702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                try {
115702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    wait(100);
116702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                } catch (InterruptedException e) {
117702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                }
118702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            }
119702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        }
120702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
121a1a85d0c6ffebdd47e17d2a8f7cc60c94ccb9cc0Mike Lockwood        if (intent == null) {
122a1a85d0c6ffebdd47e17d2a8f7cc60c94ccb9cc0Mike Lockwood            Log.e(TAG, "Intent is null in onStartCommand: ",
123a1a85d0c6ffebdd47e17d2a8f7cc60c94ccb9cc0Mike Lockwood                new NullPointerException());
124a1a85d0c6ffebdd47e17d2a8f7cc60c94ccb9cc0Mike Lockwood            return Service.START_NOT_STICKY;
125a1a85d0c6ffebdd47e17d2a8f7cc60c94ccb9cc0Mike Lockwood        }
126a1a85d0c6ffebdd47e17d2a8f7cc60c94ccb9cc0Mike Lockwood
127702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        Message msg = mServiceHandler.obtainMessage();
128702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        msg.arg1 = startId;
129702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        msg.obj = intent.getExtras();
130702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        mServiceHandler.sendMessage(msg);
131a1a85d0c6ffebdd47e17d2a8f7cc60c94ccb9cc0Mike Lockwood
132a1a85d0c6ffebdd47e17d2a8f7cc60c94ccb9cc0Mike Lockwood        // Try again later if we are killed before we can finish scanning.
133a1a85d0c6ffebdd47e17d2a8f7cc60c94ccb9cc0Mike Lockwood        return Service.START_REDELIVER_INTENT;
134702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    }
135702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
136702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    @Override
137ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey    public void onDestroy() {
138702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        // Make sure thread has started before telling it to quit.
139702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        while (mServiceLooper == null) {
140702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            synchronized (this) {
141702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                try {
142702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    wait(100);
143702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                } catch (InterruptedException e) {
144702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                }
145702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            }
146702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        }
147702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        mServiceLooper.quit();
148702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    }
149702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
150ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey    @Override
151ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey    public void run() {
152c2527694fc19e7086b025a6d5c01af75dd5d80c9Mike Lockwood        // reduce priority below other background threads to avoid interfering
153c2527694fc19e7086b025a6d5c01af75dd5d80c9Mike Lockwood        // with other services at boot time.
154c2527694fc19e7086b025a6d5c01af75dd5d80c9Mike Lockwood        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND +
155c2527694fc19e7086b025a6d5c01af75dd5d80c9Mike Lockwood                Process.THREAD_PRIORITY_LESS_FAVORABLE);
156702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        Looper.prepare();
157702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
158702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        mServiceLooper = Looper.myLooper();
159702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        mServiceHandler = new ServiceHandler();
160702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
161702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        Looper.loop();
162702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    }
163ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey
164702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    private Uri scanFile(String path, String mimeType) {
165d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood        String volumeName = MediaProvider.EXTERNAL_VOLUME;
166ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey
167ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey        try (MediaScanner scanner = new MediaScanner(this, volumeName)) {
168704fe6bc9da64c3d99db9b5a40705419aa091ce4Mike Lockwood            // make sure the file path is in canonical form
169704fe6bc9da64c3d99db9b5a40705419aa091ce4Mike Lockwood            String canonicalPath = new File(path).getCanonicalPath();
170ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey            return scanner.scanSingleFile(canonicalPath, mimeType);
171704fe6bc9da64c3d99db9b5a40705419aa091ce4Mike Lockwood        } catch (Exception e) {
172704fe6bc9da64c3d99db9b5a40705419aa091ce4Mike Lockwood            Log.e(TAG, "bad path " + path + " in scanFile()", e);
173704fe6bc9da64c3d99db9b5a40705419aa091ce4Mike Lockwood            return null;
174704fe6bc9da64c3d99db9b5a40705419aa091ce4Mike Lockwood        }
175702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    }
176702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
177702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    @Override
178ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey    public IBinder onBind(Intent intent) {
179702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        return mBinder;
180702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    }
181702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
182702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    private final IMediaScannerService.Stub mBinder =
183702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            new IMediaScannerService.Stub() {
184ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey        public void requestScanFile(String path, String mimeType, IMediaScannerListener listener) {
185e0095e763c73934e6d36be9c7722ccc3e790df77Joe Onorato            if (false) {
186702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                Log.d(TAG, "IMediaScannerService.scanFile: " + path + " mimeType: " + mimeType);
187702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            }
188702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            Bundle args = new Bundle();
189702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            args.putString("filepath", path);
190702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            args.putString("mimetype", mimeType);
191702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            if (listener != null) {
192702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                args.putIBinder("listener", listener.asBinder());
193702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            }
194702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            startService(new Intent(MediaScannerService.this,
195702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    MediaScannerService.class).putExtras(args));
196702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        }
197702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
198702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        public void scanFile(String path, String mimeType) {
199702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            requestScanFile(path, mimeType, null);
200702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        }
201702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    };
202702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
203ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey    private final class ServiceHandler extends Handler {
204702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        @Override
205ded3fa69af029f7c41d92efeec8006983a570550Jeff Sharkey        public void handleMessage(Message msg) {
206702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            Bundle arguments = (Bundle) msg.obj;
207570c47c82e382b1bb82c8e1d14e1fc9fc8e8d0e0Marco Nelissen            if (arguments == null) {
208570c47c82e382b1bb82c8e1d14e1fc9fc8e8d0e0Marco Nelissen                Log.e(TAG, "null intent, b/20953950");
209570c47c82e382b1bb82c8e1d14e1fc9fc8e8d0e0Marco Nelissen                return;
210570c47c82e382b1bb82c8e1d14e1fc9fc8e8d0e0Marco Nelissen            }
211702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            String filePath = arguments.getString("filepath");
212702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
213702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            try {
214702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                if (filePath != null) {
215702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    IBinder binder = arguments.getIBinder("listener");
216702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    IMediaScannerListener listener =
217702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                            (binder == null ? null : IMediaScannerListener.Stub.asInterface(binder));
218df21a16539a9ca247899e8d85042bcb17d9ce4c1Marco Nelissen                    Uri uri = null;
219df21a16539a9ca247899e8d85042bcb17d9ce4c1Marco Nelissen                    try {
220df21a16539a9ca247899e8d85042bcb17d9ce4c1Marco Nelissen                        uri = scanFile(filePath, arguments.getString("mimetype"));
221df21a16539a9ca247899e8d85042bcb17d9ce4c1Marco Nelissen                    } catch (Exception e) {
222df21a16539a9ca247899e8d85042bcb17d9ce4c1Marco Nelissen                        Log.e(TAG, "Exception scanning file", e);
223df21a16539a9ca247899e8d85042bcb17d9ce4c1Marco Nelissen                    }
224702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    if (listener != null) {
225702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                        listener.scanCompleted(filePath, uri);
226702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    }
227702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                } else {
228702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    String volume = arguments.getString("volume");
229702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    String[] directories = null;
2303145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasani
231702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    if (MediaProvider.INTERNAL_VOLUME.equals(volume)) {
232702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                        // scan internal media storage
233702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                        directories = new String[] {
234702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                                Environment.getRootDirectory() + "/media",
2351cf716968afd032e8261df3f6c4671c1f0c5f769Jeff Sharkey                                Environment.getOemDirectory() + "/media",
236702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                        };
237702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    }
238702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    else if (MediaProvider.EXTERNAL_VOLUME.equals(volume)) {
239d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood                        // scan external storage volumes
2403145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasani                        if (getSystemService(UserManager.class).isDemoUser()) {
2413145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasani                            directories = ArrayUtils.appendElement(String.class,
2423145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasani                                    mExternalStoragePaths,
243543d12828aeac9a154a5f121a16cf43560da4ca1Fyodor Kupolov                                    Environment.getDataPreloadsMediaDirectory().getAbsolutePath());
2443145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasani                        } else {
2453145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasani                            directories = mExternalStoragePaths;
2463145e76cbf55b40d42463868b60f2abdf4602fb5Amith Yamasani                        }
247702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    }
248c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood
249702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    if (directories != null) {
250e0095e763c73934e6d36be9c7722ccc3e790df77Joe Onorato                        if (false) Log.d(TAG, "start scanning volume " + volume + ": "
25110621774fbce4bf5f3e0d829226683f76bf8fdd5Marco Nelissen                                + Arrays.toString(directories));
252702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                        scan(directories, volume);
253e0095e763c73934e6d36be9c7722ccc3e790df77Joe Onorato                        if (false) Log.d(TAG, "done scanning volume " + volume);
254702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                    }
255702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                }
256702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            } catch (Exception e) {
257702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project                Log.e(TAG, "Exception in handleMessage", e);
258702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            }
259702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project
260702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project            stopSelf(msg.arg1);
261702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project        }
262702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project    };
263702152725052b7b3903ed647cf53f04724886a1bThe Android Open Source Project}
264