Snap for 5165440 from 4e681c1586 to qt-release
Change-Id: Ic93c1ae3e05d6e822360bcc2069c689df0b2e094
This commit is contained in:
@@ -69,6 +69,7 @@
|
||||
<uses-permission android:name="android.permission.READ_PROFILE" />
|
||||
<uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" />
|
||||
<uses-permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_MODE" />
|
||||
<uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
|
||||
<uses-permission android:name="android.permission.SET_TIME" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.REBOOT" />
|
||||
|
||||
@@ -172,8 +172,9 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
dialog.show(getSupportFragmentManager(), ConfigureKeyGuardDialog.TAG);
|
||||
return;
|
||||
}
|
||||
installIfAvailable();
|
||||
finish();
|
||||
if (installIfAvailable()) {
|
||||
finish();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -217,10 +218,13 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
|
||||
/**
|
||||
* Install credentials if available, otherwise do nothing.
|
||||
*
|
||||
* @return true if the installation is done and the activity should be finished, false if
|
||||
* an asynchronous task is pending and will finish the activity when it's done.
|
||||
*/
|
||||
private void installIfAvailable() {
|
||||
private boolean installIfAvailable() {
|
||||
if (mInstallBundle == null || mInstallBundle.isEmpty()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
final Bundle bundle = mInstallBundle;
|
||||
@@ -235,16 +239,17 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
if (uid != Process.WIFI_UID) {
|
||||
Log.e(TAG, "Failed to install credentials as uid " + uid + ": cross-user installs"
|
||||
+ " may only target wifi uids");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
final Intent installIntent = new Intent(ACTION_INSTALL)
|
||||
.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
|
||||
.putExtras(bundle);
|
||||
startActivityAsUser(installIntent, new UserHandle(dstUserId));
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean shouldFinish = true;
|
||||
if (bundle.containsKey(Credentials.EXTRA_USER_PRIVATE_KEY_NAME)) {
|
||||
final String key = bundle.getString(Credentials.EXTRA_USER_PRIVATE_KEY_NAME);
|
||||
final byte[] value = bundle.getByteArray(Credentials.EXTRA_USER_PRIVATE_KEY_DATA);
|
||||
@@ -259,7 +264,7 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
|
||||
if (!mKeyStore.importKey(key, value, uid, flags)) {
|
||||
Log.e(TAG, "Failed to install " + key + " as uid " + uid);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
// The key was prepended USER_PRIVATE_KEY by the CredentialHelper. However,
|
||||
// KeyChain internally uses the raw alias name and only prepends USER_PRIVATE_KEY
|
||||
@@ -270,6 +275,7 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
if (uid == Process.SYSTEM_UID || uid == KeyStore.UID_SELF) {
|
||||
new MarkKeyAsUserSelectable(
|
||||
key.replaceFirst("^" + Credentials.USER_PRIVATE_KEY, "")).execute();
|
||||
shouldFinish = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +287,7 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
|
||||
if (!mKeyStore.put(certName, certData, uid, flags)) {
|
||||
Log.e(TAG, "Failed to install " + certName + " as uid " + uid);
|
||||
return;
|
||||
return shouldFinish;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +297,7 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
|
||||
if (!mKeyStore.put(caListName, caListData, uid, flags)) {
|
||||
Log.e(TAG, "Failed to install " + caListName + " as uid " + uid);
|
||||
return;
|
||||
return shouldFinish;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +306,7 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
sendBroadcast(broadcast);
|
||||
|
||||
setResult(RESULT_OK);
|
||||
return shouldFinish;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -411,6 +418,13 @@ public final class CredentialStorage extends FragmentActivity {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
Log.i(TAG, String.format("Marked alias %s as selectable, success? %s",
|
||||
mAlias, result));
|
||||
CredentialStorage.this.finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,11 +14,7 @@
|
||||
package com.android.settings.display;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
import android.hardware.display.ColorDisplayManager;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
@@ -29,19 +25,16 @@ import com.android.settings.core.BasePreferenceController;
|
||||
public class ColorModePreferenceController extends BasePreferenceController {
|
||||
private static final String TAG = "ColorModePreference";
|
||||
|
||||
private static final int SURFACE_FLINGER_TRANSACTION_QUERY_COLOR_MANAGEMENT = 1030;
|
||||
|
||||
private final ConfigurationWrapper mConfigWrapper;
|
||||
private ColorDisplayController mColorDisplayController;
|
||||
|
||||
public ColorModePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mConfigWrapper = new ConfigurationWrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return mConfigWrapper.isDeviceColorManaged()
|
||||
return mContext.getSystemService(ColorDisplayManager.class)
|
||||
.isDeviceColorManaged()
|
||||
&& !getColorDisplayController().getAccessibilityTransformActivated() ?
|
||||
AVAILABLE_UNSEARCHABLE : DISABLED_FOR_USER;
|
||||
}
|
||||
@@ -68,32 +61,4 @@ public class ColorModePreferenceController extends BasePreferenceController {
|
||||
}
|
||||
return mColorDisplayController;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class ConfigurationWrapper {
|
||||
private final IBinder mSurfaceFlinger;
|
||||
|
||||
ConfigurationWrapper() {
|
||||
mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger");
|
||||
}
|
||||
|
||||
boolean isDeviceColorManaged() {
|
||||
if (mSurfaceFlinger != null) {
|
||||
final Parcel data = Parcel.obtain();
|
||||
final Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken("android.ui.ISurfaceComposer");
|
||||
try {
|
||||
mSurfaceFlinger.transact(SURFACE_FLINGER_TRANSACTION_QUERY_COLOR_MANAGEMENT,
|
||||
data, reply, 0);
|
||||
return reply.readBoolean();
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Failed to query color management support", ex);
|
||||
} finally {
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.settings.display;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import android.hardware.display.ColorDisplayManager;
|
||||
|
||||
import androidx.preference.DropDownPreference;
|
||||
|
||||
@@ -69,9 +69,9 @@ public class SliceContextualCardController implements ContextualCardController {
|
||||
dbHelper.markContextualCardAsDismissed(mContext, card.getName());
|
||||
});
|
||||
showFeedbackDialog(card);
|
||||
final ContextualCardFeatureProvider contexualCardFeatureProvider =
|
||||
final ContextualCardFeatureProvider contextualCardFeatureProvider =
|
||||
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
|
||||
contexualCardFeatureProvider.logContextualCardDismiss(mContext, card);
|
||||
contextualCardFeatureProvider.logContextualCardDismiss(mContext, card);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,8 +28,11 @@ import android.widget.ViewFlipper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceItem;
|
||||
@@ -51,13 +54,15 @@ import java.util.Set;
|
||||
* Card renderer for {@link ContextualCard} built as slices.
|
||||
*/
|
||||
public class SliceContextualCardRenderer implements ContextualCardRenderer,
|
||||
SliceView.OnSliceActionListener {
|
||||
SliceView.OnSliceActionListener, LifecycleObserver {
|
||||
public static final int VIEW_TYPE = R.layout.homepage_slice_tile;
|
||||
|
||||
private static final String TAG = "SliceCardRenderer";
|
||||
|
||||
@VisibleForTesting
|
||||
final Map<String, LiveData<Slice>> mSliceLiveDataMap;
|
||||
@VisibleForTesting
|
||||
final Set<SliceViewHolder> mFlippedCardSet;
|
||||
|
||||
private final Context mContext;
|
||||
private final LifecycleOwner mLifecycleOwner;
|
||||
@@ -71,6 +76,8 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
|
||||
mSliceLiveDataMap = new ArrayMap<>();
|
||||
mControllerRendererPool = controllerRendererPool;
|
||||
mCardSet = new ArraySet<>();
|
||||
mFlippedCardSet = new ArraySet<>();
|
||||
mLifecycleOwner.getLifecycle().addObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,20 +129,23 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
|
||||
}
|
||||
|
||||
private void initDismissalActions(SliceViewHolder cardHolder, ContextualCard card) {
|
||||
final ViewFlipper viewFlipper = cardHolder.itemView.findViewById(R.id.viewFlipper);
|
||||
cardHolder.sliceView.setOnLongClickListener(v -> {
|
||||
viewFlipper.showNext();
|
||||
cardHolder.viewFlipper.showNext();
|
||||
mFlippedCardSet.add(cardHolder);
|
||||
return true;
|
||||
});
|
||||
|
||||
final Button btnKeep = cardHolder.itemView.findViewById(R.id.keep);
|
||||
btnKeep.setOnClickListener(v -> {
|
||||
viewFlipper.showPrevious();
|
||||
cardHolder.resetCard();
|
||||
mFlippedCardSet.remove(cardHolder);
|
||||
});
|
||||
|
||||
final Button btnRemove = cardHolder.itemView.findViewById(R.id.remove);
|
||||
btnRemove.setOnClickListener(v -> {
|
||||
mControllerRendererPool.getController(mContext, card.getCardType()).onDismissed(card);
|
||||
cardHolder.resetCard();
|
||||
mFlippedCardSet.remove(cardHolder);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -158,12 +168,24 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
|
||||
}
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
|
||||
public void onStop() {
|
||||
mFlippedCardSet.stream().forEach(holder -> holder.resetCard());
|
||||
mFlippedCardSet.clear();
|
||||
}
|
||||
|
||||
public static class SliceViewHolder extends RecyclerView.ViewHolder {
|
||||
public final SliceView sliceView;
|
||||
public final ViewFlipper viewFlipper;
|
||||
|
||||
public SliceViewHolder(View view) {
|
||||
super(view);
|
||||
sliceView = view.findViewById(R.id.slice_view);
|
||||
viewFlipper = view.findViewById(R.id.viewFlipper);
|
||||
}
|
||||
|
||||
public void resetCard() {
|
||||
viewFlipper.setDisplayedChild(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.homepage.contextualcards.slices;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.Activity;
|
||||
@@ -51,10 +52,14 @@ import org.robolectric.android.controller.ActivityController;
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class SliceContextualCardRendererTest {
|
||||
|
||||
private static final String TEST_SLICE_URI = "content://test/test";
|
||||
|
||||
@Mock
|
||||
private LiveData<Slice> mSliceLiveData;
|
||||
@Mock
|
||||
private ControllerRendererPool mControllerRendererPool;
|
||||
@Mock
|
||||
private SliceContextualCardController mController;
|
||||
|
||||
private Activity mActivity;
|
||||
private SliceContextualCardRenderer mRenderer;
|
||||
@@ -75,10 +80,9 @@ public class SliceContextualCardRendererTest {
|
||||
|
||||
@Test
|
||||
public void bindView_shouldSetScrollableToFalse() {
|
||||
final String sliceUri = "content://com.android.settings.slices/action/flashlight";
|
||||
RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
|
||||
|
||||
mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
|
||||
mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
|
||||
|
||||
assertThat(
|
||||
((SliceContextualCardRenderer.SliceViewHolder) viewHolder).sliceView.isScrollable
|
||||
@@ -99,64 +103,107 @@ public class SliceContextualCardRendererTest {
|
||||
|
||||
@Test
|
||||
public void bindView_newSliceLiveData_shouldAddDataToMap() {
|
||||
final String sliceUri = "content://com.android.settings.slices/action/flashlight";
|
||||
|
||||
mRenderer.bindView(getSliceViewHolder(), buildContextualCard(sliceUri));
|
||||
mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
|
||||
|
||||
assertThat(mRenderer.mSliceLiveDataMap.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindView_sliceLiveDataShouldObserveSliceView() {
|
||||
final String sliceUri = "content://com.android.settings.slices/action/flashlight";
|
||||
mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
|
||||
|
||||
mRenderer.bindView(getSliceViewHolder(), buildContextualCard(sliceUri));
|
||||
|
||||
assertThat(mRenderer.mSliceLiveDataMap.get(sliceUri).hasObservers()).isTrue();
|
||||
assertThat(mRenderer.mSliceLiveDataMap.get(TEST_SLICE_URI).hasObservers()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindView_sliceLiveDataShouldRemoveObservers() {
|
||||
final String sliceUri = "content://com.android.settings.slices/action/flashlight";
|
||||
mRenderer.mSliceLiveDataMap.put(sliceUri, mSliceLiveData);
|
||||
mRenderer.mSliceLiveDataMap.put(TEST_SLICE_URI, mSliceLiveData);
|
||||
|
||||
mRenderer.bindView(getSliceViewHolder(), buildContextualCard(sliceUri));
|
||||
mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
|
||||
|
||||
verify(mSliceLiveData).removeObservers(mLifecycleOwner);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longClick_shouldFlipCard() {
|
||||
final String sliceUri = "content://com.android.settings.slices/action/flashlight";
|
||||
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
|
||||
final View card = viewHolder.itemView.findViewById(R.id.slice_view);
|
||||
final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.viewFlipper);
|
||||
final View dismissalView = viewHolder.itemView.findViewById(R.id.dismissal_view);
|
||||
mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
|
||||
mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
|
||||
|
||||
assertThat(card).isNotNull();
|
||||
card.performLongClick();
|
||||
|
||||
assertThat(viewFlipper.getCurrentView()).isEqualTo(dismissalView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longClick_shouldAddViewHolderToSet() {
|
||||
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
|
||||
final View card = viewHolder.itemView.findViewById(R.id.slice_view);
|
||||
mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
|
||||
|
||||
card.performLongClick();
|
||||
|
||||
assertThat(mRenderer.mFlippedCardSet).contains(viewHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void viewClick_keepCard_shouldFlipBackToSlice() {
|
||||
final String sliceUri = "content://com.android.settings.slices/action/flashlight";
|
||||
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
|
||||
final View card = viewHolder.itemView.findViewById(R.id.slice_view);
|
||||
final Button btnKeep = viewHolder.itemView.findViewById(R.id.keep);
|
||||
final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.viewFlipper);
|
||||
mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
|
||||
mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
|
||||
|
||||
assertThat(card).isNotNull();
|
||||
card.performLongClick();
|
||||
assertThat(btnKeep).isNotNull();
|
||||
btnKeep.performClick();
|
||||
|
||||
assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void viewClick_keepCard_shouldRemoveViewHolderFromSet() {
|
||||
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
|
||||
final View card = viewHolder.itemView.findViewById(R.id.slice_view);
|
||||
final Button btnKeep = viewHolder.itemView.findViewById(R.id.keep);
|
||||
mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
|
||||
|
||||
card.performLongClick();
|
||||
btnKeep.performClick();
|
||||
|
||||
assertThat(mRenderer.mFlippedCardSet).doesNotContain(viewHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void viewClick_removeCard_shouldRemoveViewHolderFromSet() {
|
||||
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
|
||||
final View card = viewHolder.itemView.findViewById(R.id.slice_view);
|
||||
final Button btnRemove = viewHolder.itemView.findViewById(R.id.remove);
|
||||
final ContextualCard contextualCard = buildContextualCard(TEST_SLICE_URI);
|
||||
mRenderer.bindView(viewHolder, contextualCard);
|
||||
doReturn(mController).when(mControllerRendererPool).getController(mActivity,
|
||||
ContextualCard.CardType.SLICE);
|
||||
|
||||
card.performLongClick();
|
||||
btnRemove.performClick();
|
||||
|
||||
assertThat(mRenderer.mFlippedCardSet).doesNotContain(viewHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_cardIsFlipped_shouldFlipBack() {
|
||||
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
|
||||
final View card = viewHolder.itemView.findViewById(R.id.slice_view);
|
||||
final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.viewFlipper);
|
||||
mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
|
||||
|
||||
card.performLongClick();
|
||||
mRenderer.onStop();
|
||||
|
||||
assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
|
||||
}
|
||||
|
||||
private RecyclerView.ViewHolder getSliceViewHolder() {
|
||||
final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
|
||||
final RecyclerView recyclerView = new RecyclerView(mActivity);
|
||||
@@ -169,6 +216,7 @@ public class SliceContextualCardRendererTest {
|
||||
private ContextualCard buildContextualCard(String sliceUri) {
|
||||
return new ContextualCard.Builder()
|
||||
.setName("test_name")
|
||||
.setCardType(ContextualCard.CardType.SLICE)
|
||||
.setSliceUri(Uri.parse(sliceUri))
|
||||
.build();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user