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

Commit 03c44458 authored by Evan Laird's avatar Evan Laird
Browse files

DO NOT MERGE: More tests for CurrentUserContextTracker

Reworks some of the CurrentUserContextTracker and test its
functionality, and consequently fixes some NotificationConversationInfo
tests

Test: atest CurrentUserContextTrackerTest NotificationConversationInfoTest
Bug: 151843296
Fixes: 154332812
Change-Id: I0e3d4b1c64cba2cab581abca4ce9377a7c4676de
parent 31ca5474
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -18,8 +18,10 @@ package com.android.systemui.settings

import android.content.Context
import android.os.UserHandle
import androidx.annotation.VisibleForTesting
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.util.Assert
import java.lang.IllegalStateException
import javax.inject.Inject
import javax.inject.Singleton

@@ -32,7 +34,16 @@ class CurrentUserContextTracker @Inject constructor(
    broadcastDispatcher: BroadcastDispatcher
) {
    private val userTracker: CurrentUserTracker
    var currentUserContext: Context
    private var initialized = false

    private var _curUserContext: Context? = null
    val currentUserContext: Context
        get() {
            if (!initialized) {
                throw IllegalStateException("Must initialize before getting context")
            }
            return _curUserContext!!
        }

    init {
        userTracker = object : CurrentUserTracker(broadcastDispatcher) {
@@ -40,21 +51,21 @@ class CurrentUserContextTracker @Inject constructor(
                handleUserSwitched(newUserId)
            }
        }

        currentUserContext = makeUserContext(userTracker.currentUserId)
    }

    fun initialize() {
        initialized = true
        _curUserContext = makeUserContext(userTracker.currentUserId)
        userTracker.startTracking()
    }

    private fun handleUserSwitched(newUserId: Int) {
        currentUserContext = makeUserContext(newUserId)
    @VisibleForTesting
    fun handleUserSwitched(newUserId: Int) {
        _curUserContext = makeUserContext(newUserId)
    }

    private fun makeUserContext(uid: Int): Context {
        Assert.isMainThread()
        return sysuiContext.createContextAsUser(
                UserHandle.getUserHandleForUid(userTracker.currentUserId), 0)
        return sysuiContext.createContextAsUser(UserHandle.of(uid), 0)
    }
}
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -378,6 +378,7 @@ public final class NotificationEntry extends ListEntry {
    /**
     * Returns the data needed for a bubble for this notification, if it exists.
     */
    @Nullable
    public Notification.BubbleMetadata getBubbleMetadata() {
        return mBubbleMetadata;
    }
@@ -385,7 +386,7 @@ public final class NotificationEntry extends ListEntry {
    /**
     * Sets bubble metadata for this notification.
     */
    public void setBubbleMetadata(Notification.BubbleMetadata metadata) {
    public void setBubbleMetadata(@Nullable Notification.BubbleMetadata metadata) {
        mBubbleMetadata = metadata;
    }

+6 −3
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -98,7 +99,7 @@ public class NotificationConversationInfo extends LinearLayout implements
    private ShortcutInfo mShortcutInfo;
    private String mConversationId;
    private StatusBarNotification mSbn;
    private Notification.BubbleMetadata mBubbleMetadata;
    @Nullable private Notification.BubbleMetadata mBubbleMetadata;
    private Context mUserContext;
    private Provider<PriorityOnboardingDialogController.Builder> mBuilderProvider;
    private boolean mIsDeviceProvisioned;
@@ -203,6 +204,7 @@ public class NotificationConversationInfo extends LinearLayout implements
            String pkg,
            NotificationChannel notificationChannel,
            NotificationEntry entry,
            Notification.BubbleMetadata bubbleMetadata,
            OnSettingsClickListener onSettingsClick,
            OnSnoozeClickListener onSnoozeClickListener,
            ConversationIconFactory conversationIconFactory,
@@ -224,7 +226,7 @@ public class NotificationConversationInfo extends LinearLayout implements
        mOnSnoozeClickListener = onSnoozeClickListener;
        mIconFactory = conversationIconFactory;
        mUserContext = userContext;
        mBubbleMetadata = entry.getBubbleMetadata();
        mBubbleMetadata = bubbleMetadata;
        mBuilderProvider = builderProvider;

        mShortcutManager = shortcutManager;
@@ -538,7 +540,8 @@ public class NotificationConversationInfo extends LinearLayout implements
            Log.e(TAG, "Could not check conversation senders", e);
        }

        boolean showAsBubble = mBubbleMetadata.getAutoExpandBubble()
        boolean showAsBubble = mBubbleMetadata != null
                && mBubbleMetadata.getAutoExpandBubble()
                && Settings.Global.getInt(mContext.getContentResolver(),
                        NOTIFICATION_BUBBLES, 0) == 1;

+5 −3
Original line number Diff line number Diff line
@@ -366,7 +366,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
            final ExpandableNotificationRow row,
            NotificationConversationInfo notificationInfoView) throws Exception {
        NotificationGuts guts = row.getGuts();
        StatusBarNotification sbn = row.getEntry().getSbn();
        NotificationEntry entry = row.getEntry();
        StatusBarNotification sbn = entry.getSbn();
        String packageName = sbn.getPackageName();
        // Settings link is only valid for notifications that specify a non-system user
        NotificationConversationInfo.OnSettingsClickListener onSettingsClick = null;
@@ -407,8 +408,9 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
                mNotificationManager,
                mVisualStabilityManager,
                packageName,
                row.getEntry().getChannel(),
                row.getEntry(),
                entry.getChannel(),
                entry,
                entry.getBubbleMetadata(),
                onSettingsClick,
                onSnoozeClickListener,
                iconFactoryLoader,
+92 −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.settings

import android.content.Context
import android.content.ContextWrapper
import android.os.UserHandle
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations

@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class CurrentUserContextTrackerTest : SysuiTestCase() {

    private lateinit var tracker: CurrentUserContextTracker
    @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        allowTestableLooperAsMainThread()

        // wrap Context so that tests don't throw for missing package errors
        val wrapped = object : ContextWrapper(context) {
            override fun createContextAsUser(user: UserHandle, flags: Int): Context {
                val mockContext = mock(Context::class.java)
                `when`(mockContext.user).thenReturn(user)
                `when`(mockContext.userId).thenReturn(user.identifier)
                return mockContext
            }
        }

        tracker = CurrentUserContextTracker(wrapped, broadcastDispatcher)
        tracker.initialize()
    }

    @Test
    fun testContextExistsAfterInit_noCrash() {
        tracker.currentUserContext
    }

    @Test
    fun testUserContextIsCorrectAfterUserSwitch() {
        // We always start out with system ui test
        assertTrue("Starting userId should be 0", tracker.currentUserContext.userId == 0)

        // WHEN user changes
        tracker.handleUserSwitched(1)

        // THEN user context should have the correct userId
        assertTrue("User has changed to userId 1, the context should reflect that",
                tracker.currentUserContext.userId == 1)
    }

    @Suppress("UNUSED_PARAMETER")
    @Test(expected = IllegalStateException::class)
    fun testContextTrackerThrowsExceptionWhenNotInitialized() {
        // GIVEN an uninitialized CurrentUserContextTracker
        val userTracker = CurrentUserContextTracker(context, broadcastDispatcher)

        // WHEN client asks for a context
        val userContext = userTracker.currentUserContext

        // THEN an exception is thrown
    }
}
 No newline at end of file
Loading