1 /* 2 * Copyright (C) 2016 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.app.calllog; 18 19 import android.app.KeyguardManager; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.database.ContentObserver; 23 import android.media.AudioManager; 24 import android.os.Bundle; 25 import android.provider.CallLog; 26 import android.provider.VoicemailContract; 27 import android.support.annotation.VisibleForTesting; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 import com.android.dialer.app.R; 32 import com.android.dialer.app.voicemail.VoicemailAudioManager; 33 import com.android.dialer.app.voicemail.VoicemailErrorManager; 34 import com.android.dialer.app.voicemail.VoicemailPlaybackPresenter; 35 import com.android.dialer.common.FragmentUtils; 36 import com.android.dialer.common.LogUtil; 37 import com.android.dialer.common.concurrent.DialerExecutor; 38 import com.android.dialer.common.concurrent.DialerExecutorComponent; 39 import com.android.dialer.logging.DialerImpression; 40 import com.android.dialer.logging.Logger; 41 import com.android.dialer.util.PermissionsUtil; 42 import com.android.dialer.voicemail.listui.error.VoicemailErrorMessageCreator; 43 import com.android.dialer.voicemail.listui.error.VoicemailStatus; 44 import com.android.dialer.voicemail.listui.error.VoicemailStatusWorker; 45 import java.util.List; 46 47 public class VisualVoicemailCallLogFragment extends CallLogFragment { 48 49 private final ContentObserver voicemailStatusObserver = new CustomContentObserver(); 50 private VoicemailPlaybackPresenter voicemailPlaybackPresenter; 51 private DialerExecutor<Context> preSyncVoicemailStatusCheckExecutor; 52 53 private VoicemailErrorManager voicemailErrorManager; 54 VisualVoicemailCallLogFragment()55 public VisualVoicemailCallLogFragment() { 56 super(CallLog.Calls.VOICEMAIL_TYPE); 57 } 58 59 @Override getVoicemailPlaybackPresenter()60 protected VoicemailPlaybackPresenter getVoicemailPlaybackPresenter() { 61 return voicemailPlaybackPresenter; 62 } 63 64 @Override onActivityCreated(Bundle savedInstanceState)65 public void onActivityCreated(Bundle savedInstanceState) { 66 voicemailPlaybackPresenter = 67 VoicemailPlaybackPresenter.getInstance(getActivity(), savedInstanceState); 68 if (PermissionsUtil.hasReadVoicemailPermissions(getContext()) 69 && PermissionsUtil.hasAddVoicemailPermissions(getContext())) { 70 getActivity() 71 .getContentResolver() 72 .registerContentObserver( 73 VoicemailContract.Status.CONTENT_URI, true, voicemailStatusObserver); 74 } else { 75 LogUtil.w( 76 "VisualVoicemailCallLogFragment.onActivityCreated", 77 "read voicemail permission unavailable."); 78 } 79 super.onActivityCreated(savedInstanceState); 80 81 preSyncVoicemailStatusCheckExecutor = 82 DialerExecutorComponent.get(getContext()) 83 .dialerExecutorFactory() 84 .createUiTaskBuilder( 85 getActivity().getFragmentManager(), 86 "fetchVoicemailStatus", 87 new VoicemailStatusWorker()) 88 .onSuccess(this::onPreSyncVoicemailStatusChecked) 89 .build(); 90 91 voicemailErrorManager = 92 new VoicemailErrorManager(getContext(), getAdapter().getAlertManager(), modalAlertManager); 93 94 if (PermissionsUtil.hasReadVoicemailPermissions(getContext()) 95 && PermissionsUtil.hasAddVoicemailPermissions(getContext())) { 96 getActivity() 97 .getContentResolver() 98 .registerContentObserver( 99 VoicemailContract.Status.CONTENT_URI, 100 true, 101 voicemailErrorManager.getContentObserver()); 102 } else { 103 LogUtil.w( 104 "VisualVoicemailCallLogFragment.onActivityCreated", 105 "read voicemail permission unavailable."); 106 } 107 } 108 109 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState)110 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { 111 View view = inflater.inflate(R.layout.call_log_fragment, container, false); 112 setupView(view); 113 return view; 114 } 115 116 @Override onResume()117 public void onResume() { 118 super.onResume(); 119 voicemailPlaybackPresenter.onResume(); 120 voicemailErrorManager.onResume(); 121 } 122 123 @Override onPause()124 public void onPause() { 125 voicemailPlaybackPresenter.onPause(); 126 voicemailErrorManager.onPause(); 127 super.onPause(); 128 } 129 130 @Override onDestroy()131 public void onDestroy() { 132 if (isAdded()) { 133 getActivity() 134 .getContentResolver() 135 .unregisterContentObserver(voicemailErrorManager.getContentObserver()); 136 voicemailPlaybackPresenter.onDestroy(); 137 voicemailErrorManager.onDestroy(); 138 getActivity().getContentResolver().unregisterContentObserver(voicemailStatusObserver); 139 } 140 super.onDestroy(); 141 } 142 143 @Override onSaveInstanceState(Bundle outState)144 public void onSaveInstanceState(Bundle outState) { 145 super.onSaveInstanceState(outState); 146 if (voicemailPlaybackPresenter != null) { 147 voicemailPlaybackPresenter.onSaveInstanceState(outState); 148 } 149 } 150 151 @Override fetchCalls()152 public void fetchCalls() { 153 super.fetchCalls(); 154 FragmentUtils.getParentUnsafe(this, CallLogFragmentListener.class).updateTabUnreadCounts(); 155 } 156 157 @Override onVisible()158 public void onVisible() { 159 LogUtil.enterBlock("VisualVoicemailCallLogFragment.onVisible"); 160 super.onVisible(); 161 if (getActivity() != null && preSyncVoicemailStatusCheckExecutor != null) { 162 preSyncVoicemailStatusCheckExecutor.executeParallel(getActivity()); 163 Logger.get(getActivity()).logImpression(DialerImpression.Type.VVM_TAB_VIEWED); 164 getActivity().setVolumeControlStream(VoicemailAudioManager.PLAYBACK_STREAM); 165 } 166 } 167 onPreSyncVoicemailStatusChecked(List<VoicemailStatus> statuses)168 private void onPreSyncVoicemailStatusChecked(List<VoicemailStatus> statuses) { 169 if (!shouldAutoSync(new VoicemailErrorMessageCreator(), statuses)) { 170 return; 171 } 172 173 Intent intent = new Intent(VoicemailContract.ACTION_SYNC_VOICEMAIL); 174 intent.setPackage(getActivity().getPackageName()); 175 getActivity().sendBroadcast(intent); 176 } 177 178 @VisibleForTesting shouldAutoSync( VoicemailErrorMessageCreator errorMessageCreator, List<VoicemailStatus> statuses)179 static boolean shouldAutoSync( 180 VoicemailErrorMessageCreator errorMessageCreator, List<VoicemailStatus> statuses) { 181 for (VoicemailStatus status : statuses) { 182 if (!status.isActive()) { 183 continue; 184 } 185 if (errorMessageCreator.isSyncBlockingError(status)) { 186 LogUtil.i( 187 "VisualVoicemailCallLogFragment.shouldAutoSync", "auto-sync blocked due to " + status); 188 return false; 189 } 190 } 191 return true; 192 } 193 194 @Override onNotVisible()195 public void onNotVisible() { 196 LogUtil.enterBlock("VisualVoicemailCallLogFragment.onNotVisible"); 197 super.onNotVisible(); 198 if (getActivity() != null) { 199 getActivity().setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE); 200 // onNotVisible will be called in the lock screen when the call ends 201 if (!getActivity().getSystemService(KeyguardManager.class).inKeyguardRestrictedInputMode()) { 202 LogUtil.i("VisualVoicemailCallLogFragment.onNotVisible", "clearing all new voicemails"); 203 CallLogNotificationsService.markAllNewVoicemailsAsOld(getActivity()); 204 } 205 } 206 } 207 } 208