Add account picker to Support Tab
Add a spinner to select the account for user. Bug: 32249920 Test: make RunSettingsRoboTests Change-Id: I372d16ec5ec3230f5f2994d79f4fd27085092236
This commit is contained in:
26
res/layout/support_account_spinner_item.xml
Normal file
26
res/layout/support_account_spinner_item.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2016 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@android:id/text1"
|
||||||
|
style="?android:attr/spinnerItemStyle"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textAlignment="inherit"/>
|
@@ -34,11 +34,25 @@
|
|||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingBottom="30dp"
|
android:paddingBottom="30dp"
|
||||||
android:textAppearance="@style/TextAppearance.Small"
|
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||||
android:textColor="?android:attr/textColorSecondary"/>
|
<TextView
|
||||||
|
android:id="@+id/account_request_prefix"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:text="@string/support_account_request_prefix"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/account_spinner"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:gravity="center_horizontal"/>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="30dp"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@@ -60,8 +74,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="14dp"
|
android:layout_marginTop="14dp"
|
||||||
android:textAppearance="@style/TextAppearance.Small"
|
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||||
android:textColor="?android:attr/textColorSecondary"/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@@ -82,8 +95,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="14dp"
|
android:layout_marginTop="14dp"
|
||||||
android:textAppearance="@style/TextAppearance.Small"
|
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||||
android:textColor="?android:attr/textColorSecondary"/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@@ -7797,6 +7797,12 @@
|
|||||||
<!-- Checkbox text, when checked dialog will not show again [CHAR LIMIT=80] -->
|
<!-- Checkbox text, when checked dialog will not show again [CHAR LIMIT=80] -->
|
||||||
<string name="support_disclaimer_do_not_show">Do not show again</string>
|
<string name="support_disclaimer_do_not_show">Do not show again</string>
|
||||||
|
|
||||||
|
<!-- Prefix text for the account picker, e.g. "Requesting as user@gmail.com" [CHAR LIMIT=60] -->
|
||||||
|
<string name="support_account_request_prefix">Requesting as</string>
|
||||||
|
|
||||||
|
<!-- Spinner dropdown text, when selected will try to add account [CHAR LIMIT=60] -->
|
||||||
|
<string name="support_account_picker_add_account">Add account</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=60] Title of work profile setting page -->
|
<!-- [CHAR LIMIT=60] Title of work profile setting page -->
|
||||||
<string name="managed_profile_settings_title">Work profile settings</string>
|
<string name="managed_profile_settings_title">Work profile settings</string>
|
||||||
<!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->
|
<!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->
|
||||||
|
@@ -138,8 +138,8 @@ public final class SupportFragment extends InstrumentedFragment implements View.
|
|||||||
@Override
|
@Override
|
||||||
public void onAccountsUpdated(Account[] accounts) {
|
public void onAccountsUpdated(Account[] accounts) {
|
||||||
// Account changed, update support items.
|
// Account changed, update support items.
|
||||||
mSupportItemAdapter.setAccount(
|
mSupportItemAdapter.setAccounts(
|
||||||
mSupportFeatureProvider.getSupportEligibleAccount(mActivity));
|
mSupportFeatureProvider.getSupportEligibleAccounts(mActivity));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -26,6 +26,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -38,6 +39,7 @@ import android.widget.Spinner;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settings.overlay.SupportFeatureProvider;
|
import com.android.settings.overlay.SupportFeatureProvider;
|
||||||
@@ -46,8 +48,8 @@ import com.android.settings.support.SupportPhone;
|
|||||||
import com.android.settings.support.SupportPhoneDialogFragment;
|
import com.android.settings.support.SupportPhoneDialogFragment;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static com.android.settings.overlay.SupportFeatureProvider.SupportType.CHAT;
|
import static com.android.settings.overlay.SupportFeatureProvider.SupportType.CHAT;
|
||||||
import static com.android.settings.overlay.SupportFeatureProvider.SupportType.PHONE;
|
import static com.android.settings.overlay.SupportFeatureProvider.SupportType.PHONE;
|
||||||
@@ -58,6 +60,7 @@ import static com.android.settings.overlay.SupportFeatureProvider.SupportType.PH
|
|||||||
public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAdapter.ViewHolder> {
|
public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAdapter.ViewHolder> {
|
||||||
|
|
||||||
private static final String STATE_SELECTED_COUNTRY = "STATE_SELECTED_COUNTRY";
|
private static final String STATE_SELECTED_COUNTRY = "STATE_SELECTED_COUNTRY";
|
||||||
|
private static final String ACCOUNT_SELECTED_INDEX = "ACCOUNT_SELECTED_INDEX";
|
||||||
private static final int TYPE_ESCALATION_OPTIONS = R.layout.support_escalation_options;
|
private static final int TYPE_ESCALATION_OPTIONS = R.layout.support_escalation_options;
|
||||||
private static final int TYPE_ESCALATION_OPTIONS_OFFLINE =
|
private static final int TYPE_ESCALATION_OPTIONS_OFFLINE =
|
||||||
R.layout.support_offline_escalation_options;
|
R.layout.support_offline_escalation_options;
|
||||||
@@ -67,7 +70,8 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
|
|
||||||
private final Activity mActivity;
|
private final Activity mActivity;
|
||||||
private final EscalationClickListener mEscalationClickListener;
|
private final EscalationClickListener mEscalationClickListener;
|
||||||
private final SpinnerItemSelectListener mSpinnerItemSelectListener;
|
private final OfflineSpinnerItemSelectListener mOfflineSpinnerItemSelectListener;
|
||||||
|
private final OnlineSpinnerItemSelectListener mOnlineSpinnerItemSelectListener;
|
||||||
private final SupportFeatureProvider mSupportFeatureProvider;
|
private final SupportFeatureProvider mSupportFeatureProvider;
|
||||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||||
private final View.OnClickListener mItemClickListener;
|
private final View.OnClickListener mItemClickListener;
|
||||||
@@ -75,7 +79,8 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
|
|
||||||
private String mSelectedCountry;
|
private String mSelectedCountry;
|
||||||
private boolean mHasInternet;
|
private boolean mHasInternet;
|
||||||
private Account mAccount;
|
private Account[] mAccounts;
|
||||||
|
private int mSelectedAccountIndex;
|
||||||
|
|
||||||
public SupportItemAdapter(Activity activity, Bundle savedInstanceState,
|
public SupportItemAdapter(Activity activity, Bundle savedInstanceState,
|
||||||
SupportFeatureProvider supportFeatureProvider,
|
SupportFeatureProvider supportFeatureProvider,
|
||||||
@@ -86,16 +91,20 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
mMetricsFeatureProvider = metricsFeatureProvider;
|
mMetricsFeatureProvider = metricsFeatureProvider;
|
||||||
mItemClickListener = itemClickListener;
|
mItemClickListener = itemClickListener;
|
||||||
mEscalationClickListener = new EscalationClickListener();
|
mEscalationClickListener = new EscalationClickListener();
|
||||||
mSpinnerItemSelectListener = new SpinnerItemSelectListener();
|
mOfflineSpinnerItemSelectListener = new OfflineSpinnerItemSelectListener();
|
||||||
|
mOnlineSpinnerItemSelectListener = new OnlineSpinnerItemSelectListener();
|
||||||
mSupportData = new ArrayList<>();
|
mSupportData = new ArrayList<>();
|
||||||
// Optimistically assume we have Internet access. It will be updated later to correct value.
|
// Optimistically assume we have Internet access. It will be updated later to correct value.
|
||||||
mHasInternet = true;
|
mHasInternet = true;
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
mSelectedCountry = savedInstanceState.getString(STATE_SELECTED_COUNTRY);
|
mSelectedCountry = savedInstanceState.getString(STATE_SELECTED_COUNTRY);
|
||||||
|
mSelectedAccountIndex = savedInstanceState.getInt(ACCOUNT_SELECTED_INDEX);
|
||||||
} else {
|
} else {
|
||||||
mSelectedCountry = mSupportFeatureProvider.getCurrentCountryCodeIfHasConfig(PHONE);
|
mSelectedCountry = mSupportFeatureProvider.getCurrentCountryCodeIfHasConfig(PHONE);
|
||||||
|
mSelectedAccountIndex = 0;
|
||||||
}
|
}
|
||||||
mAccount = mSupportFeatureProvider.getSupportEligibleAccount(mActivity);
|
|
||||||
|
mAccounts = mSupportFeatureProvider.getSupportEligibleAccounts(mActivity);
|
||||||
refreshData();
|
refreshData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,9 +168,11 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccount(Account account) {
|
public void setAccounts(Account accounts[]) {
|
||||||
if (!Objects.equals(mAccount, account)) {
|
if (!Arrays.equals(mAccounts, accounts)) {
|
||||||
mAccount = account;
|
int index = ArrayUtils.indexOf(accounts, mAccounts[mSelectedAccountIndex]);
|
||||||
|
mSelectedAccountIndex = index != -1 ? index : 0;
|
||||||
|
mAccounts = accounts;
|
||||||
mSupportFeatureProvider.refreshOperationRules();
|
mSupportFeatureProvider.refreshOperationRules();
|
||||||
refreshEscalationCards();
|
refreshEscalationCards();
|
||||||
}
|
}
|
||||||
@@ -169,6 +180,7 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
outState.putString(STATE_SELECTED_COUNTRY, mSelectedCountry);
|
outState.putString(STATE_SELECTED_COUNTRY, mSelectedCountry);
|
||||||
|
outState.putInt(ACCOUNT_SELECTED_INDEX, mSelectedAccountIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -187,7 +199,7 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
* different content.
|
* different content.
|
||||||
*/
|
*/
|
||||||
private void addEscalationCards() {
|
private void addEscalationCards() {
|
||||||
if (mAccount == null) {
|
if (mAccounts.length == 0) {
|
||||||
addSignInPromo();
|
addSignInPromo();
|
||||||
} else if (mHasInternet) {
|
} else if (mHasInternet) {
|
||||||
addOnlineEscalationCards();
|
addOnlineEscalationCards();
|
||||||
@@ -341,6 +353,21 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
holder.summary2View.setVisibility(mHasInternet && !TextUtils.isEmpty(data.summary2)
|
holder.summary2View.setVisibility(mHasInternet && !TextUtils.isEmpty(data.summary2)
|
||||||
? View.VISIBLE : View.GONE);
|
? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bindAccountPicker(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void bindAccountPicker(ViewHolder holder) {
|
||||||
|
final Spinner spinner = (Spinner) holder.itemView.findViewById(R.id.account_spinner);
|
||||||
|
|
||||||
|
final ArrayAdapter<String> adapter = new ArrayAdapter(
|
||||||
|
mActivity, R.layout.support_account_spinner_item,
|
||||||
|
extractAccountNames(mAccounts));
|
||||||
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
spinner.setAdapter(adapter);
|
||||||
|
spinner.setOnItemSelectedListener(mOnlineSpinnerItemSelectListener);
|
||||||
|
spinner.setSelection(mSelectedAccountIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindOfflineEscalationOptions(ViewHolder holder, OfflineEscalationData data) {
|
private void bindOfflineEscalationOptions(ViewHolder holder, OfflineEscalationData data) {
|
||||||
@@ -360,7 +387,7 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spinner.setOnItemSelectedListener(mSpinnerItemSelectListener);
|
spinner.setOnItemSelectedListener(mOfflineSpinnerItemSelectListener);
|
||||||
// Bind buttons
|
// Bind buttons
|
||||||
if (data.tollFreePhone != null) {
|
if (data.tollFreePhone != null) {
|
||||||
holder.text1View.setText(data.tollFreePhone.number);
|
holder.text1View.setText(data.tollFreePhone.number);
|
||||||
@@ -415,11 +442,23 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
*/
|
*/
|
||||||
private void tryStartDisclaimerAndSupport(final @SupportFeatureProvider.SupportType int type) {
|
private void tryStartDisclaimerAndSupport(final @SupportFeatureProvider.SupportType int type) {
|
||||||
if (mSupportFeatureProvider.shouldShowDisclaimerDialog(mActivity)) {
|
if (mSupportFeatureProvider.shouldShowDisclaimerDialog(mActivity)) {
|
||||||
DialogFragment fragment = SupportDisclaimerDialogFragment.newInstance(mAccount, type);
|
DialogFragment fragment = SupportDisclaimerDialogFragment.newInstance(
|
||||||
|
mAccounts[mSelectedAccountIndex], type);
|
||||||
fragment.show(mActivity.getFragmentManager(), SupportDisclaimerDialogFragment.TAG);
|
fragment.show(mActivity.getFragmentManager(), SupportDisclaimerDialogFragment.TAG);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mSupportFeatureProvider.startSupport(mActivity, mAccount, type);
|
mSupportFeatureProvider.startSupport(mActivity, mAccounts[mSelectedAccountIndex], type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] extractAccountNames(Account[] accounts) {
|
||||||
|
String[] accountNames = new String[accounts.length+1];
|
||||||
|
for (int i = 0; i < accounts.length; i++) {
|
||||||
|
accountNames[i] = accounts[i].name;
|
||||||
|
}
|
||||||
|
accountNames[accounts.length] = mActivity.getString(
|
||||||
|
R.string.support_account_picker_add_account);
|
||||||
|
|
||||||
|
return accountNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -428,7 +467,7 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
private final class EscalationClickListener implements View.OnClickListener {
|
private final class EscalationClickListener implements View.OnClickListener {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(final View v) {
|
public void onClick(final View v) {
|
||||||
if (mAccount == null) {
|
if (mAccounts.length == 0) {
|
||||||
switch (v.getId()) {
|
switch (v.getId()) {
|
||||||
case android.R.id.text1:
|
case android.R.id.text1:
|
||||||
mMetricsFeatureProvider.action(mActivity,
|
mMetricsFeatureProvider.action(mActivity,
|
||||||
@@ -490,7 +529,8 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class SpinnerItemSelectListener implements AdapterView.OnItemSelectedListener {
|
private final class OfflineSpinnerItemSelectListener
|
||||||
|
implements AdapterView.OnItemSelectedListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
@@ -508,6 +548,26 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class OnlineSpinnerItemSelectListener
|
||||||
|
implements AdapterView.OnItemSelectedListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
if (position == mAccounts.length) {
|
||||||
|
mActivity.startActivity(mSupportFeatureProvider.getAccountLoginIntent());
|
||||||
|
// Make sure "Add account" is not shown as selected item
|
||||||
|
parent.setSelection(mSelectedAccountIndex);
|
||||||
|
} else if (position != mSelectedAccountIndex) {
|
||||||
|
mSelectedAccountIndex = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link RecyclerView.ViewHolder} for support items.
|
* {@link RecyclerView.ViewHolder} for support items.
|
||||||
*/
|
*/
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.overlay;
|
|||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.annotation.StringRes;
|
import android.annotation.StringRes;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -111,15 +112,16 @@ public interface SupportFeatureProvider {
|
|||||||
void setShouldShowDisclaimerDialog(Context context, boolean shouldShow);
|
void setShouldShowDisclaimerDialog(Context context, boolean shouldShow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an {@link Account} that's eligible for support options.
|
* Returns array of {@link Account} that's eligible for support options.
|
||||||
*/
|
*/
|
||||||
Account getSupportEligibleAccount(Context context);
|
@NonNull
|
||||||
|
Account[] getSupportEligibleAccounts(Context context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts support activity of specified type
|
* Starts support activity of specified type
|
||||||
*
|
*
|
||||||
* @param activity Calling activity
|
* @param activity Calling activity
|
||||||
* @param account A account returned by {@link #getSupportEligibleAccount}
|
* @param account A account that selected by user
|
||||||
* @param type The type of support account needs.
|
* @param type The type of support account needs.
|
||||||
*/
|
*/
|
||||||
void startSupport(Activity activity, Account account, @SupportType int type);
|
void startSupport(Activity activity, Account account, @SupportType int type);
|
||||||
|
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.dashboard;
|
||||||
|
|
||||||
|
import android.accounts.Account;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.SpinnerAdapter;
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||||
|
import com.android.settings.overlay.SupportFeatureProvider;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.Robolectric;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import org.robolectric.shadows.ShadowActivity;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.robolectric.Shadows.shadowOf;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class SupportItemAdapterTest {
|
||||||
|
private static final String ACCOUNT_TYPE = "com.google";
|
||||||
|
private final Account USER_1 = new Account("user1", ACCOUNT_TYPE);
|
||||||
|
private final Account USER_2 = new Account("user2", ACCOUNT_TYPE);
|
||||||
|
private final Account TWO_ACCOUNTS[] = {USER_1, USER_2};
|
||||||
|
private final Account ONE_ACCOUNT[] = {USER_1};
|
||||||
|
|
||||||
|
private ShadowActivity mShadowActivity;
|
||||||
|
private Activity mActivity;
|
||||||
|
private SupportItemAdapter mSupportItemAdapter;
|
||||||
|
private SupportItemAdapter.ViewHolder mViewHolder;
|
||||||
|
@Mock
|
||||||
|
private SupportFeatureProvider mSupportFeatureProvider;
|
||||||
|
@Mock
|
||||||
|
private MetricsFeatureProvider mMetricsFeatureProvider;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mActivity = Robolectric.setupActivity(Activity.class);
|
||||||
|
mShadowActivity = shadowOf(mActivity);
|
||||||
|
|
||||||
|
final View itemView = LayoutInflater.from(mActivity).inflate(
|
||||||
|
R.layout.support_escalation_options, null);
|
||||||
|
mViewHolder = new SupportItemAdapter.ViewHolder(itemView);
|
||||||
|
|
||||||
|
// Mock this to prevent crash in testing
|
||||||
|
when(mSupportFeatureProvider.getAccountLoginIntent()).thenReturn(
|
||||||
|
new Intent(Settings.ACTION_ADD_ACCOUNT));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBindAccountPicker_TwoAccounts_ShouldHaveTwoAccounts() {
|
||||||
|
testBindAccountPickerInner(mViewHolder, TWO_ACCOUNTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBindAccountPicker_OneAccount_ShouldHaveOneAccount() {
|
||||||
|
testBindAccountPickerInner(mViewHolder, ONE_ACCOUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnSpinnerItemClick_AddAccountClicked_AccountLoginIntentInvoked() {
|
||||||
|
bindAccountPickerInner(mViewHolder, TWO_ACCOUNTS);
|
||||||
|
|
||||||
|
final Spinner spinner = (Spinner) mViewHolder.itemView.findViewById(R.id.account_spinner);
|
||||||
|
spinner.setSelection(TWO_ACCOUNTS.length);
|
||||||
|
|
||||||
|
Robolectric.flushForegroundThreadScheduler();
|
||||||
|
|
||||||
|
verify(mSupportFeatureProvider).getAccountLoginIntent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check after {@link SupportItemAdapter#bindAccountPicker(SupportItemAdapter.ViewHolder)} is
|
||||||
|
* invoked, whether the spinner in {@paramref viewHolder} has all the data from {@paramref
|
||||||
|
* accounts}
|
||||||
|
*
|
||||||
|
* @param viewHolder holds the view that contains the spinner to test
|
||||||
|
* @param accounts holds the accounts info to be showed in spinner.
|
||||||
|
*/
|
||||||
|
private void testBindAccountPickerInner(SupportItemAdapter.ViewHolder viewHolder,
|
||||||
|
Account accounts[]) {
|
||||||
|
bindAccountPickerInner(viewHolder, accounts);
|
||||||
|
|
||||||
|
final Spinner spinner = (Spinner) viewHolder.itemView.findViewById(R.id.account_spinner);
|
||||||
|
final SpinnerAdapter adapter = spinner.getAdapter();
|
||||||
|
|
||||||
|
// Contains "Add account" option, so should be 'count+1'
|
||||||
|
assertThat(adapter.getCount()).isEqualTo(accounts.length + 1);
|
||||||
|
for (int i = 0; i < accounts.length; i++) {
|
||||||
|
assertThat(adapter.getItem(i)).isEqualTo(accounts[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create {@link SupportItemAdapter} and bind the account picker view into
|
||||||
|
* {@paramref viewholder}
|
||||||
|
*
|
||||||
|
* @param viewHolder holds the view that contains the spinner to test
|
||||||
|
* @param accounts holds the accounts info to be showed in spinner.
|
||||||
|
*/
|
||||||
|
private void bindAccountPickerInner(SupportItemAdapter.ViewHolder viewHolder,
|
||||||
|
Account accounts[]) {
|
||||||
|
when(mSupportFeatureProvider.getSupportEligibleAccounts(mActivity)).thenReturn(accounts);
|
||||||
|
mSupportItemAdapter = new SupportItemAdapter(mActivity, null, mSupportFeatureProvider,
|
||||||
|
mMetricsFeatureProvider, null);
|
||||||
|
|
||||||
|
mSupportItemAdapter.bindAccountPicker(viewHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user