// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using UnityEngine;
namespace Google.Play.AppUpdate.Internal
{
///
/// Forwards app update states coming from Play Core. We can't receive updates while the app is in the background,
/// so this MonoBehaviour ensures that states are updated when the app enters the foreground.
///
internal class AppUpdateHandler : MonoBehaviour
{
public event Action OnStateUpdateEvent = delegate { };
private AppUpdateStateListener _stateUpdateListener;
private AppUpdateManagerInternal _appUpdateManagerInternal;
public static AppUpdateHandler CreateInScene(AppUpdateManagerInternal appUpdateManagerInternal)
{
var componentHolder = new GameObject();
componentHolder.name = "AppUpdateHandler";
DontDestroyOnLoad(componentHolder);
var instance = componentHolder.AddComponent();
instance.Init(appUpdateManagerInternal);
return instance;
}
private void Init(AppUpdateManagerInternal appUpdateManagerInternal)
{
_appUpdateManagerInternal = appUpdateManagerInternal;
_stateUpdateListener = new AppUpdateStateListener();
_stateUpdateListener.OnStateUpdateEvent += OnStateUpdateReceived;
StartListeningForUpdates();
}
private void Start()
{
if (_appUpdateManagerInternal == null || _stateUpdateListener == null)
{
throw new InvalidOperationException("AppUpdateHandler was never initialized.");
}
}
private void OnApplicationPause(bool isPaused)
{
if (isPaused)
{
StopListeningForUpdates();
}
else
{
StartListeningForUpdates();
ForceStatesUpdate();
}
}
private void OnDestroy()
{
StopListeningForUpdates();
}
private void ForceStatesUpdate()
{
// Request the state of updates currently in progress through getAppUpdateInfo(), returning a wrapped
// Play Core task which will return an AppUpdateInfo AndroidJavaObject.
var appUpdateStateTask = _appUpdateManagerInternal.GetAppUpdateInfo();
appUpdateStateTask.RegisterOnSuccessCallback(ProcessUpdateInfo);
}
private void ProcessUpdateInfo(AndroidJavaObject javaAppUpdateInfo)
{
// Parsing AppUpdateInfo java object as an AppUpdateState since AppUpdateInfo contains all the fields for
// an AppUpdateState.
var updateState = new AppUpdateState(javaAppUpdateInfo);
OnStateUpdateEvent.Invoke(updateState);
}
private void OnStateUpdateReceived(AppUpdateState newState)
{
OnStateUpdateEvent.Invoke(newState);
}
private void StartListeningForUpdates()
{
_appUpdateManagerInternal.RegisterListener(_stateUpdateListener);
}
private void StopListeningForUpdates()
{
_appUpdateManagerInternal.UnregisterListener(_stateUpdateListener);
}
}
}