Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package com.android.mtp; |
| 18 | |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 19 | import android.app.Notification; |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 20 | import android.app.Service; |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 21 | import android.app.NotificationManager; |
Daichi Hirono | fda7474 | 2016-02-01 13:00:31 +0900 | [diff] [blame] | 22 | import android.content.ComponentName; |
| 23 | import android.content.Context; |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 24 | import android.content.Intent; |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 25 | import android.os.IBinder; |
| 26 | import android.util.Log; |
| 27 | |
| 28 | import java.io.IOException; |
| 29 | |
| 30 | /** |
| 31 | * Service to manage lifetime of DocumentsProvider's process. |
| 32 | * The service prevents the system from killing the process that holds USB connections. The service |
| 33 | * starts to run when the first MTP device is opened, and stops when the last MTP device is closed. |
| 34 | */ |
| 35 | public class MtpDocumentsService extends Service { |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 36 | static final String ACTION_OPEN_DEVICE = "com.android.mtp.OPEN_DEVICE"; |
| 37 | static final String ACTION_CLOSE_DEVICE = "com.android.mtp.CLOSE_DEVICE"; |
Daichi Hirono | fda7474 | 2016-02-01 13:00:31 +0900 | [diff] [blame] | 38 | static final String ACTION_UPDATE_NOTIFICATION = "com.android.mtp.UPDATE_NOTIFICATION"; |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 39 | static final String EXTRA_DEVICE = "device"; |
| 40 | |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 41 | NotificationManager mNotificationManager; |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 42 | |
| 43 | @Override |
| 44 | public IBinder onBind(Intent intent) { |
| 45 | // The service is used via intents. |
| 46 | return null; |
| 47 | } |
| 48 | |
| 49 | @Override |
| 50 | public void onCreate() { |
| 51 | super.onCreate(); |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 52 | mNotificationManager = getSystemService(NotificationManager.class); |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | @Override |
| 56 | public int onStartCommand(Intent intent, int flags, int startId) { |
Daichi Hirono | e0282dd | 2015-11-26 15:20:08 +0900 | [diff] [blame] | 57 | // If intent is null, the service was restarted. |
Daichi Hirono | fda7474 | 2016-02-01 13:00:31 +0900 | [diff] [blame] | 58 | if (intent == null || ACTION_UPDATE_NOTIFICATION.equals(intent.getAction())) { |
| 59 | return updateForegroundState() ? START_STICKY : START_NOT_STICKY; |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 60 | } |
Daichi Hirono | fda7474 | 2016-02-01 13:00:31 +0900 | [diff] [blame] | 61 | return START_NOT_STICKY; |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 62 | } |
| 63 | |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 64 | /** |
| 65 | * Updates the foreground state of the service. |
| 66 | * @return Whether the service is foreground or not. |
| 67 | */ |
| 68 | private boolean updateForegroundState() { |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 69 | final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance(); |
Daichi Hirono | e6bffff | 2016-01-25 16:06:57 +0900 | [diff] [blame] | 70 | int notificationId = 0; |
| 71 | Notification notification = null; |
Daichi Hirono | fda7474 | 2016-02-01 13:00:31 +0900 | [diff] [blame] | 72 | // TODO: Hide notification if the device has already been removed. |
Daichi Hirono | 0f32537 | 2016-02-21 15:50:30 +0900 | [diff] [blame] | 73 | for (final MtpDeviceRecord record : provider.getOpenedDeviceRecordsCache()) { |
| 74 | final String title = getResources().getString( |
| 75 | R.string.accessing_notification_title, |
| 76 | record.name); |
| 77 | final String description = getResources().getString( |
| 78 | R.string.accessing_notification_description); |
| 79 | notificationId = record.deviceId; |
| 80 | notification = new Notification.Builder(this) |
| 81 | .setLocalOnly(true) |
| 82 | .setContentTitle(title) |
| 83 | .setContentText(description) |
| 84 | .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb) |
| 85 | .setCategory(Notification.CATEGORY_SYSTEM) |
| 86 | .setPriority(Notification.PRIORITY_LOW) |
| 87 | .build(); |
| 88 | mNotificationManager.notify(record.deviceId, notification); |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 89 | } |
Daichi Hirono | e6bffff | 2016-01-25 16:06:57 +0900 | [diff] [blame] | 90 | |
| 91 | if (notification != null) { |
| 92 | startForeground(notificationId, notification); |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 93 | return true; |
| 94 | } else { |
| 95 | stopForeground(true /* removeNotification */); |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 96 | stopSelf(); |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 97 | return false; |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 98 | } |
| 99 | } |
| 100 | |
Daichi Hirono | a57d9ed | 2015-12-07 10:52:42 +0900 | [diff] [blame] | 101 | private static void logErrorMessage(Exception exp) { |
| 102 | if (exp.getMessage() != null) { |
| 103 | Log.e(MtpDocumentsProvider.TAG, exp.getMessage()); |
| 104 | } else { |
| 105 | Log.e(MtpDocumentsProvider.TAG, exp.toString()); |
Daichi Hirono | 2efe4ca | 2015-07-27 16:47:46 +0900 | [diff] [blame] | 106 | } |
| 107 | } |
| 108 | } |