Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 203be491 authored by Daichi Hirono's avatar Daichi Hirono
Browse files

Use Context#startForegroundService in MTP provider

NotificationManager.startServiceInForeground() was moved to
Context#startForegroundService. MtpDocumentsProvider should use new one.

Bug: 36794559
Test: MtpDocumentsProviderTests
Change-Id: I84723ee8c3f0f8bfe4d5ea8ad035c01c42ce8bab
parent 1ce83f00
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -509,7 +509,7 @@ public class MtpDocumentsProvider extends DocumentsProvider {
            final DeviceToolkit toolkit =
            final DeviceToolkit toolkit =
                    new DeviceToolkit(mMtpManager, mResolver, mDatabase, device);
                    new DeviceToolkit(mMtpManager, mResolver, mDatabase, device);
            mDeviceToolkits.put(deviceId, toolkit);
            mDeviceToolkits.put(deviceId, toolkit);
            mIntentSender.sendUpdateNotificationIntent(device);
            mIntentSender.sendUpdateNotificationIntent(getOpenedDeviceRecordsCache());
            try {
            try {
                mRootScanner.resume().await();
                mRootScanner.resume().await();
            } catch (InterruptedException error) {
            } catch (InterruptedException error) {
@@ -524,9 +524,9 @@ public class MtpDocumentsProvider extends DocumentsProvider {
    void closeDevice(int deviceId) throws IOException, InterruptedException {
    void closeDevice(int deviceId) throws IOException, InterruptedException {
        synchronized (mDeviceListLock) {
        synchronized (mDeviceListLock) {
            closeDeviceInternal(deviceId);
            closeDeviceInternal(deviceId);
            mIntentSender.sendUpdateNotificationIntent(getOpenedDeviceRecordsCache());
        }
        }
        mRootScanner.resume();
        mRootScanner.resume();
        mIntentSender.sendUpdateNotificationIntent(null);
    }
    }


    MtpDeviceRecord[] getOpenedDeviceRecordsCache() {
    MtpDeviceRecord[] getOpenedDeviceRecordsCache() {
+40 −32
Original line number Original line Diff line number Diff line
@@ -16,13 +16,17 @@


package com.android.mtp;
package com.android.mtp;


import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
import android.app.Notification;
import android.app.Service;
import android.app.Service;
import android.app.NotificationManager;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.os.IBinder;
import android.os.IBinder;
import android.os.Parcelable;
import android.service.notification.StatusBarNotification;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import com.android.internal.util.Preconditions;
import java.util.HashSet;
import java.util.HashSet;
import java.util.Set;
import java.util.Set;


@@ -33,7 +37,8 @@ import java.util.Set;
 */
 */
public class MtpDocumentsService extends Service {
public class MtpDocumentsService extends Service {
    static final String ACTION_UPDATE_NOTIFICATION = "com.android.mtp.UPDATE_NOTIFICATION";
    static final String ACTION_UPDATE_NOTIFICATION = "com.android.mtp.UPDATE_NOTIFICATION";
    static final String EXTRA_DEVICE = "device";
    static final String EXTRA_DEVICE_IDS = "deviceIds";
    static final String EXTRA_DEVICE_NOTIFICATIONS = "deviceNotifications";


    private NotificationManager mNotificationManager;
    private NotificationManager mNotificationManager;


@@ -53,7 +58,12 @@ public class MtpDocumentsService extends Service {
    public int onStartCommand(Intent intent, int flags, int startId) {
    public int onStartCommand(Intent intent, int flags, int startId) {
        // If intent is null, the service was restarted.
        // If intent is null, the service was restarted.
        if (intent == null || ACTION_UPDATE_NOTIFICATION.equals(intent.getAction())) {
        if (intent == null || ACTION_UPDATE_NOTIFICATION.equals(intent.getAction())) {
            return updateForegroundState() ? START_STICKY : START_NOT_STICKY;
            final int[] ids = intent.hasExtra(EXTRA_DEVICE_IDS) ?
                    intent.getExtras().getIntArray(EXTRA_DEVICE_IDS) : null;
            final Notification[] notifications = intent.hasExtra(EXTRA_DEVICE_NOTIFICATIONS) ?
                    castToNotifications(intent.getExtras().getParcelableArray(
                            EXTRA_DEVICE_NOTIFICATIONS)) : null;
            return updateForegroundState(ids, notifications) ? START_STICKY : START_NOT_STICKY;
        }
        }
        return START_NOT_STICKY;
        return START_NOT_STICKY;
    }
    }
@@ -62,35 +72,38 @@ public class MtpDocumentsService extends Service {
     * Updates the foreground state of the service.
     * Updates the foreground state of the service.
     * @return Whether the service is foreground or not.
     * @return Whether the service is foreground or not.
     */
     */
    private boolean updateForegroundState() {
    private boolean updateForegroundState(
        final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
            @Nullable int[] ids, @Nullable Notification[] notifications) {
        final Set<Integer> openedNotification = new HashSet<>();
        final Set<Integer> openedNotification = new HashSet<>();
        boolean hasForegroundNotification = false;
        final int size = ids != null ? ids.length : 0;

        if (size != 0) {
        final StatusBarNotification[] activeNotifications =
            Preconditions.checkArgument(ids != null);
                mNotificationManager.getActiveNotifications();
            Preconditions.checkArgument(notifications != null);
            Preconditions.checkArgument(ids.length == notifications.length);
        }


        for (final MtpDeviceRecord record : provider.getOpenedDeviceRecordsCache()) {
        for (int i = 0; i < size; i++) {
            openedNotification.add(record.deviceId);
            if (i == 0) {
            if (!hasForegroundNotification) {
                // Mark this service as foreground with the notification so that the process is
                // Mark this service as foreground with the notification so that the process is not
                // not killed by the system while a MTP device is opened.
                // killed by the system while a MTP device is opened.
                startForeground(ids[i], notifications[i]);
                startForeground(record.deviceId, createNotification(this, record));
                hasForegroundNotification = true;
            } else {
            } else {
                // Only one notification can be shown as a foreground notification. We need to show
                // Only one notification can be shown as a foreground notification. We need to
                // the rest as normal notification.
                // show the rest as normal notification.
                mNotificationManager.notify(record.deviceId, createNotification(this, record));
                mNotificationManager.notify(ids[i], notifications[i]);
            }
            }
            openedNotification.add(ids[i]);
        }
        }


        final StatusBarNotification[] activeNotifications =
                mNotificationManager.getActiveNotifications();
        for (final StatusBarNotification notification : activeNotifications) {
        for (final StatusBarNotification notification : activeNotifications) {
            if (!openedNotification.contains(notification.getId())) {
            if (!openedNotification.contains(notification.getId())) {
                mNotificationManager.cancel(notification.getId());
                mNotificationManager.cancel(notification.getId());
            }
            }
        }
        }


        if (!hasForegroundNotification) {
        if (size == 0) {
            // There is no opened device.
            // There is no opened device.
            stopForeground(true /* removeNotification */);
            stopForeground(true /* removeNotification */);
            stopSelf();
            stopSelf();
@@ -100,17 +113,12 @@ public class MtpDocumentsService extends Service {
        return true;
        return true;
    }
    }


    public static Notification createNotification(Context context, MtpDeviceRecord device) {
    private static @NonNull Notification[] castToNotifications(@NonNull Parcelable[] src) {
        final String title = context.getResources().getString(
        Preconditions.checkNotNull(src);
                R.string.accessing_notification_title,
        final Notification[] notifications = new Notification[src.length];
                device.name);
        for (int i = 0; i < src.length; i++) {
        return new Notification.Builder(context)
            notifications[i] = (Notification) src[i];
                .setLocalOnly(true)
        }
                .setContentTitle(title)
        return notifications;
                .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
                .setCategory(Notification.CATEGORY_SYSTEM)
                .setPriority(Notification.PRIORITY_LOW)
                .setFlag(Notification.FLAG_NO_CLEAR, true)
                .build();
    }
    }
}
}
+30 −11
Original line number Original line Diff line number Diff line
@@ -16,11 +16,12 @@


package com.android.mtp;
package com.android.mtp;


import android.annotation.Nullable;
import android.annotation.NonNull;
import android.app.NotificationManager;
import android.app.Notification;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import com.android.internal.util.Preconditions;


/**
/**
 * Sends intent to MtpDocumentsService.
 * Sends intent to MtpDocumentsService.
@@ -34,20 +35,38 @@ class ServiceIntentSender {


    /**
    /**
     * Notify the change of opened device set.
     * Notify the change of opened device set.
     * @param record If a new device is opened, pass the device record. If a device is closed, pass
     * @param records List of opened devices. Can be empty.
     *     null.
     */
     */
    void sendUpdateNotificationIntent(@Nullable MtpDeviceRecord record) {
    void sendUpdateNotificationIntent(@NonNull MtpDeviceRecord[] records) {
        Preconditions.checkNotNull(records);
        final Intent intent = new Intent(MtpDocumentsService.ACTION_UPDATE_NOTIFICATION);
        final Intent intent = new Intent(MtpDocumentsService.ACTION_UPDATE_NOTIFICATION);
        intent.setComponent(new ComponentName(mContext, MtpDocumentsService.class));
        intent.setComponent(new ComponentName(mContext, MtpDocumentsService.class));
        final NotificationManager manager = mContext.getSystemService(NotificationManager.class);
        if (records.length != 0) {
        if (record != null) {
            final int[] ids = new int[records.length];
            manager.startServiceInForeground(
            final Notification[] notifications = new Notification[records.length];
                    intent,
            for (int i = 0; i < records.length; i++) {
                    record.deviceId,
                ids[i] = records[i].deviceId;
                    MtpDocumentsService.createNotification(mContext, record));
                notifications[i] = createNotification(mContext, records[i]);
            }
            intent.putExtra(MtpDocumentsService.EXTRA_DEVICE_IDS, ids);
            intent.putExtra(MtpDocumentsService.EXTRA_DEVICE_NOTIFICATIONS, notifications);
            mContext.startForegroundService(intent);
        } else {
        } else {
            mContext.startService(intent);
            mContext.startService(intent);
        }
        }
    }
    }

    private static Notification createNotification(Context context, MtpDeviceRecord device) {
        final String title = context.getResources().getString(
                R.string.accessing_notification_title,
                device.name);
        return new Notification.Builder(context)
                .setLocalOnly(true)
                .setContentTitle(title)
                .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
                .setCategory(Notification.CATEGORY_SYSTEM)
                .setPriority(Notification.PRIORITY_LOW)
                .setFlag(Notification.FLAG_NO_CLEAR, true)
                .build();
    }
}
}
+1 −3
Original line number Original line Diff line number Diff line
@@ -16,13 +16,11 @@


package com.android.mtp;
package com.android.mtp;


import android.annotation.Nullable;

class TestServiceIntentSender extends ServiceIntentSender {
class TestServiceIntentSender extends ServiceIntentSender {
    TestServiceIntentSender() {
    TestServiceIntentSender() {
        super(null);
        super(null);
    }
    }


    @Override
    @Override
    void sendUpdateNotificationIntent(@Nullable MtpDeviceRecord record) {}
    void sendUpdateNotificationIntent(MtpDeviceRecord[] record) {}
}
}