14fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger/*
24fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * Copyright (C) 2016 The Android Open Source Project
34fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger *
44fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * Licensed under the Apache License, Version 2.0 (the "License");
54fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * you may not use this file except in compliance with the License.
64fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * You may obtain a copy of the License at
74fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger *
84fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger *      http://www.apache.org/licenses/LICENSE-2.0
94fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger *
104fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * Unless required by applicable law or agreed to in writing, software
114fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * distributed under the License is distributed on an "AS IS" BASIS,
124fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * See the License for the specific language governing permissions and
144fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * limitations under the License
154fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger */
164fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
174fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebingerpackage android.telecom.Logging;
184fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
194fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebingerimport android.telecom.Log;
204fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
214fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger/**
224fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * Encapsulates session logging in a Runnable to reduce code duplication when continuing subsessions
234fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * in a handler/thread.
244fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger * @hide
254fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger */
264fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebingerpublic abstract class Runnable {
274fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
284fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    private Session mSubsession;
294fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    private final String mSubsessionName;
300c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger    private final Object mLock;
314fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    private final java.lang.Runnable mRunnable = new java.lang.Runnable() {
324fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        @Override
334fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        public void run() {
344fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger            synchronized (mLock) {
354fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger                try {
364fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger                    Log.continueSession(mSubsession, mSubsessionName);
374fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger                    loggedRun();
384fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger                } finally {
394fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger                    if (mSubsession != null) {
404fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger                        Log.endSession();
414fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger                        mSubsession = null;
424fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger                    }
434fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger                }
444fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger            }
454fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        }
464fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    };
474fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
480c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger    /**
490c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger     * Creates a new Telecom Runnable that incorporates Session Logging into it. Useful for carrying
500c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger     * Logging Sessions through different threads as well as through handlers.
510c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger     * @param subsessionName The name that will be used in the Logs to mark this Session
520c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger     * @param lock The synchronization lock that will be used to lock loggedRun().
530c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger     */
540c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger    public Runnable(String subsessionName, Object lock) {
550c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger        if (lock == null) {
560c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger            mLock = new Object();
570c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger        } else {
580c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger            mLock = lock;
590c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger        }
604fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        mSubsessionName = subsessionName;
614fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    }
624fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
634fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    /**
644fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     * Return the runnable that will be canceled in the handler queue.
654fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     * @return Runnable object to cancel.
664fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     */
674fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    public final java.lang.Runnable getRunnableToCancel() {
684fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        return mRunnable;
694fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    }
704fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
714fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    /**
724fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     * Creates a Runnable and a logging subsession that can be used in a handler/thread. Be sure to
734fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     * call cancel() if this session is never going to be run (removed from a handler queue, for
744fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     * for example).
754fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     * @return A Java Runnable that can be used in a handler queue or thread.
764fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     */
774fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    public java.lang.Runnable prepare() {
784fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        cancel();
794fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        mSubsession = Log.createSubsession();
804fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        return mRunnable;
814fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    }
824fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
834fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    /**
844fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     * This method is used to clean up the active session if the Runnable gets removed from a
854fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     * handler and is never run.
864fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     */
874fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    public void cancel() {
884fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        synchronized (mLock) {
894fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger            Log.cancelSubsession(mSubsession);
904fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger            mSubsession = null;
914fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger        }
924fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    }
934fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
944fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    /**
954fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     * The method that will be run in the handler/thread.
964fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger     */
974fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger    abstract public void loggedRun();
984fb372fe169c6abd463a620b56dd6b05b5ff1e7aBrad Ebinger
990c3541be65fa87519a879c053a7cf4b4526be5dbBrad Ebinger}