Home | History | Annotate | Download | only in calldetails
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.dialer.calldetails;
     18 
     19 import android.app.AlertDialog;
     20 import android.app.Dialog;
     21 import android.app.DialogFragment;
     22 import android.content.Context;
     23 import android.content.DialogInterface;
     24 import android.os.Bundle;
     25 import android.support.annotation.Nullable;
     26 import android.support.v4.util.Pair;
     27 import android.view.LayoutInflater;
     28 import android.view.View;
     29 import android.widget.TextView;
     30 import android.widget.Toast;
     31 import com.android.dialer.common.LogUtil;
     32 import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener;
     33 import com.android.dialer.common.concurrent.DialerExecutor.Worker;
     34 import com.android.dialer.common.concurrent.DialerExecutorComponent;
     35 import com.android.dialer.logging.DialerImpression;
     36 import com.android.dialer.logging.Logger;
     37 import com.android.dialer.phonenumbercache.CachedNumberLookupService;
     38 import com.android.dialer.phonenumbercache.CachedNumberLookupService.CachedContactInfo;
     39 import com.android.dialer.phonenumbercache.PhoneNumberCache;
     40 
     41 /** Dialog for reporting an inaccurate caller id information in {@link CallDetailsActivity}. */
     42 public class ReportDialogFragment extends DialogFragment {
     43 
     44   private static final String KEY_NUMBER = "number";
     45   private TextView name;
     46   private TextView numberView;
     47 
     48   private CachedNumberLookupService cachedNumberLookupService;
     49   private CachedNumberLookupService.CachedContactInfo info;
     50   private String number;
     51 
     52   public static ReportDialogFragment newInstance(String number) {
     53     ReportDialogFragment fragment = new ReportDialogFragment();
     54     Bundle bundle = new Bundle();
     55     bundle.putString(KEY_NUMBER, number);
     56     fragment.setArguments(bundle);
     57     return fragment;
     58   }
     59 
     60   @Override
     61   public void onCreate(@Nullable Bundle bundle) {
     62     super.onCreate(bundle);
     63     setRetainInstance(true);
     64     number = getArguments().getString(KEY_NUMBER);
     65     cachedNumberLookupService = PhoneNumberCache.get(getContext()).getCachedNumberLookupService();
     66   }
     67 
     68   @Override
     69   public Dialog onCreateDialog(Bundle savedInstanceState) {
     70     LayoutInflater inflater = getActivity().getLayoutInflater();
     71     View view = inflater.inflate(R.layout.caller_id_report_dialog, null, false);
     72     name = view.findViewById(R.id.name);
     73     numberView = view.findViewById(R.id.number);
     74 
     75     lookupContactInfo(number);
     76 
     77     AlertDialog reportDialog =
     78         new AlertDialog.Builder(getActivity())
     79             .setTitle(R.string.report_caller_id_dialog_title)
     80             .setPositiveButton(android.R.string.ok, (dialog, which) -> positiveClick(dialog))
     81             .setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss())
     82             .setView(view)
     83             .create();
     84 
     85     reportDialog.setOnShowListener(dialog -> onShow(getContext(), reportDialog));
     86     return reportDialog;
     87   }
     88 
     89   private void positiveClick(DialogInterface dialog) {
     90     startReportCallerIdWorker();
     91     dialog.dismiss();
     92   }
     93 
     94   private static void onShow(Context context, AlertDialog dialog) {
     95     int buttonTextColor = context.getColor(R.color.dialer_theme_color);
     96     dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(buttonTextColor);
     97     dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(buttonTextColor);
     98   }
     99 
    100   private void lookupContactInfo(String number) {
    101     Worker<String, CachedContactInfo> worker =
    102         number1 -> cachedNumberLookupService.lookupCachedContactFromNumber(getContext(), number1);
    103     SuccessListener<CachedContactInfo> successListener = this::setCachedContactInfo;
    104     DialerExecutorComponent.get(getContext())
    105         .dialerExecutorFactory()
    106         .createUiTaskBuilder(getFragmentManager(), "lookup_contact_info", worker)
    107         .onSuccess(successListener)
    108         .build()
    109         .executeParallel(number);
    110   }
    111 
    112   private void setCachedContactInfo(CachedContactInfo info) {
    113     this.info = info;
    114     if (info != null) {
    115       name.setText(info.getContactInfo().name);
    116       numberView.setText(info.getContactInfo().number);
    117     } else {
    118       numberView.setText(number);
    119       name.setVisibility(View.GONE);
    120     }
    121   }
    122 
    123   private void startReportCallerIdWorker() {
    124     Worker<Context, Pair<Context, Boolean>> worker = this::reportCallerId;
    125     SuccessListener<Pair<Context, Boolean>> successListener = this::onReportCallerId;
    126     DialerExecutorComponent.get(getContext())
    127         .dialerExecutorFactory()
    128         .createUiTaskBuilder(getFragmentManager(), "report_caller_id", worker)
    129         .onSuccess(successListener)
    130         .build()
    131         .executeParallel(getActivity());
    132   }
    133 
    134   private Pair<Context, Boolean> reportCallerId(Context context) {
    135     if (cachedNumberLookupService.reportAsInvalid(context, info)) {
    136       info.getContactInfo().isBadData = true;
    137       cachedNumberLookupService.addContact(context, info);
    138       LogUtil.d("ReportUploadTask.doInBackground", "Contact reported.");
    139       return new Pair<>(context, true);
    140     } else {
    141       return new Pair<>(context, false);
    142     }
    143   }
    144 
    145   private void onReportCallerId(Pair<Context, Boolean> output) {
    146     Context context = output.first;
    147     boolean wasReport = output.second;
    148     if (wasReport) {
    149       Logger.get(context).logImpression(DialerImpression.Type.CALLER_ID_REPORTED);
    150       Toast.makeText(context, R.string.report_caller_id_toast, Toast.LENGTH_SHORT).show();
    151     } else {
    152       Logger.get(context).logImpression(DialerImpression.Type.CALLER_ID_REPORT_FAILED);
    153       Toast.makeText(context, R.string.report_caller_id_failed, Toast.LENGTH_SHORT).show();
    154     }
    155   }
    156 
    157   @Override
    158   public void onDestroyView() {
    159     if (getDialog() != null && getRetainInstance()) {
    160       // Prevent dialog from dismissing on rotate.
    161       getDialog().setDismissMessage(null);
    162     }
    163     super.onDestroyView();
    164   }
    165 }
    166