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}