• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
onCreate(Bundle savedInstanceState)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
onResume()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
onPause()119   protected void onPause() {
120     isResumed = false;
121     super.onPause();
122   }
123 
124   @Override
onStop()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
onCreateOptionsMenu(Menu menu)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
onPrepareOptionsMenu(Menu menu)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
onOptionsItemSelected(MenuItem item)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
onPageScrolled(int position, float positionOffset, int positionOffsetPixels)172   public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
173     viewPagerTabs.onPageScrolled(position, positionOffset, positionOffsetPixels);
174   }
175 
176   @Override
onPageSelected(int position)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
onPageScrollStateChanged(int state)187   public void onPageScrollStateChanged(int state) {
188     viewPagerTabs.onPageScrollStateChanged(state);
189   }
190 
sendScreenViewForChildFragment()191   private void sendScreenViewForChildFragment() {
192     Logger.get(this).logScreenView(ScreenEvent.Type.CALL_LOG_FILTER, this);
193   }
194 
getRtlPosition(int position)195   private int getRtlPosition(int position) {
196     if (ViewUtil.isRtl()) {
197       return viewPagerAdapter.getCount() - 1 - position;
198     }
199     return position;
200   }
201 
updateMissedCalls(int position)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
onBackPressed()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 
ViewPagerAdapter(FragmentManager fm)231     public ViewPagerAdapter(FragmentManager fm) {
232       super(fm);
233     }
234 
235     @Override
getItemId(int position)236     public long getItemId(int position) {
237       return getRtlPosition(position);
238     }
239 
240     @Override
getItem(int position)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
instantiateItem(ViewGroup container, int position)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
getPageTitle(int position)270     public CharSequence getPageTitle(int position) {
271       return tabTitles[position];
272     }
273 
274     @Override
getCount()275     public int getCount() {
276       return TAB_INDEX_COUNT;
277     }
278   }
279 
280   @Override
onActivityResult(int requestCode, int resultCode, Intent data)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