Display disclaimer dialog before starting support.

Bug: 28656426
Bug: 28141203
Change-Id: I4fc0d922170badcf5f215fe906fb616c11cf8270
This commit is contained in:
Fan Zhang
2016-05-12 13:25:54 -07:00
committed by Andrew Sapperstein
parent 699efba106
commit a2bd32b397
5 changed files with 202 additions and 21 deletions

View File

@@ -0,0 +1,29 @@
<?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:orientation="vertical"
android:padding="24dp">
<TextView
android:id="@+id/support_disclaimer_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/support_disclaimer_content"/>
</LinearLayout>

View File

@@ -7532,6 +7532,13 @@
<!-- Button label that redirects user who needs help for signin to help screen [CHAR LIMIT=NONE]-->
<string name="support_sign_in_required_help">Can\'t access your account?</string>
<!-- Dialog title displayed before initiating real time support [CHAR LIMIT=80]-->
<string name="support_disclaimer_title">Send system information</string>
<!-- Dialog content displayed before initiating real time support [CHAR LIMIT=NONE]-->
<string name="support_disclaimer_content">To help address your issue quickly, we need system information for diagnosis.</string>
<!-- [CHAR LIMIT=60] Title of work profile setting page -->
<string name="managed_profile_settings_title">Work profile settings</string>
<!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->

View File

