Snap for 7938361 from a88ab65024 to tm-release
Change-Id: Id125601d3c27df75abd0a38ce0df17d0d835c8ae
This commit is contained in:
41
res/layout/search_bar_two_pane_version.xml
Normal file
41
res/layout/search_bar_two_pane_version.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SearchBarStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_margin="@dimen/search_bar_margin">
|
||||
<Toolbar
|
||||
android:id="@+id/search_action_bar_two_pane"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/search_bar_height"
|
||||
android:paddingStart="4dp"
|
||||
android:background="@drawable/search_bar_selected_background"
|
||||
android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
|
||||
android:navigationIcon="@drawable/ic_homepage_search">
|
||||
<TextView
|
||||
style="@style/TextAppearance.SearchBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="-4dp"
|
||||
android:layout_gravity="start"
|
||||
android:text="@string/search_menu"/>
|
||||
</Toolbar>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/account_avatar"
|
||||
android:layout_width="@dimen/avatar_length"
|
||||
android:layout_height="@dimen/avatar_length"
|
||||
android:layout_marginTop="@dimen/avatar_margin_top"
|
||||
android:layout_marginEnd="@dimen/avatar_margin_end"
|
||||
android:layout_gravity="end"
|
||||
android:visibility="invisible"
|
||||
android:accessibilityTraversalAfter="@id/homepage_title"
|
||||
android:contentDescription="@string/search_bar_account_avatar_content_description"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/homepage_title"
|
||||
android:text="@string/settings_label"
|
||||
style="@style/HomepageTitleText"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/suggestion_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include layout="@layout/search_bar"/>
|
||||
|
||||
</LinearLayout>
|
||||
46
res/layout/settings_homepage_app_bar_two_pane_layout.xml
Normal file
46
res/layout/settings_homepage_app_bar_two_pane_layout.xml
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/two_pane_suggestion_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<include layout="@layout/search_bar_two_pane_version"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/account_avatar_two_pane_version"
|
||||
android:layout_width="@dimen/avatar_length"
|
||||
android:layout_height="@dimen/avatar_length"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:contentDescription="@string/search_bar_account_avatar_content_description"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -65,29 +65,14 @@
|
||||
android:orientation="vertical"
|
||||
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/account_avatar"
|
||||
android:layout_width="@dimen/avatar_length"
|
||||
android:layout_height="@dimen/avatar_length"
|
||||
android:layout_marginTop="@dimen/avatar_margin_top"
|
||||
android:layout_marginEnd="@dimen/avatar_margin_end"
|
||||
android:layout_gravity="end"
|
||||
android:visibility="invisible"
|
||||
android:accessibilityTraversalAfter="@id/homepage_title"
|
||||
android:contentDescription="@string/search_bar_account_avatar_content_description"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/homepage_title"
|
||||
android:text="@string/settings_label"
|
||||
style="@style/HomepageTitleText"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/suggestion_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include layout="@layout/search_bar"/>
|
||||
<include
|
||||
android:id="@+id/homepage_app_bar_regular_phone_view"
|
||||
layout="@layout/settings_homepage_app_bar_regular_phone_layout"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/homepage_app_bar_two_pane_view"
|
||||
layout="@layout/settings_homepage_app_bar_two_pane_layout"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
@@ -5344,7 +5344,7 @@
|
||||
<!-- Title for the accessibility tutorial dialog in accessibility service with gesture. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_tutorial_dialog_title_gesture">Use gesture to open</string>
|
||||
<!-- Title for the accessibility tutorial dialog in gesture navigation settings. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_tutorial_dialog_title_gesture_settings">Use new accessibility gesture</string>
|
||||
<string name="accessibility_tutorial_dialog_title_gesture_settings">Use accessibility gesture</string>
|
||||
<!-- Message for the accessibility tutorial dialog when user enables an accessibility service while using the 3-button nav bar. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_tutorial_dialog_message_button">To use this feature, tap the accessibility button <xliff:g id="accessibility_icon" example="[Icon]">%s</xliff:g> on the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button.</string>
|
||||
<!-- Message for the accessibility tutorial dialog when user enables an accessibility service while using the accessibility floating button. [CHAR LIMIT=100] -->
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.app.ActivityManager;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
@@ -77,8 +78,11 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
private TopLevelSettings mMainFragment;
|
||||
private View mHomepageView;
|
||||
private View mSuggestionView;
|
||||
private View mTwoPaneSuggestionView;
|
||||
private CategoryMixin mCategoryMixin;
|
||||
private Set<HomepageLoadedListener> mLoadedListeners;
|
||||
private boolean mIsEmbeddingActivityEnabled;
|
||||
private boolean mIsTwoPaneLastTime;
|
||||
|
||||
/** A listener receiving homepage loaded events. */
|
||||
public interface HomepageLoadedListener {
|
||||
@@ -113,7 +117,11 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
}
|
||||
Log.i(TAG, "showHomepageWithSuggestion: " + showSuggestion);
|
||||
final View homepageView = mHomepageView;
|
||||
if (!mIsTwoPaneLastTime) {
|
||||
mSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
|
||||
} else {
|
||||
mTwoPaneSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
mHomepageView = null;
|
||||
|
||||
mLoadedListeners.forEach(listener -> listener.onHomepageLoaded());
|
||||
@@ -135,30 +143,25 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.settings_homepage_container);
|
||||
mIsEmbeddingActivityEnabled = ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this);
|
||||
mIsTwoPaneLastTime = ActivityEmbeddingUtils.isTwoPaneResolution(this);
|
||||
|
||||
final View appBar = findViewById(R.id.app_bar_container);
|
||||
appBar.setMinimumHeight(getSearchBoxHeight());
|
||||
initHomepageContainer();
|
||||
updateHomepageAppBar();
|
||||
mLoadedListeners = new ArraySet<>();
|
||||
|
||||
final Toolbar toolbar = findViewById(R.id.search_action_bar);
|
||||
FeatureFactory.getFactory(this).getSearchFeatureProvider()
|
||||
.initSearchToolbar(this /* activity */, toolbar, SettingsEnums.SETTINGS_HOMEPAGE);
|
||||
initSearchBarView();
|
||||
|
||||
getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
|
||||
mCategoryMixin = new CategoryMixin(this);
|
||||
getLifecycle().addObserver(mCategoryMixin);
|
||||
|
||||
if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
|
||||
// Only allow features on high ram devices.
|
||||
final ImageView avatarView = findViewById(R.id.account_avatar);
|
||||
if (AvatarViewMixin.isAvatarSupported(this)) {
|
||||
avatarView.setVisibility(View.VISIBLE);
|
||||
getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
|
||||
}
|
||||
|
||||
if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
|
||||
initAvatarView();
|
||||
showSuggestionFragment();
|
||||
|
||||
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.CONTEXTUAL_HOME)) {
|
||||
showFragment(new ContextualCardsFragment(), R.id.contextual_cards_content);
|
||||
}
|
||||
@@ -196,6 +199,43 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
launchDeepLinkIntentToRight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
final boolean isTwoPane = ActivityEmbeddingUtils.isTwoPaneResolution(this);
|
||||
if (mIsTwoPaneLastTime != isTwoPane) {
|
||||
mIsTwoPaneLastTime = isTwoPane;
|
||||
updateHomepageAppBar();
|
||||
}
|
||||
}
|
||||
|
||||
private void initSearchBarView() {
|
||||
final Toolbar toolbar = findViewById(R.id.search_action_bar);
|
||||
FeatureFactory.getFactory(this).getSearchFeatureProvider()
|
||||
.initSearchToolbar(this /* activity */, toolbar, SettingsEnums.SETTINGS_HOMEPAGE);
|
||||
|
||||
if (mIsEmbeddingActivityEnabled) {
|
||||
final Toolbar toolbarTwoPaneVersion = findViewById(R.id.search_action_bar_two_pane);
|
||||
FeatureFactory.getFactory(this).getSearchFeatureProvider()
|
||||
.initSearchToolbar(this /* activity */, toolbarTwoPaneVersion,
|
||||
SettingsEnums.SETTINGS_HOMEPAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void initAvatarView() {
|
||||
final ImageView avatarView = findViewById(R.id.account_avatar);
|
||||
final ImageView avatarTwoPaneView = findViewById(R.id.account_avatar_two_pane_version);
|
||||
if (AvatarViewMixin.isAvatarSupported(this)) {
|
||||
avatarView.setVisibility(View.VISIBLE);
|
||||
getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
|
||||
|
||||
if (mIsEmbeddingActivityEnabled) {
|
||||
avatarTwoPaneView.setVisibility(View.VISIBLE);
|
||||
getLifecycle().addObserver(new AvatarViewMixin(this, avatarTwoPaneView));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showSuggestionFragment() {
|
||||
final Class<? extends Fragment> fragment = FeatureFactory.getFactory(this)
|
||||
.getSuggestionFeatureProvider(this).getContextualSuggestionFragment();
|
||||
@@ -204,6 +244,7 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
}
|
||||
|
||||
mSuggestionView = findViewById(R.id.suggestion_content);
|
||||
mTwoPaneSuggestionView = findViewById(R.id.two_pane_suggestion_content);
|
||||
mHomepageView = findViewById(R.id.settings_homepage_container);
|
||||
// Hide the homepage for preparing the suggestion.
|
||||
mHomepageView.setVisibility(View.INVISIBLE);
|
||||
@@ -212,6 +253,10 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
HOMEPAGE_LOADING_TIMEOUT_MS);
|
||||
try {
|
||||
showFragment(fragment.getConstructor().newInstance(), R.id.suggestion_content);
|
||||
if (mIsEmbeddingActivityEnabled) {
|
||||
showFragment(fragment.getConstructor().newInstance(),
|
||||
R.id.two_pane_suggestion_content);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Cannot show fragment", e);
|
||||
}
|
||||
@@ -332,6 +377,19 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
view.requestFocus();
|
||||
}
|
||||
|
||||
private void updateHomepageAppBar() {
|
||||
if (!mIsEmbeddingActivityEnabled) {
|
||||
return;
|
||||
}
|
||||
if (ActivityEmbeddingUtils.isTwoPaneResolution(this)) {
|
||||
findViewById(R.id.homepage_app_bar_regular_phone_view).setVisibility(View.GONE);
|
||||
findViewById(R.id.homepage_app_bar_two_pane_view).setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
findViewById(R.id.homepage_app_bar_regular_phone_view).setVisibility(View.VISIBLE);
|
||||
findViewById(R.id.homepage_app_bar_two_pane_view).setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private int getSearchBoxHeight() {
|
||||
final int searchBarHeight = getResources().getDimensionPixelSize(R.dimen.search_bar_height);
|
||||
final int searchBarMargin = getResources().getDimensionPixelSize(R.dimen.search_bar_margin);
|
||||
|
||||
@@ -17,14 +17,16 @@ package com.android.settings.network.helper;
|
||||
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.UiccPortInfo;
|
||||
import android.telephony.UiccSlotInfo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* This is a Callable class which query slot index within device
|
||||
* This is a Callable class which query logical slot index within device
|
||||
*/
|
||||
public class QuerySimSlotIndex implements Callable<AtomicIntegerArray> {
|
||||
private static final String TAG = "QuerySimSlotIndex";
|
||||
@@ -58,30 +60,32 @@ public class QuerySimSlotIndex implements Callable<AtomicIntegerArray> {
|
||||
return new AtomicIntegerArray(0);
|
||||
}
|
||||
int slotIndexFilter = mOnlySlotWithSim ? 0 : SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
|
||||
return new AtomicIntegerArray(Arrays.stream(slotInfo)
|
||||
.filter(slot -> filterSlot(slot))
|
||||
.mapToInt(slot -> mapToSlotIndex(slot))
|
||||
.flatMapToInt(slot -> mapToLogicalSlotIndex(slot))
|
||||
.filter(slotIndex -> (slotIndex >= slotIndexFilter))
|
||||
.toArray());
|
||||
}
|
||||
|
||||
protected boolean filterSlot(UiccSlotInfo slotInfo) {
|
||||
protected IntStream mapToLogicalSlotIndex(UiccSlotInfo slotInfo) {
|
||||
if (slotInfo == null) {
|
||||
return IntStream.of(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
|
||||
}
|
||||
if (slotInfo.getCardStateInfo() == UiccSlotInfo.CARD_STATE_INFO_ABSENT) {
|
||||
return IntStream.of(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
|
||||
}
|
||||
return slotInfo.getPorts().stream()
|
||||
.filter(port -> filterPort(port))
|
||||
.mapToInt(port -> port.getLogicalSlotIndex());
|
||||
}
|
||||
|
||||
protected boolean filterPort(UiccPortInfo uiccPortInfo) {
|
||||
if (mDisabledSlotsIncluded) {
|
||||
return true;
|
||||
}
|
||||
if (slotInfo == null) {
|
||||
if (uiccPortInfo == null) {
|
||||
return false;
|
||||
}
|
||||
return slotInfo.getIsActive();
|
||||
}
|
||||
|
||||
protected int mapToSlotIndex(UiccSlotInfo slotInfo) {
|
||||
if (slotInfo == null) {
|
||||
return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
}
|
||||
if (slotInfo.getCardStateInfo() == UiccSlotInfo.CARD_STATE_INFO_ABSENT) {
|
||||
return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
}
|
||||
return slotInfo.getLogicalSlotIdx();
|
||||
return uiccPortInfo.isActive();
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -127,7 +128,10 @@ public class NfcPaymentPreferenceController extends BasePreferenceController imp
|
||||
public CharSequence getSummary() {
|
||||
final PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp();
|
||||
if (defaultApp != null) {
|
||||
return defaultApp.label;
|
||||
UserManager um = mContext.createContextAsUser(
|
||||
defaultApp.userHandle, /*flags=*/0).getSystemService(UserManager.class);
|
||||
|
||||
return defaultApp.label + " (" + um.getUserName() + ")";
|
||||
} else {
|
||||
return mContext.getText(R.string.nfc_payment_default_not_set);
|
||||
}
|
||||
@@ -218,12 +222,15 @@ public class NfcPaymentPreferenceController extends BasePreferenceController imp
|
||||
}
|
||||
|
||||
// Prevent checked callback getting called on recycled views
|
||||
UserManager um = mContext.createContextAsUser(
|
||||
appInfo.userHandle, /*flags=*/0).getSystemService(UserManager.class);
|
||||
|
||||
holder.radioButton.setOnCheckedChangeListener(null);
|
||||
holder.radioButton.setChecked(appInfo.isDefault);
|
||||
holder.radioButton.setContentDescription(appInfo.label);
|
||||
holder.radioButton.setContentDescription(appInfo.label + " (" + um.getUserName() + ")");
|
||||
holder.radioButton.setOnCheckedChangeListener(this);
|
||||
holder.radioButton.setTag(appInfo);
|
||||
holder.radioButton.setText(appInfo.label);
|
||||
holder.radioButton.setText(appInfo.label + " (" + um.getUserName() + ")");
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@@ -245,7 +252,8 @@ public class NfcPaymentPreferenceController extends BasePreferenceController imp
|
||||
|
||||
private void makeDefault(PaymentAppInfo appInfo) {
|
||||
if (!appInfo.isDefault) {
|
||||
mPaymentBackend.setDefaultPaymentApp(appInfo.componentName);
|
||||
mPaymentBackend.setDefaultPaymentApp(appInfo.componentName,
|
||||
appInfo.userHandle.getIdentifier());
|
||||
}
|
||||
final Dialog dialog = mPreference.getDialog();
|
||||
if (dialog != null) {
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
package com.android.settings.nfc;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.cardemulation.ApduServiceInfo;
|
||||
import android.nfc.cardemulation.CardEmulation;
|
||||
@@ -50,6 +49,15 @@ public class PaymentBackend {
|
||||
boolean isDefault;
|
||||
public ComponentName componentName;
|
||||
public ComponentName settingsComponent;
|
||||
public UserHandle userHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* ComponentName of the payment application and the userId that it belongs to.
|
||||
*/
|
||||
public static class PaymentInfo {
|
||||
public ComponentName componentName;
|
||||
public int userId;
|
||||
}
|
||||
|
||||
private final Context mContext;
|
||||
@@ -80,24 +88,36 @@ public class PaymentBackend {
|
||||
|
||||
public void refresh() {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
List<ApduServiceInfo> serviceInfos =
|
||||
mCardEmuManager.getServices(CardEmulation.CATEGORY_PAYMENT);
|
||||
ArrayList<PaymentAppInfo> appInfosAllProfiles = new ArrayList<PaymentAppInfo>();
|
||||
|
||||
UserManager um = mContext.createContextAsUser(
|
||||
UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)
|
||||
.getSystemService(UserManager.class);
|
||||
List<UserHandle> userHandles = um.getEnabledProfiles();
|
||||
|
||||
PaymentInfo defaultAppName = getDefaultPaymentApp();
|
||||
PaymentAppInfo foundDefaultApp = null;
|
||||
for (UserHandle uh : userHandles) {
|
||||
List<ApduServiceInfo> serviceInfosByProfile =
|
||||
mCardEmuManager.getServices(CardEmulation.CATEGORY_PAYMENT, uh.getIdentifier());
|
||||
if (serviceInfosByProfile == null) continue;
|
||||
|
||||
ArrayList<PaymentAppInfo> appInfos = new ArrayList<PaymentAppInfo>();
|
||||
|
||||
if (serviceInfos == null) {
|
||||
makeCallbacks();
|
||||
return;
|
||||
}
|
||||
|
||||
ComponentName defaultAppName = getDefaultPaymentApp();
|
||||
PaymentAppInfo foundDefaultApp = null;
|
||||
for (ApduServiceInfo service : serviceInfos) {
|
||||
for (ApduServiceInfo service : serviceInfosByProfile) {
|
||||
PaymentAppInfo appInfo = new PaymentAppInfo();
|
||||
appInfo.userHandle = uh;
|
||||
appInfo.label = service.loadLabel(pm);
|
||||
if (appInfo.label == null) {
|
||||
appInfo.label = service.loadAppLabel(pm);
|
||||
}
|
||||
appInfo.isDefault = service.getComponent().equals(defaultAppName);
|
||||
if (defaultAppName == null) {
|
||||
appInfo.isDefault = false;
|
||||
} else {
|
||||
appInfo.isDefault =
|
||||
service.getComponent().equals(defaultAppName.componentName)
|
||||
&& defaultAppName.userId == uh.getIdentifier();
|
||||
}
|
||||
if (appInfo.isDefault) {
|
||||
foundDefaultApp = appInfo;
|
||||
}
|
||||
@@ -111,9 +131,12 @@ public class PaymentBackend {
|
||||
appInfo.settingsComponent = null;
|
||||
}
|
||||
appInfo.description = service.getDescription();
|
||||
|
||||
appInfos.add(appInfo);
|
||||
}
|
||||
mAppInfos = appInfos;
|
||||
appInfosAllProfiles.addAll(appInfos);
|
||||
}
|
||||
mAppInfos = appInfosAllProfiles;
|
||||
mDefaultAppInfo = foundDefaultApp;
|
||||
makeCallbacks();
|
||||
}
|
||||
@@ -150,13 +173,36 @@ public class PaymentBackend {
|
||||
}
|
||||
|
||||
void setForegroundMode(boolean foreground) {
|
||||
UserManager um = mContext.createContextAsUser(
|
||||
UserHandle.of(UserHandle.myUserId()), /*flags=*/0)
|
||||
.getSystemService(UserManager.class);
|
||||
List<UserHandle> userHandles = um.getEnabledProfiles();
|
||||
for (UserHandle uh : userHandles) {
|
||||
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.NFC_PAYMENT_FOREGROUND, foreground ? 1 : 0, UserHandle.myUserId());
|
||||
Settings.Secure.NFC_PAYMENT_FOREGROUND, foreground ? 1 : 0, uh.getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
ComponentName getDefaultPaymentApp() {
|
||||
PaymentInfo getDefaultPaymentApp() {
|
||||
UserManager um = mContext.createContextAsUser(
|
||||
UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)
|
||||
.getSystemService(UserManager.class);
|
||||
List<UserHandle> userHandles = um.getEnabledProfiles();
|
||||
for (UserHandle uh : userHandles) {
|
||||
ComponentName defaultApp = getDefaultPaymentApp(uh.getIdentifier());
|
||||
if (defaultApp != null) {
|
||||
PaymentInfo appInfo = new PaymentInfo();
|
||||
appInfo.userId = uh.getIdentifier();
|
||||
appInfo.componentName = defaultApp;
|
||||
return appInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
ComponentName getDefaultPaymentApp(int userId) {
|
||||
String componentString = Settings.Secure.getStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT, UserHandle.myUserId());
|
||||
Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT, userId);
|
||||
if (componentString != null) {
|
||||
return ComponentName.unflattenFromString(componentString);
|
||||
} else {
|
||||
@@ -165,9 +211,29 @@ public class PaymentBackend {
|
||||
}
|
||||
|
||||
public void setDefaultPaymentApp(ComponentName app) {
|
||||
setDefaultPaymentApp(app, UserHandle.myUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Nfc default payment application
|
||||
*/
|
||||
public void setDefaultPaymentApp(ComponentName app, int userId) {
|
||||
UserManager um = mContext.createContextAsUser(
|
||||
UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)
|
||||
.getSystemService(UserManager.class);
|
||||
List<UserHandle> userHandles = um.getEnabledProfiles();
|
||||
|
||||
for (UserHandle uh : userHandles) {
|
||||
if (uh.getIdentifier() == userId) {
|
||||
Settings.Secure.putStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
|
||||
app != null ? app.flattenToString() : null, UserHandle.myUserId());
|
||||
app != null ? app.flattenToString() : null, uh.getIdentifier());
|
||||
} else {
|
||||
Settings.Secure.putStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
|
||||
null, uh.getIdentifier());
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,14 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.nfc.cardemulation.CardEmulation;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
import com.android.internal.app.AlertController;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
|
||||
import com.android.settings.nfc.PaymentBackend.PaymentInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -39,7 +41,7 @@ public final class PaymentDefaultDialog extends AlertActivity implements
|
||||
private static final int PAYMENT_APP_MAX_CAPTION_LENGTH = 40;
|
||||
|
||||
private PaymentBackend mBackend;
|
||||
private ComponentName mNewDefault;
|
||||
private PaymentInfo mNewDefault;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -56,9 +58,10 @@ public final class PaymentDefaultDialog extends AlertActivity implements
|
||||
ComponentName component = intent.getParcelableExtra(
|
||||
CardEmulation.EXTRA_SERVICE_COMPONENT);
|
||||
String category = intent.getStringExtra(CardEmulation.EXTRA_CATEGORY);
|
||||
int userId = intent.getIntExtra(CardEmulation.EXTRA_USERID, UserHandle.myUserId());
|
||||
|
||||
setResult(RESULT_CANCELED);
|
||||
if (!buildDialog(component, category)) {
|
||||
if (!buildDialog(component, category, userId)) {
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -68,7 +71,7 @@ public final class PaymentDefaultDialog extends AlertActivity implements
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case BUTTON_POSITIVE:
|
||||
mBackend.setDefaultPaymentApp(mNewDefault);
|
||||
mBackend.setDefaultPaymentApp(mNewDefault.componentName, mNewDefault.userId);
|
||||
setResult(RESULT_OK);
|
||||
break;
|
||||
case BUTTON_NEGATIVE:
|
||||
@@ -76,7 +79,7 @@ public final class PaymentDefaultDialog extends AlertActivity implements
|
||||
}
|
||||
}
|
||||
|
||||
private boolean buildDialog(ComponentName component, String category) {
|
||||
private boolean buildDialog(ComponentName component, String category, int userId) {
|
||||
if (component == null || category == null) {
|
||||
Log.e(TAG, "Component or category are null");
|
||||
return false;
|
||||
@@ -93,10 +96,12 @@ public final class PaymentDefaultDialog extends AlertActivity implements
|
||||
|
||||
List<PaymentAppInfo> services = mBackend.getPaymentAppInfos();
|
||||
for (PaymentAppInfo service : services) {
|
||||
if (component.equals(service.componentName)) {
|
||||
// check if userId matches
|
||||
if (component.equals(service.componentName)
|
||||
&& service.userHandle.getIdentifier() == userId) {
|
||||
requestedPaymentApp = service;
|
||||
}
|
||||
if (service.isDefault) {
|
||||
if (service.isDefault && service.userHandle.getIdentifier() == userId) {
|
||||
defaultPaymentApp = service;
|
||||
}
|
||||
}
|
||||
@@ -107,13 +112,17 @@ public final class PaymentDefaultDialog extends AlertActivity implements
|
||||
}
|
||||
|
||||
// Get current mode and default component
|
||||
ComponentName defaultComponent = mBackend.getDefaultPaymentApp();
|
||||
if (defaultComponent != null && defaultComponent.equals(component)) {
|
||||
PaymentInfo defaultComponent = mBackend.getDefaultPaymentApp();
|
||||
if (defaultComponent != null && defaultComponent.componentName.equals(component)
|
||||
&& defaultComponent.userId == userId) {
|
||||
Log.e(TAG, "Component " + component + " is already default.");
|
||||
return false;
|
||||
}
|
||||
|
||||
mNewDefault = component;
|
||||
mNewDefault = new PaymentInfo();
|
||||
mNewDefault.componentName = component;
|
||||
mNewDefault.userId = userId;
|
||||
|
||||
// Compose dialog; get
|
||||
final AlertController.AlertParams p = mAlertParams;
|
||||
if (defaultPaymentApp == null) {
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.settings.network.helper;
|
||||
|
||||
import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.UiccPortInfo;
|
||||
import android.telephony.UiccSlotInfo;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class QuerySimSlotIndexTest {
|
||||
private static final String TAG = "QSSI_Test";
|
||||
|
||||
@Mock
|
||||
private TelephonyManager mTelephonyManager;
|
||||
|
||||
Future<AtomicIntegerArray> mActiveSimSlotIndex;
|
||||
Future<AtomicIntegerArray> mAllSimSlotIndex;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
// query in background thread
|
||||
mAllSimSlotIndex = ThreadUtils.postOnBackgroundThread(
|
||||
new QuerySimSlotIndex(mTelephonyManager, true, true));
|
||||
// query in background thread
|
||||
mActiveSimSlotIndex = ThreadUtils.postOnBackgroundThread(
|
||||
new QuerySimSlotIndex(mTelephonyManager, false, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allSimSlotIndexCall_nullInput_getNoneNullEmptyList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(null);
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(0);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allSimSlotIndexCall_oneSimAndActivePsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(oneSim_ActivePsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(0)).isEqualTo(0);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allSimSlotIndexCall_oneSimAndActiveEsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(oneSim_ActiveEsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(0)).isEqualTo(1);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allSimSlotIndexCall_twoSimsAndActivePsimActiveEsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(twoSims_ActivePsimActiveEsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(2);
|
||||
assertThat(result.get(0)).isEqualTo(0);
|
||||
assertThat(result.get(1)).isEqualTo(1);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allSimSlotIndexCall_twoSimsAndtwoActiveEsims_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(twoSims_twoActiveEsims());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(2);
|
||||
assertThat(result.get(0)).isEqualTo(0);
|
||||
assertThat(result.get(1)).isEqualTo(1);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allSimSlotIndexCall_twoSimsAndActivePsimInactiveEsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(twoSims_ActivePsimInactiveEsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(2);
|
||||
assertThat(result.get(0)).isEqualTo(0);
|
||||
assertThat(result.get(1)).isEqualTo(1);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allSimSlotIndexCall_twoSimsAndActiveEsimInactivePsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(twoSims_ActiveEsimInactivePsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(2);
|
||||
assertThat(result.get(0)).isEqualTo(0);
|
||||
assertThat(result.get(1)).isEqualTo(1);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void activeSimSlotIndexCall_nullInput_getNoneNullEmptyList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(null);
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(0);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void activeSimSlotIndexCall_oneSimAndActivePsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(oneSim_ActivePsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(0)).isEqualTo(0);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void activeSimSlotIndexCall_oneSimAndActiveEsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(oneSim_ActiveEsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(0)).isEqualTo(1);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void activeSimSlotIndexCall_twoSimsAndActivePsimActiveEsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(twoSims_ActivePsimActiveEsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(2);
|
||||
assertThat(result.get(0)).isEqualTo(0);
|
||||
assertThat(result.get(1)).isEqualTo(1);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void activeSimSlotIndexCall_twoSimsAndtwoActiveEsims_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(twoSims_twoActiveEsims());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(2);
|
||||
assertThat(result.get(0)).isEqualTo(0);
|
||||
assertThat(result.get(1)).isEqualTo(1);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void activeSimSlotIndexCall_twoSimsAndActivePsimInactiveEsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(twoSims_ActivePsimInactiveEsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(0)).isEqualTo(0);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void activeSimSlotIndexCall_twoSimsAndActiveEsimInactivePsim_getList() {
|
||||
try {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(twoSims_ActiveEsimInactivePsim());
|
||||
List<Integer> result = SelectableSubscriptions.atomicToList(mActiveSimSlotIndex.get());
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(0)).isEqualTo(1);
|
||||
} catch (Exception exception) {
|
||||
Log.w(TAG, "Fail to request subIdList", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] oneSim_ActivePsim() {
|
||||
return new UiccSlotInfo[]{createUiccSlotInfo(false, 0, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] oneSim_ActiveEsim() {
|
||||
return new UiccSlotInfo[]{createUiccSlotInfo(true, 1, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSims_ActivePsimActiveEsim() {
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfo(false, 0, true),
|
||||
createUiccSlotInfo(true, 1, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSims_twoActiveEsims() {
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfoForTwoEsim(true, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSims_ActivePsimInactiveEsim() {
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfo(false, 0, true),
|
||||
createUiccSlotInfo(true, 1, false)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSims_ActiveEsimInactivePsim() {
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfo(false, 0, false),
|
||||
createUiccSlotInfo(true, 1, true)};
|
||||
}
|
||||
|
||||
//ToDo: add more cases.
|
||||
/*
|
||||
private List<UiccSlotInfo> threeSims_ActivePsimTwoinactiveEsim(){
|
||||
}
|
||||
private List<UiccSlotInfo> threeSims_twoActiveEsimsInactivePsim(){
|
||||
}
|
||||
private List<UiccSlotInfo> threeSims_ActiveEsimInactivePsimInactiveEsim(){
|
||||
}
|
||||
private List<UiccSlotInfo> threeSims_ActivePsimActiveEsimInactiveEsim(){
|
||||
}
|
||||
*/
|
||||
|
||||
private UiccSlotInfo createUiccSlotInfo(boolean isEuicc, int logicalSlotIdx,
|
||||
boolean isActive) {
|
||||
return new UiccSlotInfo(
|
||||
isEuicc, /* isEuicc */
|
||||
"123", /* cardId */
|
||||
CARD_STATE_INFO_PRESENT, /* cardStateInfo */
|
||||
true, /* isExtendApduSupported */
|
||||
true, /* isRemovable */
|
||||
Collections.singletonList(
|
||||
new UiccPortInfo("" /* iccId */, 0 /* portIdx */,
|
||||
logicalSlotIdx /* logicalSlotIdx */, isActive /* isActive */))
|
||||
);
|
||||
}
|
||||
|
||||
private UiccSlotInfo createUiccSlotInfoForTwoEsim(boolean isActiveEsim1,
|
||||
boolean isActiveEsim2) {
|
||||
return new UiccSlotInfo(
|
||||
true, /* isEuicc */
|
||||
"123", /* cardId */
|
||||
CARD_STATE_INFO_PRESENT, /* cardStateInfo */
|
||||
true, /* isExtendApduSupported */
|
||||
true, /* isRemovable */
|
||||
Arrays.asList(
|
||||
new UiccPortInfo("" /* iccId */, 0 /* portIdx */,
|
||||
0 /* logicalSlotIdx */, isActiveEsim1 /* isActive */),
|
||||
new UiccPortInfo("" /* iccId */, 1 /* portIdx */,
|
||||
1 /* logicalSlotIdx */, isActiveEsim2 /* isActive */))
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user