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

Commit 93dd8838 authored by Dave Mankoff's avatar Dave Mankoff
Browse files

Remove ref to Controller from KeyguardSliceView

This removes the reference that the view has to its controller,
moving click handling up to the controller.

Fixes: 162525274
Test: atest SystemUITEsts
Change-Id: Ia99ff4e643fa84fa138720cc5c01c51597f1169d
parent cd42c087
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ public class KeyguardDisplayManager {
        Presentation presentation = mPresentations.get(displayId);
        if (presentation == null) {
            final Presentation newPresentation = new KeyguardPresentation(mContext, display,
                    mKeyguardStatusViewComponentFactory,
                    mInjectableInflater.injectable(LayoutInflater.from(mContext)));
            newPresentation.setOnDismissListener(dialog -> {
                if (newPresentation.equals(mPresentations.get(displayId))) {
@@ -145,9 +146,6 @@ public class KeyguardDisplayManager {
                presentation = null;
            }
            if (presentation != null) {
                mKeyguardStatusViewComponentFactory
                        .build(presentation.findViewById(R.id.clock))
                        .getKeyguardClockSwitchController().init();
                mPresentations.append(displayId, presentation);
                return true;
            }
@@ -251,7 +249,9 @@ public class KeyguardDisplayManager {
    static final class KeyguardPresentation extends Presentation {
        private static final int VIDEO_SAFE_REGION = 80; // Percentage of display width & height
        private static final int MOVE_CLOCK_TIMEOUT = 10000; // 10s
        private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
        private final LayoutInflater mInjectableLayoutInflater;
        private KeyguardClockSwitchController mKeyguardClockSwitchController;
        private View mClock;
        private int mUsableWidth;
        private int mUsableHeight;
@@ -269,8 +269,10 @@ public class KeyguardDisplayManager {
        };

        KeyguardPresentation(Context context, Display display,
                KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
                LayoutInflater injectionLayoutInflater) {
            super(context, display, R.style.Theme_SystemUI_KeyguardPresentation);
            mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
            mInjectableLayoutInflater = injectionLayoutInflater;
            getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
            setCancelable(false);
@@ -312,6 +314,12 @@ public class KeyguardDisplayManager {

            // Avoid screen burn in
            mClock.post(mMoveTextRunnable);

            mKeyguardClockSwitchController = mKeyguardStatusViewComponentFactory
                    .build(findViewById(R.id.clock))
                    .getKeyguardClockSwitchController();

            mKeyguardClockSwitchController.init();
        }
    }
}
+26 −67
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@

package com.android.keyguard;

import static android.app.slice.Slice.HINT_LIST_ITEM;
import static android.view.Display.INVALID_DISPLAY;

import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
@@ -41,11 +38,8 @@ import android.view.animation.Animation;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.lifecycle.LiveData;
import androidx.slice.Slice;
import androidx.slice.SliceItem;
import androidx.slice.core.SliceQuery;
import androidx.slice.widget.ListContent;
import androidx.slice.widget.RowContent;
import androidx.slice.widget.SliceContent;

@@ -55,27 +49,23 @@ import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * View visible under the clock on the lock screen and AoD.
 */
public class KeyguardSliceView extends LinearLayout implements View.OnClickListener {
public class KeyguardSliceView extends LinearLayout {

    private static final String TAG = "KeyguardSliceView";
    public static final int DEFAULT_ANIM_DURATION = 550;

    private final HashMap<View, PendingIntent> mClickActions;
    private ActivityStarter mActivityStarter;
    private final LayoutTransition mLayoutTransition;
    @VisibleForTesting
    TextView mTitle;
@@ -83,8 +73,6 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
    private int mTextColor;
    private float mDarkAmount = 0;

    private LiveData<Slice> mLiveData;
    private int mDisplayId = INVALID_DISPLAY;
    private int mIconSize;
    private int mIconSizeWithHeader;
    /**
@@ -96,13 +84,12 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
    private final int mRowPadding;
    private float mRowTextSize;
    private float mRowWithHeaderTextSize;
    private KeyguardSliceViewController mController;
    private View.OnClickListener mOnClickListener;

    public KeyguardSliceView(Context context, AttributeSet attrs) {
        super(context, attrs);

        Resources resources = context.getResources();
        mClickActions = new HashMap<>();
        mRowPadding = resources.getDimensionPixelSize(R.dimen.subtitle_clock_padding);
        mRowWithHeaderPadding = resources.getDimensionPixelSize(R.dimen.header_subtitle_padding);

@@ -130,7 +117,6 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
                R.dimen.widget_label_font_size);
        mRowWithHeaderTextSize = mContext.getResources().getDimensionPixelSize(
                R.dimen.header_row_font_size);
        mTitle.setOnClickListener(this);
        mTitle.setBreakStrategy(LineBreaker.BREAK_STRATEGY_BALANCED);
    }

@@ -147,44 +133,31 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
        return mHasHeader;
    }

    void showSlice(Slice slice) {
        Trace.beginSection("KeyguardSliceView#showSlice");
        if (slice == null) {
    void hideSlice() {
        mTitle.setVisibility(GONE);
        mRow.setVisibility(GONE);
        mHasHeader = false;
        if (mContentChangeListener != null) {
            mContentChangeListener.run();
        }
            Trace.endSection();
            return;
    }
        mClickActions.clear();

        ListContent lc = new ListContent(getContext(), slice);
        SliceContent headerContent = lc.getHeader();
        mHasHeader = headerContent != null && !headerContent.getSliceItem().hasHint(HINT_LIST_ITEM);
        List<SliceContent> subItems = new ArrayList<>();
        for (int i = 0; i < lc.getRowItems().size(); i++) {
            SliceContent subItem = lc.getRowItems().get(i);
            String itemUri = subItem.getSliceItem().getSlice().getUri().toString();
            // Filter out the action row
            if (!KeyguardSliceProvider.KEYGUARD_ACTION_URI.equals(itemUri)) {
                subItems.add(subItem);
            }
        }
    Map<View, PendingIntent> showSlice(RowContent header, List<SliceContent> subItems) {
        Trace.beginSection("KeyguardSliceView#showSlice");
        mHasHeader = header != null;
        Map<View, PendingIntent> clickActions = new HashMap<>();

        if (!mHasHeader) {
            mTitle.setVisibility(GONE);
        } else {
            mTitle.setVisibility(VISIBLE);

            RowContent header = lc.getHeader();
            SliceItem mainTitle = header.getTitleItem();
            CharSequence title = mainTitle != null ? mainTitle.getText() : null;
            mTitle.setText(title);
            if (header.getPrimaryAction() != null
                    && header.getPrimaryAction().getAction() != null) {
                mClickActions.put(mTitle, header.getPrimaryAction().getAction());
                clickActions.put(mTitle, header.getPrimaryAction().getAction());
            }
        }

@@ -214,7 +187,7 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
            if (rc.getPrimaryAction() != null) {
                pendingIntent = rc.getPrimaryAction().getAction();
            }
            mClickActions.put(button, pendingIntent);
            clickActions.put(button, pendingIntent);

            final SliceItem titleItem = rc.getTitleItem();
            button.setText(titleItem == null ? null : titleItem.getText());
@@ -235,14 +208,14 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
                }
            }
            button.setCompoundDrawables(iconDrawable, null, null, null);
            button.setOnClickListener(this);
            button.setOnClickListener(mOnClickListener);
            button.setClickable(pendingIntent != null);
        }

        // Removing old views
        for (int i = 0; i < mRow.getChildCount(); i++) {
            View child = mRow.getChildAt(i);
            if (!mClickActions.containsKey(child)) {
            if (!clickActions.containsKey(child)) {
                mRow.removeView(child);
                i--;
            }
@@ -252,6 +225,8 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
            mContentChangeListener.run();
        }
        Trace.endSection();

        return clickActions;
    }

    public void setDarkAmount(float darkAmount) {
@@ -272,14 +247,6 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
        }
    }

    @Override
    public void onClick(View v) {
        final PendingIntent action = mClickActions.get(v);
        if (action != null && mActivityStarter != null) {
            mActivityStarter.startPendingIntentDismissingKeyguard(action);
        }
    }

    /**
     * Runnable that gets invoked every time the title or the row visibility changes.
     * @param contentChangeListener The listener.
@@ -308,13 +275,8 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
                R.dimen.header_row_font_size);
    }

    public void refresh() {
        mController.refresh();
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("KeyguardSliceView:");
        pw.println("  mClickActions: " + mClickActions);
        pw.println("  mTitle: " + (mTitle == null ? "null" : mTitle.getVisibility() == VISIBLE));
        pw.println("  mRow: " + (mRow == null ? "null" : mRow.getVisibility() == VISIBLE));
        pw.println("  mTextColor: " + Integer.toHexString(mTextColor));
@@ -322,13 +284,10 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
        pw.println("  mHasHeader: " + mHasHeader);
    }

    public void setActivityStarter(ActivityStarter activityStarter) {
        mActivityStarter = activityStarter;
    }

    public void setController(KeyguardSliceViewController keyguardSliceViewController) {
        // TODO: remove this method.
        mController = keyguardSliceViewController;
    @Override
    public void setOnClickListener(View.OnClickListener onClickListener) {
        mOnClickListener = onClickListener;
        mTitle.setOnClickListener(onClickListener);
    }

    public static class Row extends LinearLayout {
+56 −6
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.keyguard;

import static android.app.slice.Slice.HINT_LIST_ITEM;
import static android.view.Display.DEFAULT_DISPLAY;

import android.app.PendingIntent;
import android.net.Uri;
import android.os.Trace;
import android.provider.Settings;
@@ -30,6 +32,9 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.slice.Slice;
import androidx.slice.SliceViewManager;
import androidx.slice.widget.ListContent;
import androidx.slice.widget.RowContent;
import androidx.slice.widget.SliceContent;
import androidx.slice.widget.SliceLiveData;

import com.android.keyguard.dagger.KeyguardStatusViewScope;
@@ -42,15 +47,19 @@ import com.android.systemui.tuner.TunerService;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.inject.Inject;

/** Controller for a {@link KeyguardSliceView}. */
@KeyguardStatusViewScope
public class KeyguardSliceViewController implements Dumpable {
    private static final String TAG = "KeyguardSliceViewController";
    private static final String TAG = "KeyguardSliceViewCtrl";

    private final KeyguardSliceView mView;
    private final KeyguardStatusView mKeyguardStatusView;
    private final ActivityStarter mActivityStarter;
    private final ConfigurationController mConfigurationController;
    private final TunerService mTunerService;
@@ -59,6 +68,7 @@ public class KeyguardSliceViewController implements Dumpable {
    private LiveData<Slice> mLiveData;
    private Uri mKeyguardSliceUri;
    private Slice mSlice;
    private Map<View, PendingIntent> mClickActions;

    private final View.OnAttachStateChangeListener mOnAttachStateChangeListener =
            new View.OnAttachStateChangeListener() {
@@ -106,15 +116,27 @@ public class KeyguardSliceViewController implements Dumpable {
        @Override
        public void onChanged(Slice slice) {
            mSlice = slice;
            mView.showSlice(slice);
            showSlice(slice);
        }
    };

    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final PendingIntent action = mClickActions.get(v);
            if (action != null && mActivityStarter != null) {
                mActivityStarter.startPendingIntentDismissingKeyguard(action);
            }
        }
    };

    @Inject
    public KeyguardSliceViewController(KeyguardSliceView keyguardSliceView,
            ActivityStarter activityStarter, ConfigurationController configurationController,
            TunerService tunerService, DumpManager dumpManager) {
            KeyguardStatusView keyguardStatusView, ActivityStarter activityStarter,
            ConfigurationController configurationController, TunerService tunerService,
            DumpManager dumpManager) {
        mView = keyguardSliceView;
        mKeyguardStatusView = keyguardStatusView;
        mActivityStarter = activityStarter;
        mConfigurationController = configurationController;
        mTunerService = tunerService;
@@ -127,8 +149,9 @@ public class KeyguardSliceViewController implements Dumpable {
            mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
        }
        mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
        mView.setActivityStarter(mActivityStarter);
        mView.setController(this);  // TODO: remove this.
        mView.setOnClickListener(mOnClickListener);
        // TODO: remove the line below.
        mKeyguardStatusView.setKeyguardSliceViewController(this);
    }

    /**
@@ -177,8 +200,35 @@ public class KeyguardSliceViewController implements Dumpable {
        Trace.endSection();
    }

    void showSlice(Slice slice) {
        Trace.beginSection("KeyguardSliceViewController#showSlice");
        if (slice == null) {
            mView.hideSlice();
            Trace.endSection();
            return;
        }

        ListContent lc = new ListContent(slice);
        RowContent headerContent = lc.getHeader();
        boolean hasHeader =
                headerContent != null && !headerContent.getSliceItem().hasHint(HINT_LIST_ITEM);

        List<SliceContent> subItems = lc.getRowItems().stream().filter(sliceContent -> {
            String itemUri = sliceContent.getSliceItem().getSlice().getUri().toString();
            // Filter out the action row
            return !KeyguardSliceProvider.KEYGUARD_ACTION_URI.equals(itemUri);
        }).collect(Collectors.toList());


        mClickActions = mView.showSlice(hasHeader ? headerContent : null, subItems);

        Trace.endSection();
    }


    @Override
    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
        pw.println("  mSlice: " + mSlice);
        pw.println("  mClickActions: " + mClickActions);
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import android.util.Slog;
import android.util.TypedValue;
import android.view.View;
import android.widget.GridLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.core.graphics.ColorUtils;
@@ -56,7 +55,6 @@ public class KeyguardStatusView extends GridLayout implements
    private final LockPatternUtils mLockPatternUtils;
    private final IActivityManager mIActivityManager;

    private LinearLayout mStatusViewContainer;
    private TextView mLogoutView;
    private KeyguardClockSwitch mClockView;
    private TextView mOwnerInfo;
@@ -64,6 +62,7 @@ public class KeyguardStatusView extends GridLayout implements
    private View mNotificationIcons;
    private Runnable mPendingMarqueeStart;
    private Handler mHandler;
    private KeyguardSliceViewController mKeyguardSliceViewController;

    private boolean mPulsing;
    private float mDarkAmount = 0;
@@ -179,7 +178,6 @@ public class KeyguardStatusView extends GridLayout implements
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mStatusViewContainer = findViewById(R.id.status_view_container);
        mLogoutView = findViewById(R.id.logout);
        mNotificationIcons = findViewById(R.id.clock_notification_icon_container);
        if (mLogoutView != null) {
@@ -250,7 +248,7 @@ public class KeyguardStatusView extends GridLayout implements

    public void dozeTimeTick() {
        refreshTime();
        mKeyguardSlice.refresh();
        mKeyguardSliceViewController.refresh();
    }

    private void refreshTime() {
@@ -456,4 +454,9 @@ public class KeyguardStatusView extends GridLayout implements
            Log.e(TAG, "Failed to logout user", re);
        }
    }

    // TODO: remove this method when a controller is available.
    void setKeyguardSliceViewController(KeyguardSliceViewController keyguardSliceViewController) {
        mKeyguardSliceViewController = keyguardSliceViewController;
    }
}
+15 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.keyguard;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

import android.content.Context;
@@ -28,6 +29,7 @@ import android.view.View;
import androidx.test.filters.SmallTest;

import com.android.keyguard.KeyguardDisplayManager.KeyguardPresentation;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
@@ -51,6 +53,12 @@ public class KeyguardPresentationTest extends SysuiTestCase {
    KeyguardSliceView mMockKeyguardSliceView;
    @Mock
    KeyguardStatusView mMockKeyguardStatusView;
    @Mock
    private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
    @Mock
    private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
    @Mock
    private KeyguardClockSwitchController mKeyguardClockSwitchController;

    LayoutInflater mLayoutInflater;

@@ -62,6 +70,11 @@ public class KeyguardPresentationTest extends SysuiTestCase {
        when(mMockKeyguardSliceView.getContext()).thenReturn(mContext);
        when(mMockKeyguardStatusView.getContext()).thenReturn(mContext);
        when(mMockKeyguardStatusView.findViewById(R.id.clock)).thenReturn(mMockKeyguardStatusView);
        when(mKeyguardStatusViewComponentFactory.build(any(KeyguardStatusView.class)))
                .thenReturn(mKeyguardStatusViewComponent);
        when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController())
                .thenReturn(mKeyguardClockSwitchController);

        allowTestableLooperAsMainThread();

        InjectionInflationController inflationController = new InjectionInflationController(
@@ -99,7 +112,8 @@ public class KeyguardPresentationTest extends SysuiTestCase {
    @Test
    public void testInflation_doesntCrash() {
        KeyguardPresentation keyguardPresentation = new KeyguardPresentation(mContext,
                mContext.getDisplayNoVerify(), mLayoutInflater);
                mContext.getDisplayNoVerify(), mKeyguardStatusViewComponentFactory,
                mLayoutInflater);
        keyguardPresentation.onCreate(null /*savedInstanceState */);
    }
}
Loading