diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index ca4799dc5..b2a8679fa 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -32,7 +32,6 @@ import android.hardware.SensorManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; -import android.os.Handler; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.telephony.PhoneStateListener; @@ -97,7 +96,6 @@ public class LinphoneManager implements SensorEventListener { private final Sensor mProximity; private final MediaScanner mMediaScanner; private Timer mTimer, mAutoAnswerTimer; - private final Handler mHandler = new Handler(); private final LinphonePreferences mPrefs; private Core mCore; @@ -109,6 +107,7 @@ public class LinphoneManager implements SensorEventListener { private boolean mCallGsmON; private boolean mProximitySensingEnabled; private boolean mHasLastCallSasBeenRejected; + private Runnable mIterateRunnable; public LinphoneManager(Context c) { mExited = false; @@ -263,7 +262,7 @@ public class LinphoneManager implements SensorEventListener { if (result == VersionUpdateCheckResult.NewVersionAvailable) { final String urlToUse = url; final String versionAv = version; - mHandler.postDelayed( + LinphoneUtils.dispatchOnUIThreadAfter( new Runnable() { @Override public void run() { @@ -450,19 +449,21 @@ public class LinphoneManager implements SensorEventListener { } mCore.start(); + + mIterateRunnable = + new Runnable() { + @Override + public void run() { + if (mCore != null) { + mCore.iterate(); + } + } + }; TimerTask lTask = new TimerTask() { @Override public void run() { - LinphoneUtils.dispatchOnUIThread( - new Runnable() { - @Override - public void run() { - if (mCore != null) { - mCore.iterate(); - } - } - }); + LinphoneUtils.dispatchOnUIThread(mIterateRunnable); } }; /*use schedule instead of scheduleAtFixedRate to avoid iterate from being call in burst after cpu wake up*/ diff --git a/app/src/main/java/org/linphone/activities/LinphoneLauncherActivity.java b/app/src/main/java/org/linphone/activities/LinphoneLauncherActivity.java index 9ccd2b58b..7b9f74939 100644 --- a/app/src/main/java/org/linphone/activities/LinphoneLauncherActivity.java +++ b/app/src/main/java/org/linphone/activities/LinphoneLauncherActivity.java @@ -23,7 +23,6 @@ import android.app.Activity; import android.content.Intent; import android.content.pm.ActivityInfo; import android.os.Bundle; -import android.os.Handler; import org.linphone.LinphoneManager; import org.linphone.LinphoneService; import org.linphone.R; @@ -31,11 +30,10 @@ import org.linphone.assistant.MenuAssistantActivity; import org.linphone.chat.ChatActivity; import org.linphone.history.HistoryActivity; import org.linphone.settings.LinphonePreferences; +import org.linphone.utils.LinphoneUtils; /** Creates LinphoneService and wait until Core is ready to start main Activity */ public class LinphoneLauncherActivity extends Activity { - private Handler mHandler; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -47,8 +45,6 @@ public class LinphoneLauncherActivity extends Activity { if (!getResources().getBoolean(R.bool.use_full_screen_image_splashscreen)) { setContentView(R.layout.launch_screen); } // Otherwise use drawable/launch_screen layer list up until first activity starts - - mHandler = new Handler(); } @Override @@ -90,7 +86,7 @@ public class LinphoneLauncherActivity extends Activity { LinphoneManager.getInstance().checkForUpdate(); } - mHandler.postDelayed( + LinphoneUtils.dispatchOnUIThreadAfter( new Runnable() { @Override public void run() { @@ -118,7 +114,7 @@ public class LinphoneLauncherActivity extends Activity { throw new RuntimeException("waiting thread sleep() has been interrupted"); } } - mHandler.post( + LinphoneUtils.dispatchOnUIThread( new Runnable() { @Override public void run() { diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index 3c33e2219..b9f1c0291 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -29,7 +29,6 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.CountDownTimer; -import android.os.Handler; import android.os.SystemClock; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -49,6 +48,7 @@ import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.drawerlayout.widget.DrawerLayout; +import java.lang.ref.WeakReference; import org.linphone.LinphoneManager; import org.linphone.LinphoneService; import org.linphone.R; @@ -84,18 +84,25 @@ public class CallActivity extends LinphoneGenericActivity private static final int WRITE_EXTERNAL_STORAGE_FOR_RECORDING = 2; private static final int CAMERA_TO_ACCEPT_UPDATE = 3; - private Handler mHandler = new Handler(); - private Runnable mHideControlsRunnable = - new Runnable() { - @Override - public void run() { - // Make sure that at the time this is executed this is still required - Call call = mCore.getCurrentCall(); - if (call != null && call.getCurrentParams().videoEnabled()) { - updateButtonsVisibility(false); - } - } - }; + private static class HideControlsRunnable implements Runnable { + private WeakReference mWeakCallActivity; + + public HideControlsRunnable(CallActivity activity) { + mWeakCallActivity = new WeakReference<>(activity); + } + + @Override + public void run() { + // Make sure that at the time this is executed this is still required + Call call = LinphoneManager.getCore().getCurrentCall(); + if (call != null && call.getCurrentParams().videoEnabled()) { + CallActivity activity = mWeakCallActivity.get(); + if (activity != null) activity.updateButtonsVisibility(false); + } + } + } + + private final HideControlsRunnable mHideControlsRunnable = new HideControlsRunnable(this); private int mPreviewX, mPreviewY; private TextureView mLocalPreview, mRemoteVideo; @@ -485,9 +492,49 @@ public class CallActivity extends LinphoneGenericActivity core.setNativeVideoWindowId(null); core.setNativePreviewWindowId(null); } + if (mZoomHelper != null) { mZoomHelper.destroy(); + mZoomHelper = null; } + if (mCallUpdateCountDownTimer != null) { + mCallUpdateCountDownTimer.cancel(); + mCallUpdateCountDownTimer = null; + } + + mCallTimer.stop(); + mCallTimer = null; + mLocalPreview = null; + mRemoteVideo = null; + mStatsFragment = null; + + mButtons = null; + mActiveCalls = null; + mContactAvatar = null; + mActiveCallHeader = null; + mConferenceHeader = null; + mCallsList = null; + mCallPausedByRemote = null; + mConferenceList = null; + mMicro = null; + mSpeaker = null; + mVideo = null; + mPause = null; + mSwitchCamera = null; + mRecordingInProgress = null; + mExtrasButtons = null; + mAddCall = null; + mTransferCall = null; + mRecordCall = null; + mConference = null; + mAudioRoute = null; + mRouteEarpiece = null; + mRouteSpeaker = null; + mRouteBluetooth = null; + mContactName = null; + mMissedMessages = null; + mVideoInviteInProgress = null; + mCallUpdateDialog = null; super.onDestroy(); } @@ -588,8 +635,9 @@ public class CallActivity extends LinphoneGenericActivity @Override public void resetCallControlsHidingTimer() { - mHandler.removeCallbacks(mHideControlsRunnable); - mHandler.postDelayed(mHideControlsRunnable, SECONDS_BEFORE_HIDING_CONTROLS); + LinphoneUtils.removeFromUIThreadDispatcher(mHideControlsRunnable); + LinphoneUtils.dispatchOnUIThreadAfter( + mHideControlsRunnable, SECONDS_BEFORE_HIDING_CONTROLS); } // BUTTONS @@ -742,7 +790,7 @@ public class CallActivity extends LinphoneGenericActivity LinphoneManager.getInstance().enableProximitySensing(!videoEnabled); if (!videoEnabled) { - mHandler.removeCallbacks(mHideControlsRunnable); + LinphoneUtils.removeFromUIThreadDispatcher(mHideControlsRunnable); } } diff --git a/app/src/main/java/org/linphone/call/CallStatsChildViewHolder.java b/app/src/main/java/org/linphone/call/CallStatsChildViewHolder.java index 83c5f27e3..fd2306337 100644 --- a/app/src/main/java/org/linphone/call/CallStatsChildViewHolder.java +++ b/app/src/main/java/org/linphone/call/CallStatsChildViewHolder.java @@ -20,7 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import android.content.Context; -import android.os.Handler; import android.text.Html; import android.view.View; import android.widget.TextView; @@ -37,11 +36,11 @@ import org.linphone.core.CallParams; import org.linphone.core.CallStats; import org.linphone.core.PayloadType; import org.linphone.core.StreamType; +import org.linphone.utils.LinphoneUtils; public class CallStatsChildViewHolder { private Timer mTimer; private Call mCall; - private final Handler mHandler = new Handler(); private CallListenerStub mListener; private HashMap mEncoderTexts; private HashMap mDecoderTexts; @@ -170,7 +169,7 @@ public class CallStatsChildViewHolder { return; } - mHandler.post( + LinphoneUtils.dispatchOnUIThread( new Runnable() { @Override public void run() { diff --git a/app/src/main/java/org/linphone/call/CallStatusBarFragment.java b/app/src/main/java/org/linphone/call/CallStatusBarFragment.java index b3656392d..44ed8a206 100644 --- a/app/src/main/java/org/linphone/call/CallStatusBarFragment.java +++ b/app/src/main/java/org/linphone/call/CallStatusBarFragment.java @@ -25,7 +25,6 @@ import android.content.Context; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -46,9 +45,9 @@ import org.linphone.core.ProxyConfig; import org.linphone.core.RegistrationState; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; +import org.linphone.utils.LinphoneUtils; public class CallStatusBarFragment extends Fragment { - private final Handler mRefreshHandler = new Handler(); private TextView mStatusText; private ImageView mStatusLed, mCallQuality, mEncryption; private Runnable mCallQualityUpdater; @@ -191,7 +190,7 @@ public class CallStatusBarFragment extends Fragment { } if (mCallQualityUpdater != null) { - mRefreshHandler.removeCallbacks(mCallQualityUpdater); + LinphoneUtils.removeFromUIThreadDispatcher(mCallQualityUpdater); mCallQualityUpdater = null; } } @@ -245,7 +244,7 @@ public class CallStatusBarFragment extends Fragment { } private void startCallQuality() { - mRefreshHandler.postDelayed( + LinphoneUtils.dispatchOnUIThreadAfter( mCallQualityUpdater = new Runnable() { final Call mCurrentCall = LinphoneManager.getCore().getCurrentCall(); @@ -258,7 +257,7 @@ public class CallStatusBarFragment extends Fragment { float newQuality = mCurrentCall.getCurrentQuality(); updateQualityOfSignalIcon(newQuality); - mRefreshHandler.postDelayed(this, 1000); + LinphoneUtils.dispatchOnUIThreadAfter(this, 1000); } }, 1000); diff --git a/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java b/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java index 8a1853f25..0a9b56af3 100644 --- a/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java @@ -32,8 +32,6 @@ import android.content.Intent; import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; import android.os.Parcelable; import android.provider.MediaStore; import android.text.Editable; @@ -102,7 +100,6 @@ public class ChatMessagesFragment extends Fragment private static final String INPUT_CONTENT_INFO_KEY = "COMMIT_CONTENT_INPUT_CONTENT_INFO"; private static final String COMMIT_CONTENT_FLAGS_KEY = "COMMIT_CONTENT_FLAGS"; - private final Handler mHandler = new Handler(Looper.getMainLooper()); private ImageView mCallButton; private ImageView mBackToCallButton; private ImageView mGroupInfosButton; @@ -607,7 +604,7 @@ public class ChatMessagesFragment extends Fragment } private void loadMoreData(final int totalItemsCount) { - mHandler.post( + LinphoneUtils.dispatchOnUIThread( new Runnable() { @Override public void run() { diff --git a/app/src/main/java/org/linphone/recording/Recording.java b/app/src/main/java/org/linphone/recording/Recording.java index 3e94047ca..fe6e35c30 100644 --- a/app/src/main/java/org/linphone/recording/Recording.java +++ b/app/src/main/java/org/linphone/recording/Recording.java @@ -21,7 +21,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import android.annotation.SuppressLint; import android.content.Context; -import android.os.Handler; import androidx.annotation.NonNull; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -32,6 +31,7 @@ import org.linphone.LinphoneManager; import org.linphone.core.Player; import org.linphone.core.PlayerListener; import org.linphone.core.tools.Log; +import org.linphone.utils.LinphoneUtils; class Recording implements PlayerListener, Comparable { public static final Pattern RECORD_PATTERN = @@ -42,7 +42,6 @@ class Recording implements PlayerListener, Comparable { private Date mRecordDate; private final Player mPlayer; private RecordingListener mListener; - private final Handler mHandler; private Runnable mUpdateCurrentPositionTimer; @SuppressLint("SimpleDateFormat") @@ -60,14 +59,14 @@ class Recording implements PlayerListener, Comparable { } } - mHandler = new Handler(context.getMainLooper()); mUpdateCurrentPositionTimer = new Runnable() { @Override public void run() { if (mListener != null) mListener.currentPositionChanged(getCurrentPosition()); - if (isPlaying()) mHandler.postDelayed(mUpdateCurrentPositionTimer, 20); + if (isPlaying()) + LinphoneUtils.dispatchOnUIThreadAfter(mUpdateCurrentPositionTimer, 20); } }; @@ -97,7 +96,7 @@ class Recording implements PlayerListener, Comparable { } mPlayer.start(); - mHandler.post(mUpdateCurrentPositionTimer); + LinphoneUtils.dispatchOnUIThread(mUpdateCurrentPositionTimer); } public boolean isPlaying() { diff --git a/app/src/main/java/org/linphone/utils/ActivityMonitor.java b/app/src/main/java/org/linphone/utils/ActivityMonitor.java index bcd91241a..8bf2268db 100644 --- a/app/src/main/java/org/linphone/utils/ActivityMonitor.java +++ b/app/src/main/java/org/linphone/utils/ActivityMonitor.java @@ -84,9 +84,7 @@ public class ActivityMonitor implements Application.ActivityLifecycleCallbacks { void startInactivityChecker() { if (mLastChecker != null) mLastChecker.cancel(); - LinphoneService.instance() - .handler - .postDelayed((mLastChecker = new InactivityChecker()), 2000); + LinphoneUtils.dispatchOnUIThreadAfter((mLastChecker = new InactivityChecker()), 2000); } void checkActivity() { diff --git a/app/src/main/java/org/linphone/utils/LinphoneUtils.java b/app/src/main/java/org/linphone/utils/LinphoneUtils.java index 3e2a5e729..a7ac035d1 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneUtils.java +++ b/app/src/main/java/org/linphone/utils/LinphoneUtils.java @@ -90,6 +90,14 @@ public final class LinphoneUtils { sHandler.post(r); } + public static void dispatchOnUIThreadAfter(Runnable r, long after) { + sHandler.postDelayed(r, after); + } + + public static void removeFromUIThreadDispatcher(Runnable r) { + sHandler.removeCallbacks(r); + } + private static boolean isSipAddress(String numberOrAddress) { Factory.instance().createAddress(numberOrAddress); return true;