// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.gcore; import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus.ApplicationStateListener; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import java.util.HashSet; import java.util.Set; /** * Listens to application state changes. It is created lazily when we want to register a * {@link GoogleApiClientHelper}. * Thread safe. */ class LifecycleHook implements ApplicationStateListener { private static LifecycleHook sInstance; private static final Object sInstanceLock = new Object(); private static final String TAG = "GCore"; public static LifecycleHook getInstance() { synchronized (sInstanceLock) { if (sInstance == null) sInstance = new LifecycleHook(); return sInstance; } } /** * Reset static singletons. * This is needed for JUnit tests as statics are not reset between runs and previous states can * make other tests fail. It is not needed in instrumentation tests (and will be removed by * Proguard in release builds) since the application lifecycle will naturally do the work. */ public static void destroyInstanceForJUnitTests() { LifecycleHook hook; synchronized (sInstanceLock) { if (sInstance == null) return; hook = sInstance; sInstance = null; } ApplicationStatus.unregisterApplicationStateListener(hook); } private final Set<GoogleApiClientHelper> mClientHelpers; private boolean mIsApplicationVisible; private LifecycleHook() { mClientHelpers = new HashSet<GoogleApiClientHelper>(); mIsApplicationVisible = ApplicationStatus.hasVisibleActivities(); ApplicationStatus.registerApplicationStateListener(this); Log.d(TAG, "lifecycle hook registered."); } public void registerClientHelper(GoogleApiClientHelper clientHelper) { synchronized (mClientHelpers) { mClientHelpers.add(clientHelper); } } public void unregisterClientHelper(GoogleApiClientHelper clientHelper) { synchronized (mClientHelpers) { mClientHelpers.remove(clientHelper); } } @Override public void onApplicationStateChange(int newState) { Log.d(TAG, "onApplicationStateChange"); ThreadUtils.assertOnUiThread(); boolean newVisibility = ApplicationStatus.hasVisibleActivities(); if (mIsApplicationVisible == newVisibility) return; Log.d(TAG, "Application visibilty changed to %s. Updating state of %d client(s).", newVisibility, mClientHelpers.size()); mIsApplicationVisible = newVisibility; synchronized (mClientHelpers) { for (GoogleApiClientHelper clientHelper : mClientHelpers) { if (mIsApplicationVisible) clientHelper.restoreConnectedState(); else clientHelper.scheduleDisconnection(); } } } }