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