Make conditional work properly when toggle it in QS

Some conditionals do not work properly when users toggle its state in
QS, the cause is that these conditionals don't have a way to monitor the
status changed. Make RecyclerView handle onWindowFocusChanged event and
make sure that conditionals can update the status when going back to
Settings from QS.

Bug: 118387886
Bug: 123171638
Bug: 123167705
Test: visual, robotests
Change-Id: Ib3bb9bf43afaa58726502eea1e98bcf602bc3677
This commit is contained in:
Mill Chen
2019-03-19 18:56:11 -07:00
parent 2f8e02fdbe
commit bd10886288
4 changed files with 63 additions and 5 deletions

View File

@@ -21,7 +21,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView <com.android.settings.homepage.contextualcards.FocusRecyclerView
android:id="@+id/card_container" android:id="@+id/card_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View File

@@ -43,6 +43,8 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -98,7 +100,6 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
mLifecycleObservers = new ArrayList<>(); mLifecycleObservers = new ArrayList<>();
mControllerRendererPool = new ControllerRendererPool(); mControllerRendererPool = new ControllerRendererPool();
mLifecycle.addObserver(this); mLifecycle.addObserver(this);
if (savedInstanceState == null) { if (savedInstanceState == null) {
mIsFirstLaunch = true; mIsFirstLaunch = true;
mSavedCards = null; mSavedCards = null;
@@ -240,6 +241,21 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
outState.putStringArrayList(KEY_CONTEXTUAL_CARDS, cards); outState.putStringArrayList(KEY_CONTEXTUAL_CARDS, cards);
} }
public void onWindowFocusChanged(boolean hasWindowFocus) {
// Duplicate a list to avoid java.util.ConcurrentModificationException.
final List<ContextualCard> cards = new ArrayList<>(mContextualCards);
for (ContextualCard card : cards) {
final ContextualCardController controller = mControllerRendererPool
.getController(mContext, card.getCardType());
if (hasWindowFocus && controller instanceof OnStart) {
((OnStart) controller).onStart();
}
if (!hasWindowFocus && controller instanceof OnStop) {
((OnStop) controller).onStop();
}
}
}
public ControllerRendererPool getControllerRendererPool() { public ControllerRendererPool getControllerRendererPool() {
return mControllerRendererPool; return mControllerRendererPool;
} }

View File

@@ -27,17 +27,17 @@ import android.view.ViewGroup;
import androidx.loader.app.LoaderManager; import androidx.loader.app.LoaderManager;
import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.InstrumentedFragment;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
public class ContextualCardsFragment extends InstrumentedFragment { public class ContextualCardsFragment extends InstrumentedFragment implements
FocusRecyclerView.FocusListener {
private static final String TAG = "ContextualCardsFragment"; private static final String TAG = "ContextualCardsFragment";
private RecyclerView mCardsContainer; private FocusRecyclerView mCardsContainer;
private GridLayoutManager mLayoutManager; private GridLayoutManager mLayoutManager;
private ContextualCardsAdapter mContextualCardsAdapter; private ContextualCardsAdapter mContextualCardsAdapter;
private ContextualCardManager mContextualCardManager; private ContextualCardManager mContextualCardManager;
@@ -72,10 +72,16 @@ public class ContextualCardsFragment extends InstrumentedFragment {
this /* lifecycleOwner */, mContextualCardManager); this /* lifecycleOwner */, mContextualCardManager);
mCardsContainer.setAdapter(mContextualCardsAdapter); mCardsContainer.setAdapter(mContextualCardsAdapter);
mContextualCardManager.setListener(mContextualCardsAdapter); mContextualCardManager.setListener(mContextualCardsAdapter);
mCardsContainer.setListener(this);
return rootView; return rootView;
} }
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
mContextualCardManager.onWindowFocusChanged(hasWindowFocus);
}
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return SettingsEnums.SETTINGS_HOMEPAGE; return SettingsEnums.SETTINGS_HOMEPAGE;

View File

@@ -0,0 +1,36 @@
package com.android.settings.homepage.contextualcards;
import android.content.Context;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
public class FocusRecyclerView extends RecyclerView {
private FocusListener mListener;
public FocusRecyclerView(Context context) {
super(context);
}
public FocusRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (mListener != null) {
mListener.onWindowFocusChanged(hasWindowFocus);
}
}
public void setListener(FocusListener listener) {
mListener = listener;
}
public interface FocusListener {
void onWindowFocusChanged(boolean hasWindowFocus);
}
}