/* * 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.annotation.DrawableRes; import android.annotation.LayoutRes; import android.annotation.StringRes; import android.app.Activity; import android.app.DialogFragment; import android.content.Context; import android.content.Intent; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsProto; 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; import java.util.Objects; import static com.android.settings.overlay.SupportFeatureProvider.SupportType.CHAT; import static com.android.settings.overlay.SupportFeatureProvider.SupportType.PHONE; /** * Item adapter for support tiles. */ public final class SupportItemAdapter extends RecyclerView.Adapter { 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_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 SupportFeatureProvider mSupportFeatureProvider; private final View.OnClickListener mItemClickListener; private final List mSupportData; private boolean mHasInternet; private Account mAccount; public SupportItemAdapter(Activity activity, SupportFeatureProvider supportFeatureProvider, View.OnClickListener itemClickListener) { mActivity = activity; mSupportFeatureProvider = supportFeatureProvider; mItemClickListener = itemClickListener; mEscalationClickListener = new EscalationClickListener(); mSupportData = new ArrayList<>(); // Optimistically assume we have Internet access. It will be updated later to correct value. mHasInternet = true; setAccount(mSupportFeatureProvider.getSupportEligibleAccount(mActivity)); refreshData(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate( viewType, parent, false)); } @Override public void onBindViewHolder(ViewHolder holder, int position) { final SupportData data = mSupportData.get(position); switch (holder.getItemViewType()) { case TYPE_SIGN_IN_BUTTON: bindSignInPromoTile(holder, data); break; case TYPE_ESCALATION_OPTIONS: bindEscalationOptions(holder, data); break; default: bindSupportTile(holder, data); break; } } @Override public int getItemViewType(int position) { return mSupportData.get(position).type; } @Override public int getItemCount() { return mSupportData.size(); } /** * Called when a support item is clicked. */ public void onItemClicked(int position) { if (position >= 0 && position < mSupportData.size()) { final SupportData data = mSupportData.get(position); if (data.intent != null) { if (data.metricsEvent >= 0) { MetricsLogger.action(mActivity, data.metricsEvent); } mActivity.startActivityForResult(data.intent, 0); } } } public void setHasInternet(boolean hasInternet) { if (mHasInternet != hasInternet) { mHasInternet = hasInternet; refreshData(); } } public void setAccount(Account account) { if (!Objects.equals(mAccount, account)) { mAccount = account; refreshData(); } } /** * Create data for the adapter. If there is already data in the adapter, they will be * destroyed and recreated. */ private void refreshData() { mSupportData.clear(); if (mAccount == null) { addSignInPromo(); } else { addEscalationCards(); } addMoreHelpItems(); notifyDataSetChanged(); } private void addEscalationCards() { if (mHasInternet) { if (mSupportFeatureProvider.isAlwaysOperating(PHONE) || mSupportFeatureProvider.isAlwaysOperating(CHAT)) { mSupportData.add(new SupportData.Builder(mActivity, TYPE_TITLE) .setText1(R.string.support_escalation_24_7_title) .setText2(mActivity.getString(R.string.support_escalation_24_7_summary)) .build()); } else if (mSupportFeatureProvider.isOperatingNow(PHONE) || mSupportFeatureProvider.isOperatingNow(CHAT)) { mSupportData.add(new SupportData.Builder(mActivity, TYPE_TITLE) .setText1(R.string.support_escalation_title) .setText2(R.string.support_escalation_summary) .build()); } else { mSupportData.add(new SupportData.Builder(mActivity, TYPE_TITLE) .setText1(R.string.support_escalation_closed_title) .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)) { builder.setText1(R.string.support_escalation_by_phone); builder.setSummary1(mSupportFeatureProvider.getEstimatedWaitTime(mActivity, PHONE)); builder.setEnabled1(mSupportFeatureProvider.isOperatingNow(PHONE)); } if (mSupportFeatureProvider.isSupportTypeEnabled(mActivity, CHAT)) { builder.setText2(R.string.support_escalation_by_chat); builder.setSummary2(mSupportFeatureProvider.getEstimatedWaitTime(mActivity, CHAT)); builder.setEnabled2(mSupportFeatureProvider.isOperatingNow(CHAT)); } mSupportData.add(builder.build()); } private void addSignInPromo() { mSupportData.add(new SupportData.Builder(mActivity, TYPE_TITLE) .setText1(R.string.support_sign_in_required_title) .setText2(R.string.support_sign_in_required_summary) .build()); mSupportData.add(new SupportData.Builder(mActivity, TYPE_SIGN_IN_BUTTON) .setText1(R.string.support_sign_in_button_text) .setText2(R.string.support_sign_in_required_help) .build()); } private void addMoreHelpItems() { mSupportData.add(new SupportData.Builder(mActivity, TYPE_SUPPORT_TILE) .setIcon(R.drawable.ic_lightbulb_outline_24) .setText1(R.string.support_tips_and_tricks_title) .setIntent(mSupportFeatureProvider.getTipsAndTricksIntent(mActivity)) .setMetricsEvent(MetricsProto.MetricsEvent.ACTION_SUPPORT_TIPS_AND_TRICKS) .build()); mSupportData.add(new SupportData.Builder(mActivity, TYPE_SUPPORT_TILE) .setIcon(R.drawable.ic_help_24dp) .setText1(R.string.help_feedback_label) .setIntent(mSupportFeatureProvider.getHelpIntent(mActivity)) .setMetricsEvent(MetricsProto.MetricsEvent.ACTION_SUPPORT_HELP_AND_FEEDBACK) .build()); } private void bindEscalationOptions(ViewHolder holder, SupportData data) { if (data.text1 == 0) { holder.text1View.setVisibility(View.GONE); } else { holder.text1View.setText(data.text1); holder.text1View.setOnClickListener(mEscalationClickListener); holder.text1View.setEnabled(data.enabled1 && mHasInternet); holder.text1View.setVisibility(View.VISIBLE); } if (TextUtils.isEmpty(data.text2)) { holder.text2View.setVisibility(View.GONE); } else { holder.text2View.setText(data.text2); holder.text2View.setOnClickListener(mEscalationClickListener); holder.text2View.setEnabled(data.enabled2 && mHasInternet); holder.text2View.setVisibility(View.VISIBLE); } if (holder.summary1View != null) { holder.summary1View.setText(data.summary1); holder.summary1View.setVisibility(mHasInternet ? View.VISIBLE : View.GONE); } if (holder.summary2View != null) { holder.summary2View.setText(data.summary2); holder.summary2View.setVisibility(mHasInternet ? View.VISIBLE : View.GONE); } } private void bindSignInPromoTile(ViewHolder holder, SupportData data) { holder.text1View.setText(data.text1); holder.text2View.setText(data.text2); holder.text1View.setOnClickListener(mEscalationClickListener); holder.text2View.setOnClickListener(mEscalationClickListener); } private void bindSupportTile(ViewHolder holder, SupportData data) { if (holder.iconView != null) { holder.iconView.setImageResource(data.icon); } if (holder.text1View != null) { holder.text1View.setText(data.text1); } if (holder.text2View != null) { holder.text2View.setText(data.text2); } 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(final View v) { if (mAccount == null) { switch (v.getId()) { case android.R.id.text1: MetricsLogger.action(mActivity, MetricsProto.MetricsEvent.ACTION_SUPPORT_SIGN_IN); mActivity.startActivityForResult( mSupportFeatureProvider.getAccountLoginIntent(), 0 /* requestCode */); break; case android.R.id.text2: mActivity.startActivityForResult( mSupportFeatureProvider.getSignInHelpIntent(mActivity), 0 /* requestCode */); break; } } else { switch (v.getId()) { case android.R.id.text1: MetricsLogger.action(mActivity, MetricsProto.MetricsEvent.ACTION_SUPPORT_PHONE); tryStartDisclaimerAndSupport(PHONE); break; case android.R.id.text2: MetricsLogger.action(mActivity, MetricsProto.MetricsEvent.ACTION_SUPPORT_CHAT); tryStartDisclaimerAndSupport(CHAT); break; } } } } /** * {@link RecyclerView.ViewHolder} for support items. */ static final class ViewHolder extends RecyclerView.ViewHolder { final ImageView iconView; final TextView text1View; final TextView text2View; final TextView summary1View; final TextView summary2View; ViewHolder(View itemView) { super(itemView); iconView = (ImageView) itemView.findViewById(android.R.id.icon); text1View = (TextView) itemView.findViewById(android.R.id.text1); text2View = (TextView) itemView.findViewById(android.R.id.text2); summary1View = (TextView) itemView.findViewById(R.id.summary1); summary2View = (TextView) itemView.findViewById(R.id.summary2); } } /** * Data for a single support item. */ private static final class SupportData { final Intent intent; final int metricsEvent; @LayoutRes final int type; @DrawableRes final int icon; @StringRes final int text1; final CharSequence text2; final boolean enabled1; final boolean enabled2; final CharSequence summary1; final CharSequence summary2; private SupportData(Builder builder) { this.type = builder.mType; this.icon = builder.mIcon; this.text1 = builder.mText1; this.text2 = builder.mText2; this.summary1 = builder.mSummary1; this.summary2 = builder.mSummary2; this.enabled1 = builder.mEnabled1; this.enabled2 = builder.mEnabled2; this.intent = builder.mIntent; this.metricsEvent = builder.mMetricsEvent; } static final class Builder { private final Context mContext; @LayoutRes private final int mType; @DrawableRes private int mIcon; private boolean mEnabled1; private boolean mEnabled2; @StringRes private int mText1; private CharSequence mText2; private CharSequence mSummary1; private CharSequence mSummary2; private Intent mIntent; private int mMetricsEvent = -1; Builder(Context context, @LayoutRes int type) { mContext = context; mType = type; } Builder setIcon(@DrawableRes int icon) { mIcon = icon; return this; } Builder setEnabled1(boolean enabled) { mEnabled1 = enabled; return this; } Builder setText1(@StringRes int text1) { mText1 = text1; return this; } Builder setText2(@StringRes int text2) { mText2 = mContext.getString(text2); return this; } Builder setText2(CharSequence text2) { mText2 = text2; return this; } Builder setSummary1(String summary1) { mSummary1 = summary1; return this; } Builder setEnabled2(boolean enabled) { mEnabled2 = enabled; return this; } Builder setSummary2(String summary2) { mSummary2 = summary2; return this; } Builder setMetricsEvent(int metricsEvent) { mMetricsEvent = metricsEvent; return this; } Builder setIntent(Intent intent) { mIntent = intent; return this; } SupportData build() { return new SupportData(this); } } } }