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

Commit e4531a37 authored by Jason Monk's avatar Jason Monk Committed by Android (Google) Code Review
Browse files

Merge changes I151af596,Ib1ceddd7,I1cf84a09

* changes:
  QS: Don't animate first state change
  Fix QS getting stuck in weird animation during recreate
  Have QS fragment keep track of some state on recreate
parents 32f93274 2b48aa3f
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.Fragment;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -39,6 +40,8 @@ import com.android.systemui.statusbar.stack.StackStateAnimator;
public class QSFragment extends Fragment implements QS {
    private static final String TAG = "QS";
    private static final boolean DEBUG = false;
    private static final String EXTRA_EXPANDED = "expanded";
    private static final String EXTRA_LISTENING = "listening";

    private final Rect mQsBounds = new Rect();
    private boolean mQsExpanded;
@@ -85,6 +88,35 @@ public class QSFragment extends Fragment implements QS {

        mQSCustomizer = view.findViewById(R.id.qs_customize);
        mQSCustomizer.setQs(this);
        if (savedInstanceState != null) {
            setExpanded(savedInstanceState.getBoolean(EXTRA_EXPANDED));
            setListening(savedInstanceState.getBoolean(EXTRA_LISTENING));
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mListening) {
            setListening(false);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(EXTRA_EXPANDED, mQsExpanded);
        outState.putBoolean(EXTRA_LISTENING, mListening);
    }

    @VisibleForTesting
    boolean isListening() {
        return mListening;
    }

    @VisibleForTesting
    boolean isExpanded() {
        return mQsExpanded;
    }

    @Override
+4 −2
Original line number Diff line number Diff line
@@ -84,8 +84,10 @@ public class QSIconViewImpl extends QSIconView {

    protected void updateIcon(ImageView iv, State state) {
        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
            boolean shouldAnimate = iv.isShown() && mAnimationEnabled
                    && iv.getDrawable() != null;
            Drawable d = state.icon != null
                    ? iv.isShown() && mAnimationEnabled ? state.icon.getDrawable(mContext)
                    ? shouldAnimate ? state.icon.getDrawable(mContext)
                    : state.icon.getInvisibleDrawable(mContext) : null;
            int padding = state.icon != null ? state.icon.getPadding() : 0;
            if (d != null) {
@@ -114,7 +116,7 @@ public class QSIconViewImpl extends QSIconView {
        if (state.state != mState) {
            int color = getColor(state.state);
            mState = state.state;
            if (iv.isShown()) {
            if (iv.isShown() && mTint != 0) {
                animateGrayScale(mTint, color, iv);
                mTint = color;
            } else {
+23 −0
Original line number Diff line number Diff line
@@ -15,8 +15,11 @@
package com.android.systemui.qs;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;

import android.app.FragmentController;
import android.app.FragmentManagerNonConfig;
import android.os.Looper;

import com.android.internal.logging.MetricsLogger;
@@ -24,6 +27,7 @@ import com.android.keyguard.CarrierText;
import com.android.systemui.Dependency;
import com.android.systemui.R;

import android.os.Parcelable;
import android.testing.AndroidTestingRunner;

import com.android.systemui.SysuiBaseFragmentTest;
@@ -90,4 +94,23 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
        host.destroy();
        processAllMessages();
    }

    @Test
    public void testSaveState() {
        QSFragment qs = (QSFragment) mFragment;

        mFragments.dispatchResume();
        processAllMessages();

        qs.setListening(true);
        qs.setExpanded(true);
        processAllMessages();
        recreateFragment();
        processAllMessages();

        // Get the reference to the new fragment.
        qs = (QSFragment) mFragment;
        assertTrue(qs.isListening());
        assertTrue(qs.isExpanded());
    }
}
+83 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.qs.tileimpl;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.service.quicksettings.Tile;
import android.testing.AndroidTestingRunner;
import android.testing.UiThreadTest;
import android.widget.ImageView;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.qs.QSTile.Icon;
import com.android.systemui.plugins.qs.QSTile.State;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;

@RunWith(AndroidTestingRunner.class)
@UiThreadTest
public class QSIconViewImplTest extends SysuiTestCase {

    private QSIconViewImpl mIconView;

    @Before
    public void setup() {
        mIconView = new QSIconViewImpl(mContext);
    }

    @Test
    public void testNoFirstAnimation() {
        ImageView iv = mock(ImageView.class);
        State s = new State();
        when(iv.isShown()).thenReturn(true);

        // No current icon, only the static drawable should be used.
        s.icon = mock(Icon.class);
        when(iv.getDrawable()).thenReturn(null);
        mIconView.updateIcon(iv, s);
        verify(s.icon, never()).getDrawable(any());
        verify(s.icon).getInvisibleDrawable(any());

        // Has icon, should use the standard (animated) form.
        s.icon = mock(Icon.class);
        when(iv.getDrawable()).thenReturn(mock(Drawable.class));
        mIconView.updateIcon(iv, s);
        verify(s.icon).getDrawable(any());
        verify(s.icon, never()).getInvisibleDrawable(any());
    }

    @Test
    public void testNoFirstFade() {
        ImageView iv = mock(ImageView.class);
        State s = new State();
        s.state = Tile.STATE_ACTIVE;
        int desiredColor = mIconView.getColor(s.state);
        when(iv.isShown()).thenReturn(true);

        mIconView.setIcon(iv, s);
        verify(iv).setImageTintList(argThat(stateList -> stateList.getColors()[0] == desiredColor));
    }
}
+13 −8
Original line number Diff line number Diff line
@@ -133,14 +133,7 @@ public abstract class BaseFragmentTest {
    public void testRecreate() {
        mFragments.dispatchResume();
        processAllMessages();
        mFragments.dispatchPause();
        Parcelable p = mFragments.saveAllState();
        mFragments.dispatchDestroy();

        mFragments = FragmentController.createController(new HostCallbacks());
        mFragments.attachHost(null);
        mFragments.restoreAllState(p, (FragmentManagerNonConfig) null);
        mFragments.dispatchResume();
        recreateFragment();
        processAllMessages();
    }

@@ -154,6 +147,18 @@ public abstract class BaseFragmentTest {
        processAllMessages();
    }

    protected void recreateFragment() {
        mFragments.dispatchPause();
        Parcelable p = mFragments.saveAllState();
        mFragments.dispatchDestroy();

        mFragments = FragmentController.createController(new HostCallbacks());
        mFragments.attachHost(null);
        mFragments.restoreAllState(p, (FragmentManagerNonConfig) null);
        mFragments.dispatchResume();
        mFragment = mFragments.getFragmentManager().findFragmentById(VIEW_ID);
    }

    protected void attachFragmentToWindow() {
        ViewUtils.attachView(mView);
        TestableLooper.get(this).processMessages(1);