• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 import android.app.Notification;
20 import android.app.Service;
21 import android.app.NotificationManager;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
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 {
36     static final String ACTION_OPEN_DEVICE = "com.android.mtp.OPEN_DEVICE";
37     static final String ACTION_CLOSE_DEVICE = "com.android.mtp.CLOSE_DEVICE";
38     static final String ACTION_UPDATE_NOTIFICATION = "com.android.mtp.UPDATE_NOTIFICATION";
39     static final String EXTRA_DEVICE = "device";
40 
41     NotificationManager mNotificationManager;
42 
43     @Override
onBind(Intent intent)44     public IBinder onBind(Intent intent) {
45         // The service is used via intents.
46         return null;
47     }
48 
49     @Override
onCreate()50     public void onCreate() {
51         super.onCreate();
52         mNotificationManager = getSystemService(NotificationManager.class);
53     }
54 
55     @Override
onStartCommand(Intent intent, int flags, int startId)56     public int onStartCommand(Intent intent, int flags, int startId) {
57         // If intent is null, the service was restarted.
58         if (intent == null || ACTION_UPDATE_NOTIFICATION.equals(intent.getAction())) {
59             return updateForegroundState() ? START_STICKY : START_NOT_STICKY;
60         }
61         return START_NOT_STICKY;
62     }
63 
64     /**
65      * Updates the foreground state of the service.
66      * @return Whether the service is foreground or not.
67      */
updateForegroundState()68     private boolean updateForegroundState() {
69         final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
70         int notificationId = 0;
71         Notification notification = null;
72         // TODO: Hide notification if the device has already been removed.
73         for (final MtpDeviceRecord record : provider.getOpenedDeviceRecordsCache()) {
74             final String title = getResources().getString(
75                     R.string.accessing_notification_title,
76                     record.name);
77             notificationId = record.deviceId;
78             notification = new Notification.Builder(this)
79                     .setLocalOnly(true)
80                     .setContentTitle(title)
81                     .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
82                     .setCategory(Notification.CATEGORY_SYSTEM)
83                     .setPriority(Notification.PRIORITY_LOW)
84                     .build();
85             mNotificationManager.notify(record.deviceId, notification);
86         }
87 
88         if (notification != null) {
89             startForeground(notificationId, notification);
90             return true;
91         } else {
92             stopForeground(true /* removeNotification */);
93             stopSelf();
94             return false;
95         }
96     }
97 
logErrorMessage(Exception exp)98     private static void logErrorMessage(Exception exp) {
99         if (exp.getMessage() != null) {
100             Log.e(MtpDocumentsProvider.TAG, exp.getMessage());
101         } else {
102             Log.e(MtpDocumentsProvider.TAG, exp.toString());
103         }
104     }
105 }
106