Home | History | Annotate | Download | only in calllog
      1 /*
      2  * Copyright (C) 2013 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 package com.android.dialer.app.calllog;
     17 
     18 import android.app.Fragment;
     19 import android.app.FragmentManager;
     20 import android.content.Intent;
     21 import android.os.Bundle;
     22 import android.provider.CallLog;
     23 import android.provider.CallLog.Calls;
     24 import android.support.annotation.VisibleForTesting;
     25 import android.support.design.widget.Snackbar;
     26 import android.support.v13.app.FragmentPagerAdapter;
     27 import android.support.v4.view.ViewPager;
     28 import android.support.v7.app.ActionBar;
     29 import android.view.Menu;
     30 import android.view.MenuInflater;
     31 import android.view.MenuItem;
     32 import android.view.ViewGroup;
     33 import com.android.contacts.common.list.ViewPagerTabs;
     34 import com.android.dialer.app.DialtactsActivity;
     35 import com.android.dialer.app.R;
     36 import com.android.dialer.calldetails.CallDetailsActivity;
     37 import com.android.dialer.common.Assert;
     38 import com.android.dialer.constants.ActivityRequestCodes;
     39 import com.android.dialer.database.CallLogQueryHandler;
     40 import com.android.dialer.logging.Logger;
     41 import com.android.dialer.logging.ScreenEvent;
     42 import com.android.dialer.logging.UiAction;
     43 import com.android.dialer.performancereport.PerformanceReport;
     44 import com.android.dialer.postcall.PostCall;
     45 import com.android.dialer.util.TransactionSafeActivity;
     46 import com.android.dialer.util.ViewUtil;
     47 
     48 /** Activity for viewing call history. */
     49 public class CallLogActivity extends TransactionSafeActivity
     50     implements ViewPager.OnPageChangeListener {
     51 
     52   @VisibleForTesting static final int TAB_INDEX_ALL = 0;
     53   @VisibleForTesting static final int TAB_INDEX_MISSED = 1;
     54   private static final int TAB_INDEX_COUNT = 2;
     55   private ViewPager viewPager;
     56   private ViewPagerTabs viewPagerTabs;
     57   private ViewPagerAdapter viewPagerAdapter;
     58   private CallLogFragment allCallsFragment;
     59   private CallLogFragment missedCallsFragment;
     60   private String[] tabTitles;
     61   private boolean isResumed;
     62   private int selectedPageIndex;
     63 
     64   @Override
     65   protected void onCreate(Bundle savedInstanceState) {
     66     super.onCreate(savedInstanceState);
     67 
     68     setContentView(R.layout.call_log_activity);
     69     getWindow().setBackgroundDrawable(null);
     70 
     71     final ActionBar actionBar = getSupportActionBar();
     72     actionBar.setDisplayShowHomeEnabled(true);
     73     actionBar.setDisplayHomeAsUpEnabled(true);
     74     actionBar.setDisplayShowTitleEnabled(true);
     75     actionBar.setElevation(0);
     76 
     77     int startingTab = TAB_INDEX_ALL;
     78     final Intent intent = getIntent();
     79     if (intent != null) {
     80       final int callType = intent.getIntExtra(CallLog.Calls.EXTRA_CALL_TYPE_FILTER, -1);
     81       if (callType == CallLog.Calls.MISSED_TYPE) {
     82         startingTab = TAB_INDEX_MISSED;
     83       }
     84     }
     85     selectedPageIndex = startingTab;
     86 
     87     tabTitles = new String[TAB_INDEX_COUNT];
     88     tabTitles[0] = getString(R.string.call_log_all_title);
     89     tabTitles[1] = getString(R.string.call_log_missed_title);
     90 
     91     viewPager = (ViewPager) findViewById(R.id.call_log_pager);
     92 
     93     viewPagerAdapter = new ViewPagerAdapter(getFragmentManager());
     94     viewPager.setAdapter(viewPagerAdapter);
     95     viewPager.setOffscreenPageLimit(1);
     96     viewPager.setOnPageChangeListener(this);
     97 
     98     viewPagerTabs = (ViewPagerTabs) findViewById(R.id.viewpager_header);
     99 
    100     viewPagerTabs.setViewPager(viewPager);
    101     viewPager.setCurrentItem(startingTab);
    102   }
    103 
    104   @Override
    105   protected void onResume() {
    106     // Some calls may not be recorded (eg. from quick contact),
    107     // so we should restart recording after these calls. (Recorded call is stopped)
    108     PostCall.restartPerformanceRecordingIfARecentCallExist(this);
    109     if (!PerformanceReport.isRecording()) {
    110       PerformanceReport.startRecording();
    111     }
    112 
    113     isResumed = true;
    114     super.onResume();
    115     sendScreenViewForChildFragment();
    116   }
    117 
    118   @Override
    119   protected void onPause() {
    120     isResumed = false;
    121     super.onPause();
    122   }
    123 
    124   @Override
    125   protected void onStop() {
    126     if (!isChangingConfigurations() && viewPager != null) {
    127       // Make sure current index != selectedPageIndex
    128       selectedPageIndex = -1;
    129       updateMissedCalls(viewPager.getCurrentItem());
    130     }
    131     super.onStop();
    132   }
    133 
    134   @Override
    135   public boolean onCreateOptionsMenu(Menu menu) {
    136     final MenuInflater inflater = getMenuInflater();
    137     inflater.inflate(R.menu.call_log_options, menu);
    138     return true;
    139   }
    140 
    141   @Override
    142   public boolean onPrepareOptionsMenu(Menu menu) {
    143     final MenuItem itemDeleteAll = menu.findItem(R.id.delete_all);
    144     if (allCallsFragment != null && itemDeleteAll != null) {
    145       // If onPrepareOptionsMenu is called before fragments are loaded, don't do anything.
    146       final CallLogAdapter adapter = allCallsFragment.getAdapter();
    147       itemDeleteAll.setVisible(adapter != null && !adapter.isEmpty());
    148     }
    149     return true;
    150   }
    151 
    152   @Override
    153   public boolean onOptionsItemSelected(MenuItem item) {
    154     if (!isSafeToCommitTransactions()) {
    155       return true;
    156     }
    157 
    158     if (item.getItemId() == android.R.id.home) {
    159       PerformanceReport.recordClick(UiAction.Type.CLOSE_CALL_HISTORY_WITH_CANCEL_BUTTON);
    160       final Intent intent = new Intent(this, DialtactsActivity.class);
    161       intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    162       startActivity(intent);
    163       return true;
    164     } else if (item.getItemId() == R.id.delete_all) {
    165       ClearCallLogDialog.show(getFragmentManager());
    166       return true;
    167     }
    168     return super.onOptionsItemSelected(item);
    169   }
    170 
    171   @Override
    172   public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    173     viewPagerTabs.onPageScrolled(position, positionOffset, positionOffsetPixels);
    174   }
    175 
    176   @Override
    177   public void onPageSelected(int position) {
    178     updateMissedCalls(position);
    179     selectedPageIndex = position;
    180     if (isResumed) {
    181       sendScreenViewForChildFragment();
    182     }
    183     viewPagerTabs.onPageSelected(position);
    184   }
    185 
    186   @Override
    187   public void onPageScrollStateChanged(int state) {
    188     viewPagerTabs.onPageScrollStateChanged(state);
    189   }
    190 
    191   private void sendScreenViewForChildFragment() {
    192     Logger.get(this).logScreenView(ScreenEvent.Type.CALL_LOG_FILTER, this);
    193   }
    194 
    195   private int getRtlPosition(int position) {
    196     if (ViewUtil.isRtl()) {
    197       return viewPagerAdapter.getCount() - 1 - position;
    198     }
    199     return position;
    200   }
    201 
    202   private void updateMissedCalls(int position) {
    203     if (position == selectedPageIndex) {
    204       return;
    205     }
    206     switch (getRtlPosition(position)) {
    207       case TAB_INDEX_ALL:
    208         if (allCallsFragment != null) {
    209           allCallsFragment.markMissedCallsAsReadAndRemoveNotifications();
    210         }
    211         break;
    212       case TAB_INDEX_MISSED:
    213         if (missedCallsFragment != null) {
    214           missedCallsFragment.markMissedCallsAsReadAndRemoveNotifications();
    215         }
    216         break;
    217       default:
    218         throw Assert.createIllegalStateFailException("Invalid position: " + position);
    219     }
    220   }
    221 
    222   @Override
    223   public void onBackPressed() {
    224     PerformanceReport.recordClick(UiAction.Type.PRESS_ANDROID_BACK_BUTTON);
    225     super.onBackPressed();
    226   }
    227 
    228   /** Adapter for the view pager. */
    229   public class ViewPagerAdapter extends FragmentPagerAdapter {
    230 
    231     public ViewPagerAdapter(FragmentManager fm) {
    232       super(fm);
    233     }
    234 
    235     @Override
    236     public long getItemId(int position) {
    237       return getRtlPosition(position);
    238     }
    239 
    240     @Override
    241     public Fragment getItem(int position) {
    242       switch (getRtlPosition(position)) {
    243         case TAB_INDEX_ALL:
    244           return new CallLogFragment(
    245               CallLogQueryHandler.CALL_TYPE_ALL, true /* isCallLogActivity */);
    246         case TAB_INDEX_MISSED:
    247           return new CallLogFragment(Calls.MISSED_TYPE, true /* isCallLogActivity */);
    248         default:
    249           throw new IllegalStateException("No fragment at position " + position);
    250       }
    251     }
    252 
    253     @Override
    254     public Object instantiateItem(ViewGroup container, int position) {
    255       final CallLogFragment fragment = (CallLogFragment) super.instantiateItem(container, position);
    256       switch (getRtlPosition(position)) {
    257         case TAB_INDEX_ALL:
    258           allCallsFragment = fragment;
    259           break;
    260         case TAB_INDEX_MISSED:
    261           missedCallsFragment = fragment;
    262           break;
    263         default:
    264           throw Assert.createIllegalStateFailException("Invalid position: " + position);
    265       }
    266       return fragment;
    267     }
    268 
    269     @Override
    270     public CharSequence getPageTitle(int position) {
    271       return tabTitles[position];
    272     }
    273 
    274     @Override
    275     public int getCount() {
    276       return TAB_INDEX_COUNT;
    277     }
    278   }
    279 
    280   @Override
    281   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    282     if (requestCode == ActivityRequestCodes.DIALTACTS_CALL_DETAILS) {
    283       if (resultCode == RESULT_OK
    284           && data != null
    285           && data.getBooleanExtra(CallDetailsActivity.EXTRA_HAS_ENRICHED_CALL_DATA, false)) {
    286         String number = data.getStringExtra(CallDetailsActivity.EXTRA_PHONE_NUMBER);
    287         Snackbar.make(findViewById(R.id.calllog_frame), getString(R.string.ec_data_deleted), 5_000)
    288             .setAction(
    289                 R.string.view_conversation,
    290                 v -> startActivity(IntentProvider.getSendSmsIntentProvider(number).getIntent(this)))
    291             .setActionTextColor(getResources().getColor(R.color.dialer_snackbar_action_text_color))
    292             .show();
    293       }
    294     }
    295     super.onActivityResult(requestCode, resultCode, data);
    296   }
    297 }
    298