When offline show a list of countries with phone support.
Bug: 29105266 TODO: - Support phones UI for international travel - Selecting default country - Show operation hours for selected country Change-Id: I08a6780497dfcb9b9dc8670f2705d01df021c57b
This commit is contained in:
55
res/layout/support_offline_escalation_options.xml
Normal file
55
res/layout/support_offline_escalation_options.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/card_background_grey"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingBottom="40dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/support_country_list_title"
|
||||
android:textAppearance="@style/TextAppearance.Small"
|
||||
android:textColor="?android:attr/textColorSecondary"/>
|
||||
<Spinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
<Button
|
||||
android:id="@android:id/text1"
|
||||
style="@style/SupportPrimaryButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"/>
|
||||
<Button
|
||||
android:id="@android:id/text2"
|
||||
style="@style/SupportSecondaryButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:minHeight="48dp"/>
|
||||
</LinearLayout>
|
@@ -7522,12 +7522,24 @@
|
||||
<xliff:g id="start_day">%s</xliff:g> - <xliff:g id="end_day">%s</xliff:g>, <xliff:g id="start_time">%s</xliff:g> - <xliff:g id="end_time">%s</xliff:g><br>
|
||||
</string>
|
||||
|
||||
<!-- Button label for choosing country for phone support. [CHAR LIMIT=40]-->
|
||||
<string name="support_country_list_title">Support for:</string>
|
||||
|
||||
<!-- Template for formatting country and language. eg Canada - French [CHAR LIMIT=NONE]-->
|
||||
<string name="support_country_format"><xliff:g id="country" example="Canada">%s</xliff:g> - <xliff:g id="language" example="French">%s</xliff:g></string>
|
||||
|
||||
<!-- Title text that indicates there is not internet connection. [CHAR LIMIT=80]-->
|
||||
<string name="support_offline_title">You\'re offline</string>
|
||||
|
||||
<!-- Summary text telling user to connect to Internet in order to request customer support. [CHAR LIMIT=NONE]-->
|
||||
<string name="support_offline_summary">To reach support, first connect to Wi-Fi or data.</string>
|
||||
|
||||
<!-- Title text for a list of international support phone numbers. [CHAR LIMIT=60]-->
|
||||
<string name="support_international_phone_title">Traveling aboard?</string>
|
||||
|
||||
<!-- Description text warning international phone charge may apply when dialing support numbers. [CHAR LIMIT=NONE]-->
|
||||
<string name="support_international_phone_summary">International charges may apply</string>
|
||||
|
||||
<!-- Button label for contacting customer support by phone [CHAR LIMIT=20]-->
|
||||
<string name="support_escalation_by_phone">Phone</string>
|
||||
|
||||
|
@@ -28,7 +28,10 @@ import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
@@ -36,6 +39,7 @@ import com.android.internal.logging.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.overlay.SupportFeatureProvider;
|
||||
import com.android.settings.support.SupportDisclaimerDialogFragment;
|
||||
import com.android.settings.support.SupportPhone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -51,15 +55,19 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
|
||||
private static final int TYPE_TITLE = R.layout.support_item_title;
|
||||
private static final int TYPE_ESCALATION_OPTIONS = R.layout.support_escalation_options;
|
||||
private static final int TYPE_ESCALATION_OPTIONS_OFFLINE =
|
||||
R.layout.support_offline_escalation_options;
|
||||
private static final int TYPE_SUPPORT_TILE = R.layout.support_tile;
|
||||
private static final int TYPE_SIGN_IN_BUTTON = R.layout.support_sign_in_button;
|
||||
|
||||
private final Activity mActivity;
|
||||
private final EscalationClickListener mEscalationClickListener;
|
||||
private final SpinnerItemSelectListener mSpinnerItemSelectListener;
|
||||
private final SupportFeatureProvider mSupportFeatureProvider;
|
||||
private final View.OnClickListener mItemClickListener;
|
||||
private final List<SupportData> mSupportData;
|
||||
|
||||
private String mSelectedCountry;
|
||||
private boolean mHasInternet;
|
||||
private Account mAccount;
|
||||
|
||||
@@ -69,6 +77,7 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
mSupportFeatureProvider = supportFeatureProvider;
|
||||
mItemClickListener = itemClickListener;
|
||||
mEscalationClickListener = new EscalationClickListener();
|
||||
mSpinnerItemSelectListener = new SpinnerItemSelectListener();
|
||||
mSupportData = new ArrayList<>();
|
||||
// Optimistically assume we have Internet access. It will be updated later to correct value.
|
||||
mHasInternet = true;
|
||||
@@ -92,6 +101,9 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
case TYPE_ESCALATION_OPTIONS:
|
||||
bindEscalationOptions(holder, data);
|
||||
break;
|
||||
case TYPE_ESCALATION_OPTIONS_OFFLINE:
|
||||
bindOfflineEscalationOptions(holder, (OfflineSupportData) data);
|
||||
break;
|
||||
default:
|
||||
bindSupportTile(holder, data);
|
||||
break;
|
||||
@@ -145,15 +157,16 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
mSupportData.clear();
|
||||
if (mAccount == null) {
|
||||
addSignInPromo();
|
||||
} else {
|
||||
} else if (mHasInternet) {
|
||||
addEscalationCards();
|
||||
} else {
|
||||
addOfflineEscalationCards();
|
||||
}
|
||||
addMoreHelpItems();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void addEscalationCards() {
|
||||
if (mHasInternet) {
|
||||
if (mSupportFeatureProvider.isAlwaysOperating(PHONE)
|
||||
|| mSupportFeatureProvider.isAlwaysOperating(CHAT)) {
|
||||
mSupportData.add(new SupportData.Builder(mActivity, TYPE_TITLE)
|
||||
@@ -172,12 +185,6 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
.setText2(mSupportFeatureProvider.getOperationHours(mActivity, PHONE))
|
||||
.build());
|
||||
}
|
||||
} else {
|
||||
mSupportData.add(new SupportData.Builder(mActivity, TYPE_TITLE)
|
||||
.setText1(R.string.support_offline_title)
|
||||
.setText2(R.string.support_offline_summary)
|
||||
.build());
|
||||
}
|
||||
final SupportData.Builder builder =
|
||||
new SupportData.Builder(mActivity, TYPE_ESCALATION_OPTIONS);
|
||||
if (mSupportFeatureProvider.isSupportTypeEnabled(mActivity, PHONE)) {
|
||||
@@ -193,6 +200,20 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
mSupportData.add(builder.build());
|
||||
}
|
||||
|
||||
private void addOfflineEscalationCards() {
|
||||
mSupportData.add(new SupportData.Builder(mActivity, TYPE_TITLE)
|
||||
.setText1(R.string.support_offline_title)
|
||||
.setText2(R.string.support_offline_summary)
|
||||
.build());
|
||||
final OfflineSupportData.Builder builder = new OfflineSupportData.Builder(mActivity);
|
||||
builder.setCountries(mSupportFeatureProvider.getPhoneSupportCountries())
|
||||
.setTollFreePhone(mSupportFeatureProvider.getSupportPhones(
|
||||
mSelectedCountry, true /* isTollFree */))
|
||||
.setTolledPhone(mSupportFeatureProvider.getSupportPhones(
|
||||
mSelectedCountry, false /* isTollFree */));
|
||||
mSupportData.add(builder.build());
|
||||
}
|
||||
|
||||
private void addSignInPromo() {
|
||||
mSupportData.add(new SupportData.Builder(mActivity, TYPE_TITLE)
|
||||
.setText1(R.string.support_sign_in_required_title)
|
||||
@@ -246,6 +267,38 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
}
|
||||
}
|
||||
|
||||
private void bindOfflineEscalationOptions(ViewHolder holder, OfflineSupportData data) {
|
||||
// Bind spinner
|
||||
final Spinner spinner = (Spinner) holder.itemView.findViewById(R.id.spinner);
|
||||
final ArrayAdapter<String> adapter = new ArrayAdapter(
|
||||
mActivity, android.R.layout.simple_spinner_dropdown_item, data.countries);
|
||||
spinner.setAdapter(adapter);
|
||||
final List<String> countryCodes = mSupportFeatureProvider.getPhoneSupportCountryCodes();
|
||||
for (int i = 0; i < countryCodes.size(); i++) {
|
||||
if (TextUtils.equals(countryCodes.get(i), mSelectedCountry)) {
|
||||
spinner.setSelection(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
spinner.setOnItemSelectedListener(mSpinnerItemSelectListener);
|
||||
// Bind buttons
|
||||
if (data.tollFreePhone != null) {
|
||||
holder.text1View.setText(data.tollFreePhone.number);
|
||||
holder.text1View.setVisibility(View.VISIBLE);
|
||||
holder.text1View.setOnClickListener(mEscalationClickListener);
|
||||
} else {
|
||||
holder.text1View.setVisibility(View.GONE);
|
||||
}
|
||||
if (data.tolledPhone != null) {
|
||||
holder.text2View.setText(
|
||||
mActivity.getString(R.string.support_international_phone_title));
|
||||
holder.text2View.setVisibility(View.VISIBLE);
|
||||
holder.text2View.setOnClickListener(mEscalationClickListener);
|
||||
} else {
|
||||
holder.text2View.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void bindSignInPromoTile(ViewHolder holder, SupportData data) {
|
||||
holder.text1View.setText(data.text1);
|
||||
holder.text2View.setText(data.text2);
|
||||
@@ -299,7 +352,7 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
0 /* requestCode */);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
} else if (mHasInternet) {
|
||||
switch (v.getId()) {
|
||||
case android.R.id.text1:
|
||||
MetricsLogger.action(mActivity,
|
||||
@@ -312,7 +365,37 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
tryStartDisclaimerAndSupport(CHAT);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (v.getId()) {
|
||||
case android.R.id.text1:
|
||||
final SupportPhone phone = mSupportFeatureProvider
|
||||
.getSupportPhones(mSelectedCountry, true /* isTollFree */);
|
||||
if (phone != null) {
|
||||
mActivity.startActivity(phone.getDialIntent());
|
||||
}
|
||||
break;
|
||||
case android.R.id.text2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class SpinnerItemSelectListener implements AdapterView.OnItemSelectedListener {
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
final List<String> countryCodes = mSupportFeatureProvider.getPhoneSupportCountryCodes();
|
||||
final String selectedCountry = countryCodes.get(position);
|
||||
if (!TextUtils.equals(selectedCountry, mSelectedCountry)) {
|
||||
mSelectedCountry = selectedCountry;
|
||||
refreshData();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +423,7 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
/**
|
||||
* Data for a single support item.
|
||||
*/
|
||||
private static final class SupportData {
|
||||
private static class SupportData {
|
||||
|
||||
final Intent intent;
|
||||
final int metricsEvent;
|
||||
@@ -369,7 +452,7 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
this.metricsEvent = builder.mMetricsEvent;
|
||||
}
|
||||
|
||||
static final class Builder {
|
||||
static class Builder {
|
||||
|
||||
private final Context mContext;
|
||||
@LayoutRes
|
||||
@@ -446,4 +529,51 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Support data for offline mode.
|
||||
*/
|
||||
private static final class OfflineSupportData extends SupportData {
|
||||
|
||||
final List<String> countries;
|
||||
final SupportPhone tollFreePhone;
|
||||
final SupportPhone tolledPhone;
|
||||
|
||||
private OfflineSupportData(Builder builder) {
|
||||
super(builder);
|
||||
countries = builder.mCountries;
|
||||
tollFreePhone = builder.mTollFreePhone;
|
||||
tolledPhone = builder.mTolledPhone;
|
||||
}
|
||||
|
||||
static final class Builder extends SupportData.Builder {
|
||||
|
||||
private List<String> mCountries;
|
||||
private SupportPhone mTollFreePhone;
|
||||
private SupportPhone mTolledPhone;
|
||||
|
||||
Builder(Context context) {
|
||||
super(context, TYPE_ESCALATION_OPTIONS_OFFLINE);
|
||||
}
|
||||
|
||||
Builder setCountries(List<String> countries) {
|
||||
mCountries = countries;
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder setTollFreePhone(SupportPhone phone) {
|
||||
mTollFreePhone = phone;
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder setTolledPhone(SupportPhone phone) {
|
||||
mTolledPhone = phone;
|
||||
return this;
|
||||
}
|
||||
|
||||
OfflineSupportData build() {
|
||||
return new OfflineSupportData(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -22,8 +22,11 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import com.android.settings.support.SupportPhone;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Feature provider for support tab.
|
||||
@@ -68,6 +71,22 @@ public interface SupportFeatureProvider {
|
||||
*/
|
||||
String getEstimatedWaitTime(Context context, @SupportType int type);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of country codes that have phone support.
|
||||
*/
|
||||
List<String> getPhoneSupportCountryCodes();
|
||||
|
||||
/**
|
||||
* Returns a list of countries that have phone support.
|
||||
*/
|
||||
List<String> getPhoneSupportCountries();
|
||||
|
||||
/**
|
||||
* Returns a support phone for specified country.
|
||||
*/
|
||||
SupportPhone getSupportPhones(String countryCode, boolean isTollfree);
|
||||
|
||||
/**
|
||||
* Whether or not a disclaimer dialog should be displayed.
|
||||
*/
|
||||
|
52
src/com/android/settings/support/SupportPhone.java
Normal file
52
src/com/android/settings/support/SupportPhone.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.support;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
/**
|
||||
* Data model for a support phone number.
|
||||
*/
|
||||
public final class SupportPhone {
|
||||
|
||||
public final String language;
|
||||
public final String number;
|
||||
public final boolean isTollFree;
|
||||
|
||||
public SupportPhone(String config) throws ParseException {
|
||||
// Config follows this format: language:[tollfree|tolled]:number
|
||||
final String[] tokens = config.split(":");
|
||||
if (tokens.length != 3) {
|
||||
throw new ParseException("Phone config is invalid " + config, 0);
|
||||
}
|
||||
language = tokens[0];
|
||||
isTollFree = TextUtils.equals(tokens[1], "tollfree");
|
||||
number = tokens[2];
|
||||
}
|
||||
|
||||
public Intent getDialIntent() {
|
||||
return new Intent(Intent.ACTION_DIAL)
|
||||
.setData(new Uri.Builder()
|
||||
.scheme("tel")
|
||||
.appendPath(number)
|
||||
.build());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user