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

Commit 0b8224a5 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker Committed by Duy Truong
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/20342565',...

Merge cherrypicks of ['googleplex-android-review.googlesource.com/20342565', 'googleplex-android-review.googlesource.com/23687079', 'googleplex-android-review.googlesource.com/23728043', 'googleplex-android-review.googlesource.com/23892861', 'googleplex-android-review.googlesource.com/23883016', 'googleplex-android-review.googlesource.com/23834099'] into security-aosp-rvc-release.

Change-Id: I5e9a42a8c5a5a7d276b09edceb8ecf640d3cc13d
parents b36ab5a5 42f3d2db
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -465,6 +465,12 @@ public class NotificationManager {
     */
    public static final int BUBBLE_PREFERENCE_SELECTED = 2;

    /**
     * Maximum length of the component name of a registered NotificationListenerService.
     * @hide
     */
    public static int MAX_SERVICE_COMPONENT_NAME_LENGTH = 500;

    @UnsupportedAppUsage
    private static INotificationManager sService;

+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.media;

import android.content.ComponentName;
import android.content.Context;
import android.media.browse.MediaBrowser;
import android.os.Bundle;

import javax.inject.Inject;

/**
 * Testable wrapper around {@link MediaBrowser} constructor
 */
public class MediaBrowserFactory {
    private final Context mContext;

    @Inject
    public MediaBrowserFactory(Context context) {
        mContext = context;
    }

    /**
     * Creates a new MediaBrowser
     *
     * @param serviceComponent
     * @param callback
     * @param rootHints
     * @return
     */
    public MediaBrowser create(ComponentName serviceComponent,
            MediaBrowser.ConnectionCallback callback, Bundle rootHints) {
        return new MediaBrowser(mContext, serviceComponent, callback, rootHints);
    }
}
 No newline at end of file
+40 −13
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.UserHandle
import android.provider.Settings
import android.service.media.MediaBrowserService
import android.util.Log
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.tuner.TunerService
@@ -47,7 +48,8 @@ class MediaResumeListener @Inject constructor(
    private val context: Context,
    private val broadcastDispatcher: BroadcastDispatcher,
    @Background private val backgroundExecutor: Executor,
    private val tunerService: TunerService
    private val tunerService: TunerService,
    private val mediaBrowserFactory: ResumeMediaBrowserFactory
) : MediaDataManager.Listener {

    private var useMediaResumption: Boolean = Utils.useMediaResumption(context)
@@ -58,7 +60,8 @@ class MediaResumeListener @Inject constructor(
    private var mediaBrowser: ResumeMediaBrowser? = null
    private var currentUserId: Int = context.userId

    private val userChangeReceiver = object : BroadcastReceiver() {
    @VisibleForTesting
    val userChangeReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (Intent.ACTION_USER_UNLOCKED == intent.action) {
                loadMediaResumptionControls()
@@ -87,9 +90,16 @@ class MediaResumeListener @Inject constructor(
                Log.e(TAG, "Error getting package information", e)
            }

            Log.d(TAG, "Adding resume controls $desc")
            mediaDataManager.addResumptionControls(currentUserId, desc, resumeAction, token,
                appName.toString(), appIntent, component.packageName)
            Log.d(TAG, "Adding resume controls for ${browser.userId}: $desc")
            mediaDataManager.addResumptionControls(
                browser.userId,
                desc,
                resumeAction,
                token,
                appName.toString(),
                appIntent,
                component.packageName
            )
        }
    }

@@ -132,7 +142,11 @@ class MediaResumeListener @Inject constructor(
            val component = ComponentName(packageName, className)
            resumeComponents.add(component)
        }
        Log.d(TAG, "loaded resume components ${resumeComponents.toArray().contentToString()}")
        Log.d(
            TAG,
            "loaded resume components for $currentUserId: " +
                "${resumeComponents.toArray().contentToString()}"
        )
    }

    /**
@@ -143,9 +157,19 @@ class MediaResumeListener @Inject constructor(
            return
        }

        val pm = context.packageManager
        resumeComponents.forEach {
            val browser = ResumeMediaBrowser(context, mediaBrowserCallback, it)
            // Verify that the service exists for this user
            val intent = Intent(MediaBrowserService.SERVICE_INTERFACE)
            intent.component = it
            val inf = pm.resolveServiceAsUser(intent, 0, currentUserId)
            if (inf != null) {
                val browser =
                        mediaBrowserFactory.create(mediaBrowserCallback, it, currentUserId)
                browser.findRecentMedia()
            } else {
                Log.d(TAG, "User $currentUserId does not have component $it")
            }
        }
    }

@@ -159,7 +183,7 @@ class MediaResumeListener @Inject constructor(
                Log.d(TAG, "Checking for service component for " + data.packageName)
                val pm = context.packageManager
                val serviceIntent = Intent(MediaBrowserService.SERVICE_INTERFACE)
                val resumeInfo = pm.queryIntentServices(serviceIntent, 0)
                val resumeInfo = pm.queryIntentServicesAsUser(serviceIntent, 0, currentUserId)

                val inf = resumeInfo?.filter {
                    it.serviceInfo.packageName == data.packageName
@@ -183,7 +207,7 @@ class MediaResumeListener @Inject constructor(
    private fun tryUpdateResumptionList(key: String, componentName: ComponentName) {
        Log.d(TAG, "Testing if we can connect to $componentName")
        mediaBrowser?.disconnect()
        mediaBrowser = ResumeMediaBrowser(context,
        mediaBrowser = mediaBrowserFactory.create(
                object : ResumeMediaBrowser.Callback() {
                    override fun onConnected() {
                        Log.d(TAG, "yes we can resume with $componentName")
@@ -200,7 +224,9 @@ class MediaResumeListener @Inject constructor(
                        mediaBrowser = null
                    }
                },
                componentName)
                componentName,
                currentUserId
            )
        mediaBrowser?.testConnection()
    }

@@ -235,7 +261,7 @@ class MediaResumeListener @Inject constructor(
    private fun getResumeAction(componentName: ComponentName): Runnable {
        return Runnable {
            mediaBrowser?.disconnect()
            mediaBrowser = ResumeMediaBrowser(context,
            mediaBrowser = mediaBrowserFactory.create(
                object : ResumeMediaBrowser.Callback() {
                    override fun onConnected() {
                        if (mediaBrowser?.token == null) {
@@ -257,7 +283,8 @@ class MediaResumeListener @Inject constructor(
                        mediaBrowser = null
                    }
                },
                componentName)
                componentName,
                currentUserId)
            mediaBrowser?.restart()
        }
    }
+20 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.media;

import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -46,6 +47,9 @@ public class ResumeMediaBrowser {
    private static final String TAG = "ResumeMediaBrowser";
    private final Context mContext;
    private final Callback mCallback;
    private MediaBrowserFactory mBrowserFactory;
    @UserIdInt private final int mUserId;

    private MediaBrowser mMediaBrowser;
    private ComponentName mComponentName;

@@ -54,11 +58,15 @@ public class ResumeMediaBrowser {
     * @param context the context
     * @param callback used to report media items found
     * @param componentName Component name of the MediaBrowserService this browser will connect to
     * @param userId ID of the current user
     */
    public ResumeMediaBrowser(Context context, Callback callback, ComponentName componentName) {
    public ResumeMediaBrowser(Context context, Callback callback, ComponentName componentName,
            MediaBrowserFactory browserFactory, @UserIdInt int userId) {
        mContext = context;
        mCallback = callback;
        mComponentName = componentName;
        mBrowserFactory = browserFactory;
        mUserId = userId;
    }

    /**
@@ -74,7 +82,7 @@ public class ResumeMediaBrowser {
        disconnect();
        Bundle rootHints = new Bundle();
        rootHints.putBoolean(MediaBrowserService.BrowserRoot.EXTRA_RECENT, true);
        mMediaBrowser = new MediaBrowser(mContext,
        mMediaBrowser = mBrowserFactory.create(
                mComponentName,
                mConnectionCallback,
                rootHints);
@@ -182,7 +190,7 @@ public class ResumeMediaBrowser {
        disconnect();
        Bundle rootHints = new Bundle();
        rootHints.putBoolean(MediaBrowserService.BrowserRoot.EXTRA_RECENT, true);
        mMediaBrowser = new MediaBrowser(mContext, mComponentName,
        mMediaBrowser = mBrowserFactory.create(mComponentName,
                new MediaBrowser.ConnectionCallback() {
                    @Override
                    public void onConnected() {
@@ -212,6 +220,14 @@ public class ResumeMediaBrowser {
        mMediaBrowser.connect();
    }

    /**
     * Get the ID of the user associated with this broswer
     * @return the user ID
     */
    public @UserIdInt int getUserId() {
        return mUserId;
    }

    /**
     * Get the media session token
     * @return the token, or null if the MediaBrowser is null or disconnected
@@ -268,7 +284,7 @@ public class ResumeMediaBrowser {
                };
        Bundle rootHints = new Bundle();
        rootHints.putBoolean(MediaBrowserService.BrowserRoot.EXTRA_RECENT, true);
        mMediaBrowser = new MediaBrowser(mContext,
        mMediaBrowser =  mBrowserFactory.create(
                mComponentName,
                connectionCallback,
                rootHints);
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.media;

import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Context;

import javax.inject.Inject;

/**
 * Testable wrapper around {@link ResumeMediaBrowser} constructor
 */
public class ResumeMediaBrowserFactory {
    private final Context mContext;
    private final MediaBrowserFactory mBrowserFactory;

    @Inject
    public ResumeMediaBrowserFactory(Context context, MediaBrowserFactory browserFactory) {
        mContext = context;
        mBrowserFactory = browserFactory;
    }

    /**
     * Creates a new ResumeMediaBrowser.
     *
     * @param callback will be called on connection or error, and addTrack when media item found
     * @param componentName component to browse
     * @param userId ID of the current user
     * @return
     */
    public ResumeMediaBrowser create(ResumeMediaBrowser.Callback callback,
            ComponentName componentName, @UserIdInt int userId) {
        return new ResumeMediaBrowser(mContext, callback, componentName, mBrowserFactory,
                userId);
    }
}
Loading