1fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono/* 2fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * Copyright (C) 2016 The Android Open Source Project 3fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * 4fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * Licensed under the Apache License, Version 2.0 (the "License"); 5fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * you may not use this file except in compliance with the License. 6fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * You may obtain a copy of the License at 7fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * 8fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * http://www.apache.org/licenses/LICENSE-2.0 9fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * 10fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * Unless required by applicable law or agreed to in writing, software 11fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * distributed under the License is distributed on an "AS IS" BASIS, 12fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * See the License for the specific language governing permissions and 14fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * limitations under the License. 15fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono */ 16fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono 17fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hironopackage com.android.mtp; 18fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono 1998f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hironoimport android.annotation.NonNull; 2098f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hironoimport android.app.Notification; 213393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hironoimport android.app.NotificationChannel; 223393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hironoimport android.app.NotificationManager; 23fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hironoimport android.content.ComponentName; 24fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hironoimport android.content.Context; 25fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hironoimport android.content.Intent; 26c5949bd39c788e98edd9862c7ac12e822a906ad5Daichi Hironoimport com.android.internal.annotations.VisibleForTesting; 2798f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hironoimport com.android.internal.util.Preconditions; 28fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono 29fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono/** 30fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono * Sends intent to MtpDocumentsService. 31fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono */ 32fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hironoclass ServiceIntentSender { 333393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono private final static String CHANNEL_ID = "device_notification_channel"; 34c5949bd39c788e98edd9862c7ac12e822a906ad5Daichi Hirono private final Context mContext; 35fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono 36fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono ServiceIntentSender(Context context) { 37fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono mContext = context; 383393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono 393393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono // Create notification channel. 403393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono final NotificationChannel mChannel = new NotificationChannel( 413393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono CHANNEL_ID, 423393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono context.getResources().getString( 433393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono com.android.internal.R.string.default_notification_channel_label), 443393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono NotificationManager.IMPORTANCE_LOW); 453393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono final NotificationManager notificationManager = 463393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 473393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono notificationManager.createNotificationChannel(mChannel); 48fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono } 49fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono 50c5949bd39c788e98edd9862c7ac12e822a906ad5Daichi Hirono @VisibleForTesting 51c5949bd39c788e98edd9862c7ac12e822a906ad5Daichi Hirono protected ServiceIntentSender() { 52c5949bd39c788e98edd9862c7ac12e822a906ad5Daichi Hirono mContext = null; 53c5949bd39c788e98edd9862c7ac12e822a906ad5Daichi Hirono } 54c5949bd39c788e98edd9862c7ac12e822a906ad5Daichi Hirono 55d3c6dd1522dc9b08476b70c4f6923f4debff78eeDaichi Hirono /** 56d3c6dd1522dc9b08476b70c4f6923f4debff78eeDaichi Hirono * Notify the change of opened device set. 5798f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono * @param records List of opened devices. Can be empty. 58d3c6dd1522dc9b08476b70c4f6923f4debff78eeDaichi Hirono */ 5998f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono void sendUpdateNotificationIntent(@NonNull MtpDeviceRecord[] records) { 6098f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono Preconditions.checkNotNull(records); 61fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono final Intent intent = new Intent(MtpDocumentsService.ACTION_UPDATE_NOTIFICATION); 62fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono intent.setComponent(new ComponentName(mContext, MtpDocumentsService.class)); 6398f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono if (records.length != 0) { 6498f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono final int[] ids = new int[records.length]; 6598f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono final Notification[] notifications = new Notification[records.length]; 6698f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono for (int i = 0; i < records.length; i++) { 6798f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono ids[i] = records[i].deviceId; 6898f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono notifications[i] = createNotification(mContext, records[i]); 6998f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono } 7098f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono intent.putExtra(MtpDocumentsService.EXTRA_DEVICE_IDS, ids); 7198f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono intent.putExtra(MtpDocumentsService.EXTRA_DEVICE_NOTIFICATIONS, notifications); 7298f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono mContext.startForegroundService(intent); 73d3c6dd1522dc9b08476b70c4f6923f4debff78eeDaichi Hirono } else { 74d3c6dd1522dc9b08476b70c4f6923f4debff78eeDaichi Hirono mContext.startService(intent); 75d3c6dd1522dc9b08476b70c4f6923f4debff78eeDaichi Hirono } 76fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono } 7798f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono 7898f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono private static Notification createNotification(Context context, MtpDeviceRecord device) { 7998f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono final String title = context.getResources().getString( 8098f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono R.string.accessing_notification_title, 8198f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono device.name); 823393bc9a7cea48bc85c75f1ec3d417c179a75ee5Daichi Hirono return new Notification.Builder(context, CHANNEL_ID) 8398f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono .setLocalOnly(true) 8498f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono .setContentTitle(title) 8598f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb) 8698f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono .setCategory(Notification.CATEGORY_SYSTEM) 8798f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono .setFlag(Notification.FLAG_NO_CLEAR, true) 8898f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono .build(); 8998f48479e95b04479b5512c587da6bc9fbd73b7eDaichi Hirono } 90fda7474c5faae1e36a9274d8a5fe83e42ec6503bDaichi Hirono} 91