@@ -20,6 +20,7 @@ import android.annotation.DrawableRes;
import android.annotation.LayoutRes;
import android.annotation.StringRes;
import android.app.Activity;
import android.app.DialogFragment;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@@ -30,6 +31,7 @@ import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.overlay.SupportFeatureProvider;
import com.android.settings.support.SupportDisclaimerDialogFragment;
import java.util.ArrayList;
import java.util.List;
@@ -247,25 +249,44 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
holder.itemView.setOnClickListener(mItemClickListener);
}
/**
* Show a disclaimer dialog and start support action after disclaimer has been acknowledged.
*/
private void tryStartDisclaimerAndSupport(final @SupportFeatureProvider.SupportType int type) {
if (mSupportFeatureProvider.shouldShowDisclaimerDialog(mActivity)) {
DialogFragment fragment = SupportDisclaimerDialogFragment.newInstance(mAccount, type);
fragment.show(mActivity.getFragmentManager(), SupportDisclaimerDialogFragment.TAG);
return;
}
mSupportFeatureProvider.startSupport(mActivity, mAccount, type);
}
/**
* Click handler for starting escalation options.
*/
private final class EscalationClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
public void onClick(final View v) {
if (mAccount == null) {
switch (v.getId()) {
case android.R.id.text1: {
final Intent intent = mAccount == null
? mSupportFeatureProvider.getAccountLoginIntent()
: mSupportFeatureProvider.getSupportIntent(mActivity, mAccount, PHONE);
mActivity.startActivityForResult(intent, 0 /* requestCode */);
case android.R.id.text1:
mActivity.startActivityForResult(
mSupportFeatureProvider.getAccountLoginIntent(),
0 /* requestCode */);
break;
case android.R.id.text2:
mActivity.startActivityForResult(
mSupportFeatureProvider.getSignInHelpIntent(mActivity),
0 /* requestCode */);
break;
}
case android.R.id.text2: {
final Intent intent = mAccount == null
? mSupportFeatureProvider.getSignInHelpIntent(mActivity)
: mSupportFeatureProvider.getSupportIntent(mActivity, mAccount, CHAT);
mActivity.startActivityForResult(intent, 0 /* requestCode */);
} else {
switch (v.getId()) {
case android.R.id.text1:
tryStartDisclaimerAndSupport(PHONE);
break;
case android.R.id.text2:
tryStartDisclaimerAndSupport(CHAT);
break;
}
}
@@ -321,10 +342,14 @@ public final class SupportItemAdapter extends RecyclerView.Adapter<SupportItemAd
}
static final class Builder {
@LayoutRes private final int mType;
@DrawableRes private int mIcon;
@StringRes private int mText1;
@StringRes private int mText2;
@LayoutRes
private final int mType;
@DrawableRes
private int mIcon;
@StringRes
private int mText1;
@StringRes
private int mText2;
private String mSummary1;
private String mSummary2;
private Intent mIntent;

View File

@@ -18,6 +18,7 @@ package com.android.settings.overlay;
import android.accounts.Account;
import android.annotation.IntDef;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -57,19 +58,24 @@ public interface SupportFeatureProvider {
*/
String getEstimatedWaitTime(Context context, @SupportType int type);
/**
* Whether or not a disclaimer dialog should be displayed.
*/
boolean shouldShowDisclaimerDialog(Context context);
/**
* Returns an {@link Account} that's eligible for support options.
*/
Account getSupportEligibleAccount(Context context);
/**
* Returns an {@link Intent} that opens email support for specified account.
* Starts support activity of specified type
*
* @param context A UI Context
* @param activity Calling activity
* @param account A account returned by {@link #getSupportEligibleAccount}
* @param type The type of support account needs.
*/
Intent getSupportIntent(Context context, Account account, @SupportType int type);
void startSupport(Activity activity, Account account, @SupportType int type);
/**
* Returns an {@link Intent} that opens help and allow user get help on sign in.

View File

@@ -0,0 +1,114 @@
/*
* 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.accounts.Account;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.Spannable;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.overlay.SupportFeatureProvider;
/**
* {@link DialogFragment} for support disclaimer.
*/
public final class SupportDisclaimerDialogFragment extends DialogFragment implements
DialogInterface.OnClickListener {
public static final String TAG = "SupportDisclaimerDialog";
private static final String EXTRA_TYPE = "extra_type";
private static final String EXTRA_ACCOUNT = "extra_account";
public static SupportDisclaimerDialogFragment newInstance(Account account,
@SupportFeatureProvider.SupportType int type) {
final SupportDisclaimerDialogFragment fragment = new SupportDisclaimerDialogFragment();
final Bundle bundle = new Bundle(2);
bundle.putParcelable(SupportDisclaimerDialogFragment.EXTRA_ACCOUNT, account);
bundle.putInt(SupportDisclaimerDialogFragment.EXTRA_TYPE, type);
fragment.setArguments(bundle);
return fragment;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(R.string.support_disclaimer_title)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, null);
final View content = LayoutInflater.from(builder.getContext())
.inflate(R.layout.support_disclaimer_content, null);
final TextView disclaimer = (TextView) content.findViewById(R.id.support_disclaimer_text);
disclaimer.setMovementMethod(LinkMovementMethod.getInstance());
stripUnderlines((Spannable) disclaimer.getText());
return builder
.setView(content)
.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
final Activity activity = getActivity();
final SupportFeatureProvider supportFeatureProvider =
FeatureFactory.getFactory(activity).getSupportFeatureProvider(activity);
final Bundle bundle = getArguments();
supportFeatureProvider.startSupport(getActivity(),
(Account) bundle.getParcelable(EXTRA_ACCOUNT), bundle.getInt(EXTRA_TYPE));
}
/**
* Removes the underlines of {@link android.text.style.URLSpan}s.
*/
private static void stripUnderlines(Spannable input) {
final URLSpan[] urls = input.getSpans(0, input.length(), URLSpan.class);
for (URLSpan span : urls) {
final int start = input.getSpanStart(span);
final int end = input.getSpanEnd(span);
input.removeSpan(span);
input.setSpan(new NoUnderlineUrlSpan(span.getURL()), start, end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
/**
* A {@link URLSpan} that doesn't decorate the link with underline.
*/
public static class NoUnderlineUrlSpan extends URLSpan {
public NoUnderlineUrlSpan(String url) {
super(url);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
}
}