chunk 2: remaining non-audio non-NewImport assets
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
namespace Google.Play.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// Errors that can be encountered while interacting with asset packs.
|
||||
/// </summary>
|
||||
public enum AssetDeliveryErrorCode
|
||||
{
|
||||
/// <summary>
|
||||
/// No error has occurred.
|
||||
/// </summary>
|
||||
NoError = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The requesting app is unavailable.
|
||||
///
|
||||
/// <para>This could be caused by multiple reasons:
|
||||
///
|
||||
/// <list type="bullet">
|
||||
/// <item><description>
|
||||
/// The app isn't published in the Play Store.
|
||||
/// </description></item>
|
||||
/// <item><description>
|
||||
/// The app version code isn't published in the Play Store. Note: an older version may exist.
|
||||
/// </description></item>
|
||||
/// <item><description>
|
||||
/// The app is only available on a testing track that the user doesn't have access to.
|
||||
/// </description></item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
AppUnavailable = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The requested asset pack is unavailable.
|
||||
/// </summary>
|
||||
BundleUnavailable = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Network error. Unable to obtain asset pack details.
|
||||
/// </summary>
|
||||
NetworkError = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Download not permitted under current device circumstances, for example the app is running in the background.
|
||||
/// </summary>
|
||||
AccessDenied = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Asset pack installation failed due to insufficient storage.
|
||||
/// </summary>
|
||||
InsufficientStorage = 7,
|
||||
|
||||
/// <summary>
|
||||
/// AssetBundle failed to load.
|
||||
/// </summary>
|
||||
AssetBundleLoadingError = 8,
|
||||
|
||||
/// <summary>
|
||||
/// The download was cancelled, likely by the user cancelling the download notification.
|
||||
/// </summary>
|
||||
Canceled = 9,
|
||||
|
||||
/// <summary>
|
||||
/// Unknown error retrieving asset pack.
|
||||
/// </summary>
|
||||
InternalError = 10,
|
||||
|
||||
/// <summary>
|
||||
/// The Play Store app is either not installed or not the official version.
|
||||
/// </summary>
|
||||
PlayStoreNotFound = 11,
|
||||
|
||||
/// <summary>
|
||||
/// Returned if <see cref="PlayAssetDelivery.ShowCellularDataConfirmation"/> is called but
|
||||
/// no asset packs are waiting for Wi-Fi.
|
||||
/// </summary>
|
||||
NetworkUnrestricted = 12,
|
||||
|
||||
/// <summary>
|
||||
/// The app isn't owned by any user on this device. An app is "owned" if it has been
|
||||
/// acquired from the Play Store.
|
||||
/// </summary>
|
||||
AppNotOwned = 13,
|
||||
|
||||
/// <summary>
|
||||
/// Returned if <see cref="PlayAssetDelivery.ShowConfirmationDialog"/> is called but
|
||||
/// no asset packs are waiting for user confirmation.
|
||||
/// </summary>
|
||||
ConfirmationNotRequired = 14,
|
||||
|
||||
/// <summary>
|
||||
/// Returned if the app was not installed by Play.
|
||||
/// </summary>
|
||||
UnrecognizedInstallation = 15,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44c7175244a2a4e2fa4c9c0b08ee011a
|
||||
timeCreated: 1549325947
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
namespace Google.Play.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum indicating the current status of an asset pack request.
|
||||
/// </summary>
|
||||
public enum AssetDeliveryStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Asset pack download is pending and will be processed soon.
|
||||
/// </summary>
|
||||
Pending = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Asset pack is being downloaded and transferred to the app's storage.
|
||||
/// </summary>
|
||||
Retrieving = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Asset pack is available on disk. For <see cref="PlayAssetPackRequest"/>s this indicates that the request is
|
||||
/// complete.
|
||||
/// </summary>
|
||||
Available = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Contained AssetBundle is being loaded.
|
||||
/// </summary>
|
||||
Loading = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Contained AssetBundle has finished loading, assets can now be loaded. For
|
||||
/// <see cref="PlayAssetBundleRequest"/>s this indicates that the request is complete.
|
||||
/// </summary>
|
||||
Loaded = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Asset pack retrieval has failed.
|
||||
/// </summary>
|
||||
Failed = 5,
|
||||
|
||||
/// <summary>
|
||||
/// Asset pack download is paused until the device acquires wifi, or the user confirms a dialog
|
||||
/// presented with <see cref="PlayAssetDelivery.ShowCellularDataConfirmation"/>.
|
||||
/// </summary>
|
||||
WaitingForWifi = 6,
|
||||
|
||||
/// <summary>
|
||||
/// Asset pack download is paused until the user provides consent. Consent can be obtained
|
||||
/// by presenting a dialog with <see cref="PlayAssetDelivery.ShowConfirmationDialog"/>.
|
||||
RequiresUserConfirmation = 7,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25b7a48b8c89b48b689489816a0541ce
|
||||
timeCreated: 1549325947
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
namespace Google.Play.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps Play Core's AssetLocation which represents the location of an Asset within an asset pack on disk.
|
||||
/// </summary>
|
||||
public abstract class AssetLocation
|
||||
{
|
||||
/// <summary>
|
||||
/// If the asset pack is stored within an apk, this will be the path to the APK containing the asset.
|
||||
/// Otherwise, this will be the path to the specific asset.
|
||||
/// </summary>
|
||||
public string Path { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the asset pack is stored within an apk this will be the offset of the asset within the APK.
|
||||
/// Otherwise, this will be 0.
|
||||
/// </summary>
|
||||
public ulong Offset { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the asset pack is stored within an apk, this will be the size of the asset within the APK.
|
||||
/// Otherwise, this will be the size of the asset file.
|
||||
/// </summary>
|
||||
public ulong Size { get; protected set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: feeabbf9c2a5434b92caedf15d713ab4
|
||||
timeCreated: 1562870112
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
namespace Google.Play.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum indicating the availability of a newer version of a particular asset pack.
|
||||
/// </summary>
|
||||
public enum AssetPackUpdateAvailability
|
||||
{
|
||||
/// <summary>
|
||||
/// The asset pack update availability is unknown.
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The asset pack is already at the latest version; there's no update available.
|
||||
/// </summary>
|
||||
UpdateNotAvailable = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The asset pack can be updated to a newer version.
|
||||
/// </summary>
|
||||
UpdateAvailable = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5783583a0d44b0ba50a7c506d800d97
|
||||
timeCreated: 1621898257
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
namespace Google.Play.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// User response to a Play controlled confirmation dialog.
|
||||
/// </summary>
|
||||
public enum ConfirmationDialogResult
|
||||
{
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The dialog was confirmed.
|
||||
/// </summary>
|
||||
Accepted = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The dialog was cancelled.
|
||||
/// </summary>
|
||||
Denied = 2,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d76ee58a8b854281a6f86e139807cb9a
|
||||
timeCreated: 1566422650
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4af3441c942f42ce8da4a213cfb959d
|
||||
folderAsset: yes
|
||||
timeCreated: 1550267071
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2019 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 Google.Play.Common.Internal;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an asynchronous operation that produces a result or an AssetDeliveryErrorCode upon completion.
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">The type of the result of the operation.</typeparam>
|
||||
internal class AssetDeliveryAsyncOperation<TResult> : PlayAsyncOperationImpl<TResult, AssetDeliveryErrorCode>
|
||||
{
|
||||
public override bool IsSuccessful
|
||||
{
|
||||
get { return IsDone && Error == AssetDeliveryErrorCode.NoError; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 567126ac059a42489a8e5a8a7639dd1c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,176 @@
|
||||
// Copyright 2019 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 System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Forwards pack state updates coming from play core.
|
||||
/// We can't receive updates while the app is in the background, so this MonoBehaviour ensures that pack states
|
||||
/// are updated when the app enters the foreground.
|
||||
/// </summary>
|
||||
internal class AssetDeliveryUpdateHandler : MonoBehaviour
|
||||
{
|
||||
public event Action<AssetPackState> OnStateUpdateEvent = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// The pack names of any AssetBundles that have received state updates after GetPackStates but before the
|
||||
/// Play Core Task has completed. This is to prevent the race condition between the task returned from
|
||||
/// <see cref="AssetPackManager.GetPackStates"/> and
|
||||
/// <see cref="AssetPackStateUpdateListener.OnStateUpdateEvent"/>.
|
||||
/// </summary>
|
||||
private readonly HashSet<string> _stateUpdatesSinceGetPackStates = new HashSet<string>();
|
||||
|
||||
private bool _gettingPackStates;
|
||||
private AssetPackStateUpdateListener _stateUpdateListener;
|
||||
private AssetPackManager _assetPackManager;
|
||||
private PlayRequestRepository _requestRepository;
|
||||
|
||||
public static AssetDeliveryUpdateHandler CreateInScene(AssetPackManager assetPackManager,
|
||||
PlayRequestRepository requestRepository)
|
||||
{
|
||||
var componentHolder = new GameObject();
|
||||
DontDestroyOnLoad(componentHolder);
|
||||
componentHolder.name = "AssetDeliveryUpdateHandler";
|
||||
|
||||
var instance = componentHolder.AddComponent<AssetDeliveryUpdateHandler>();
|
||||
instance.Init(assetPackManager, requestRepository);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void Init(AssetPackManager assetPackManager, PlayRequestRepository requestRepository)
|
||||
{
|
||||
_assetPackManager = assetPackManager;
|
||||
_requestRepository = requestRepository;
|
||||
_stateUpdateListener = new AssetPackStateUpdateListener();
|
||||
_stateUpdateListener.OnStateUpdateEvent += OnStateUpdateReceived;
|
||||
StartListeningForUpdates();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (_assetPackManager == null || _stateUpdateListener == null)
|
||||
{
|
||||
throw new InvalidOperationException("AssetDeliveryUpdateHandler was never initialized.");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplicationPause(bool isPaused)
|
||||
{
|
||||
if (isPaused)
|
||||
{
|
||||
StopListeningForUpdates();
|
||||
}
|
||||
else
|
||||
{
|
||||
StartListeningForUpdates();
|
||||
ForcePackStatesUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
StopListeningForUpdates();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asks <see cref="AssetPackManager"/> for the current pack states and routes them to
|
||||
/// <see cref="OnForcedStateUpdate"/>.
|
||||
/// </summary>
|
||||
private void ForcePackStatesUpdate()
|
||||
{
|
||||
if (_gettingPackStates)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
"ForceStateUpdate attempt ignored because the latest states are still being retrieved.");
|
||||
return;
|
||||
}
|
||||
|
||||
var activeRequestBundleNames = _requestRepository.GetActiveAssetPackNames();
|
||||
if (activeRequestBundleNames.Length == 0)
|
||||
{
|
||||
// No requests to update.
|
||||
return;
|
||||
}
|
||||
|
||||
BeginGetPackStates();
|
||||
var getPackStateTask = _assetPackManager.GetPackStates(activeRequestBundleNames);
|
||||
getPackStateTask.RegisterOnSuccessCallback(ProcessPackStates);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a java AssetPackStates object and invokes <see cref="OnForcedStateUpdate"/> for each pack
|
||||
/// state it contains.
|
||||
/// </summary>
|
||||
/// <param name="javaPackStates">A java object representing a AssetPackStates object.</param>
|
||||
private void ProcessPackStates(AndroidJavaObject javaPackStates)
|
||||
{
|
||||
try
|
||||
{
|
||||
var packStates = new AssetPackStates(javaPackStates);
|
||||
|
||||
foreach (var packStatePair in packStates.PackStates)
|
||||
{
|
||||
if (_stateUpdatesSinceGetPackStates.Contains(packStatePair.Key))
|
||||
{
|
||||
// A newer state update was received before the getPackStateTask finished.
|
||||
// Discard this state.
|
||||
continue;
|
||||
}
|
||||
|
||||
OnStateUpdateEvent.Invoke(packStatePair.Value);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
EndGetPackStates();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStateUpdateReceived(AssetPackState newState)
|
||||
{
|
||||
if (_gettingPackStates)
|
||||
{
|
||||
_stateUpdatesSinceGetPackStates.Add(newState.Name);
|
||||
}
|
||||
|
||||
OnStateUpdateEvent.Invoke(newState);
|
||||
}
|
||||
|
||||
private void BeginGetPackStates()
|
||||
{
|
||||
_gettingPackStates = true;
|
||||
}
|
||||
|
||||
private void EndGetPackStates()
|
||||
{
|
||||
_gettingPackStates = false;
|
||||
_stateUpdatesSinceGetPackStates.Clear();
|
||||
}
|
||||
|
||||
private void StartListeningForUpdates()
|
||||
{
|
||||
_assetPackManager.RegisterListener(_stateUpdateListener);
|
||||
}
|
||||
|
||||
private void StopListeningForUpdates()
|
||||
{
|
||||
_assetPackManager.UnregisterListener(_stateUpdateListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb8fa3dd35e1c4dc790b1faa33b0265c
|
||||
timeCreated: 1554494584
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
// 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.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an internal implementation for AssetLocation.
|
||||
/// </summary>
|
||||
public class AssetLocationImpl : AssetLocation
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an AssetPackLocation with all the fields of the underlying Java object, disposing the Java
|
||||
/// object in the process.
|
||||
/// </summary>
|
||||
public AssetLocationImpl(AndroidJavaObject packLocation)
|
||||
{
|
||||
using (packLocation)
|
||||
{
|
||||
Path = packLocation.Call<string>("path");
|
||||
|
||||
// Cast to uint because Unity AssetBundle loading APIs expect uint offset.
|
||||
Offset = (ulong) packLocation.Call<long>("offset");
|
||||
Size = (ulong) packLocation.Call<long>("size");
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var stateDescription = new StringBuilder();
|
||||
stateDescription.AppendFormat("path: {0}\n", Path);
|
||||
stateDescription.AppendFormat("offset: {0}\n", Offset);
|
||||
stateDescription.AppendFormat("size: {0}\n", Size);
|
||||
return stateDescription.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 006516d0561e414dbe8a46b07c73c4cc
|
||||
timeCreated: 1588294051
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright 2019 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.Text;
|
||||
using Google.Play.Core.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps Play Core's AssetPackLocation which represents the location of an asset pack on disk.
|
||||
/// </summary>
|
||||
internal class AssetPackLocation
|
||||
{
|
||||
/// <summary>
|
||||
/// The path to the directory which will contain the contents of an asset pack, if the asset pack is available
|
||||
/// on disk.
|
||||
/// </summary>
|
||||
public string Path { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the pack is installed as an APK or unpackaged into a folder on the filesystem.
|
||||
/// </summary>
|
||||
public AssetPackStorageMethod PackStorageMethod { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates an AssetPackLocation with all the fields of the underlying Java object, disposing the Java
|
||||
/// object in the process.
|
||||
/// </summary>
|
||||
public AssetPackLocation(AndroidJavaObject packLocation)
|
||||
{
|
||||
using (packLocation)
|
||||
{
|
||||
// Called with AndroidJavaObject instead of string because path may be null.
|
||||
var javaPathString = packLocation.Call<AndroidJavaObject>("path");
|
||||
Path = PlayCoreHelper.ConvertJavaString(javaPathString);
|
||||
PackStorageMethod = (AssetPackStorageMethod) packLocation.Call<int>("packStorageMethod");
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var stateDescription = new StringBuilder();
|
||||
stateDescription.AppendFormat("path: {0}\n", Path);
|
||||
stateDescription.AppendFormat("packStorageMethod: {0}\n", PackStorageMethod);
|
||||
return stateDescription.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c3389864c64846d9ae474033eba316f
|
||||
timeCreated: 1554317027
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,223 @@
|
||||
// Copyright 2019 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 Google.Play.Common;
|
||||
using Google.Play.Core.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps Play Core's AssetPackManager which manages downloads of asset packs.
|
||||
/// </summary>
|
||||
internal class AssetPackManager : IDisposable
|
||||
{
|
||||
private AndroidJavaObject _javaAssetPackManager;
|
||||
|
||||
public AssetPackManager()
|
||||
{
|
||||
const string factoryClassName = PlayCoreConstants.AssetPackPackagePrefix + "AssetPackManagerFactory";
|
||||
|
||||
using (var activity = UnityPlayerHelper.GetCurrentActivity())
|
||||
using (var assetPackManagerFactory = new AndroidJavaClass(factoryClassName))
|
||||
{
|
||||
_javaAssetPackManager = assetPackManagerFactory.CallStatic<AndroidJavaObject>("getInstance", activity);
|
||||
}
|
||||
|
||||
if (_javaAssetPackManager == null)
|
||||
{
|
||||
throw new NullReferenceException("Play Core returned null AssetPackManager");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a listener that will be called when a pack download changes state.
|
||||
/// Listeners should be subsequently unregistered using <see cref="UnregisterListener"/>
|
||||
/// </summary>
|
||||
/// <param name="listener">
|
||||
/// An AndroidJavaProxy representing a java object of class:
|
||||
/// com.google.android.play.core.assetpacks.AssetPackStateUpdateListener
|
||||
/// </param>
|
||||
public void RegisterListener(AndroidJavaProxy listener)
|
||||
{
|
||||
_javaAssetPackManager.Call("registerListener", listener);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Play Core to unregister a listener previously added using <see cref="RegisterListener"/>
|
||||
/// </summary>
|
||||
/// <param name="listener">
|
||||
/// An AndroidJavaProxy representing a java object of class:
|
||||
/// com.google.android.play.core.assetpacks.AssetPackStateUpdateListener
|
||||
/// </param>
|
||||
public void UnregisterListener(AndroidJavaProxy listener)
|
||||
{
|
||||
_javaAssetPackManager.Call("unregisterListener", listener);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Play Core to start a download for the specified asset packs.
|
||||
/// </summary>
|
||||
/// <param name="assetPackNames">The asset packs to include in the download request.</param>
|
||||
/// <returns>
|
||||
/// A wrapped Play Core task, which will return a AndroidJavaObject representing an
|
||||
/// AssetPackStates. The caller is responsible for disposing this task.
|
||||
/// </returns>
|
||||
public PlayServicesTask<AndroidJavaObject> Fetch(params string[] assetPackNames)
|
||||
{
|
||||
using (var request = BuildAssetPackList(assetPackNames))
|
||||
{
|
||||
var javaTask = _javaAssetPackManager.Call<AndroidJavaObject>("fetch", request);
|
||||
return new PlayServicesTask<AndroidJavaObject>(javaTask);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Play Core to get the states of the specified packs.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A wrapped Play Core task, which will return a AndroidJavaObject representing an
|
||||
/// AssetPackStates. The caller is responsible for disposing this task.
|
||||
/// </returns>
|
||||
public PlayServicesTask<AndroidJavaObject> GetPackStates(params string[] assetPackNames)
|
||||
{
|
||||
using (var packList = BuildAssetPackList(assetPackNames))
|
||||
{
|
||||
var javaTask = _javaAssetPackManager.Call<AndroidJavaObject>("getPackStates", packList);
|
||||
return new PlayServicesTask<AndroidJavaObject>(javaTask);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Play Core to get the location of the specified asset pack.
|
||||
/// This should contain the AssetBundle associated with the specified asset pack.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The AssetPackLocation containing the contents of the specified asset pack, or null if the most up-to-date
|
||||
/// version of this asset pack isn't available on disk.
|
||||
/// </returns>
|
||||
public AssetPackLocation GetPackLocation(string assetPackName)
|
||||
{
|
||||
var javaPackLocation = _javaAssetPackManager.Call<AndroidJavaObject>("getPackLocation", assetPackName);
|
||||
return PlayCoreHelper.IsNull(javaPackLocation) ? null : new AssetPackLocation(javaPackLocation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Play Core to get the location of the specified asset within the specified asset pack.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The AssetLocation of the specified asset or null if the most up-to-date
|
||||
/// version of this asset pack isn't available on disk.
|
||||
/// </returns>
|
||||
public AssetLocation GetAssetLocation(string assetPackName, string assetPath)
|
||||
{
|
||||
var javaAssetLocation =
|
||||
_javaAssetPackManager.Call<AndroidJavaObject>("getAssetLocation", assetPackName, assetPath);
|
||||
return PlayCoreHelper.IsNull(javaAssetLocation) ? null : new AssetLocationImpl(javaAssetLocation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests to cancel the download for a list of packs.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Returns a AndroidJavaObject representing an AssetPackStates which contains the new states
|
||||
/// of all specified assetPackNames.
|
||||
/// </returns>
|
||||
public AndroidJavaObject Cancel(params string[] assetPackNames)
|
||||
{
|
||||
using (var packList = BuildAssetPackList(assetPackNames))
|
||||
{
|
||||
var javaPackStates = _javaAssetPackManager.Call<AndroidJavaObject>("cancel", packList);
|
||||
return javaPackStates;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified asset pack from internal storage of the app.
|
||||
/// Deleted packs will not be re-downloaded after update.
|
||||
/// If the asset pack is currently being downloaded or installed, this method will not cancel the process.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A PlayServicesTask representing a Task{Void} that will only be successful if files were successfully
|
||||
/// deleted.
|
||||
/// </returns>
|
||||
public PlayServicesTask<AndroidJavaObject> RemovePack(string assetPackName)
|
||||
{
|
||||
var javaTask = _javaAssetPackManager.Call<AndroidJavaObject>("removePack", assetPackName);
|
||||
return new PlayServicesTask<AndroidJavaObject>(javaTask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Play Core to show a confirmation dialog for all downloads that are currently in the
|
||||
/// <see cref="AssetDeliveryStatus.WaitingForWifi"/> state. If the user accepts the dialog, then those
|
||||
/// packs are downloaded over cellular data.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Returns a <see cref=" PlayServicesTask{ActivityResult}"/> that completes once the dialog has been accepted,
|
||||
/// denied or closed. A successful task result contains one of the following values:
|
||||
/// <ul>
|
||||
/// <li><see cref="ActivityResult.ResultOk"/> if the user accepted.</li>
|
||||
/// <li><see cref="ActivityResult.ResultCancelled"/> if the user denied or the dialog has been closed in
|
||||
/// any other way (e.g. backpress).</li>
|
||||
/// </ul>
|
||||
/// </returns>
|
||||
public PlayServicesTask<int> ShowCellularDataConfirmation()
|
||||
{
|
||||
var task = _javaAssetPackManager.Call<AndroidJavaObject>("showCellularDataConfirmation",
|
||||
UnityPlayerHelper.GetCurrentActivity());
|
||||
return new PlayServicesTask<int>(task);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls the Java Asset Delivery SDK to show a confirmation dialog for all downloads that
|
||||
/// are currently in either the <see cref="AssetDeliveryStatus.RequiresUserConfirmation"/>
|
||||
/// state or the <see cref="AssetDeliveryStatus.WaitingForWifi"/> state.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Returns a <see cref=" PlayServicesTask{ActivityResult}"/> that completes once the dialog
|
||||
/// has been accepted, denied or closed. A successful task result contains one of the
|
||||
/// following values:
|
||||
/// <ul>
|
||||
/// <li><see cref="ActivityResult.ResultOk"/> if the user accepted.</li>
|
||||
/// <li><see cref="ActivityResult.ResultCancelled"/> if the user denied or the dialog has
|
||||
/// been closed in
|
||||
/// any other way (e.g. backpress).</li>
|
||||
/// </ul>
|
||||
/// </returns>
|
||||
public PlayServicesTask<int> ShowConfirmationDialog()
|
||||
{
|
||||
var task = _javaAssetPackManager.Call<AndroidJavaObject>("showConfirmationDialog",
|
||||
UnityPlayerHelper.GetCurrentActivity());
|
||||
return new PlayServicesTask<int>(task);
|
||||
}
|
||||
|
||||
// Returns a list of asset pack names.
|
||||
private static AndroidJavaObject BuildAssetPackList(params string[] assetPackNames)
|
||||
{
|
||||
var assetPackList = new AndroidJavaObject("java.util.ArrayList");
|
||||
foreach (var packName in assetPackNames)
|
||||
{
|
||||
assetPackList.Call<bool>("add", packName);
|
||||
}
|
||||
|
||||
return assetPackList;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_javaAssetPackManager.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04178671ed4954e2bb56c84dd03d92bc
|
||||
timeCreated: 1549564032
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2019 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.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps Play Core's AssetPackState which represents the current state of an AssetPack download.
|
||||
/// </summary>
|
||||
internal class AssetPackState
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the asset pack being downloaded.
|
||||
/// </summary>
|
||||
public string Name { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes downloaded so far.
|
||||
/// </summary>
|
||||
public long BytesDownloaded { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The total number of bytes that need to be downloaded.
|
||||
/// </summary>
|
||||
public long TotalBytesToDownload { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The status of the associated download session (downloading, downloaded, installed, etc).
|
||||
/// </summary>
|
||||
public int Status { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error code indicating the reason the download session failed.
|
||||
/// </summary>
|
||||
public int ErrorCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates an AssetPackState with all the fields of the underlying Java object, disposing the Java
|
||||
/// object in the process.
|
||||
/// </summary>
|
||||
public AssetPackState(AndroidJavaObject javaAssetPackState)
|
||||
{
|
||||
using (javaAssetPackState)
|
||||
{
|
||||
Name = javaAssetPackState.Call<string>("name");
|
||||
BytesDownloaded = javaAssetPackState.Call<long>("bytesDownloaded");
|
||||
TotalBytesToDownload = javaAssetPackState.Call<long>("totalBytesToDownload");
|
||||
Status = javaAssetPackState.Call<int>("status");
|
||||
ErrorCode = javaAssetPackState.Call<int>("errorCode");
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var stateDescription = new StringBuilder();
|
||||
stateDescription.AppendFormat("name: {0}\n", Name);
|
||||
stateDescription.AppendFormat("status: {0}\n", Status);
|
||||
stateDescription.AppendFormat("error code: {0}\n", ErrorCode);
|
||||
stateDescription.AppendFormat("bytes downloaded: {0}\n", BytesDownloaded);
|
||||
stateDescription.AppendFormat("total downloaded: {0}\n", TotalBytesToDownload);
|
||||
|
||||
return stateDescription.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9528fb96e4de4c618a777a82382ba6e
|
||||
timeCreated: 1551829374
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2019 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 Google.Play.Core.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Proxy for Play Core's AssetPackStateUpdateListener class.
|
||||
/// Used to receive callbacks from Play Core's AssetPackManager.
|
||||
/// </summary>
|
||||
internal class AssetPackStateUpdateListener : AndroidJavaProxy
|
||||
{
|
||||
public event Action<AssetPackState> OnStateUpdateEvent = delegate { };
|
||||
|
||||
public AssetPackStateUpdateListener() :
|
||||
base(PlayCoreConstants.AssetPackPackagePrefix + "AssetPackStateUpdateListener")
|
||||
{
|
||||
}
|
||||
|
||||
// Proxied java calls. Method names are camelCase to match the corresponding java methods.
|
||||
public void onStateUpdate(AndroidJavaObject assetPacksState)
|
||||
{
|
||||
var packState = new AssetPackState(assetPacksState);
|
||||
PlayCoreEventHandler.HandleEvent(() => OnStateUpdateEvent.Invoke(packState));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0dc15ad4480243fb8c18279cbae4fa6
|
||||
timeCreated: 1549327262
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright 2019 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Google.Play.Core.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps Play Core's AssetPackStates which represents the current state of all requested asset packs.
|
||||
/// </summary>
|
||||
internal class AssetPackStates
|
||||
{
|
||||
/// <summary>
|
||||
/// The total size of all requested packs in bytes.
|
||||
/// </summary>
|
||||
public long TotalBytes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary containing the download states of all requested asset packs.
|
||||
/// </summary>
|
||||
public Dictionary<string, AssetPackState> PackStates { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates an AssetPackStates with all the fields of the underlying Java object.
|
||||
/// </summary>
|
||||
public AssetPackStates(AndroidJavaObject packStates)
|
||||
{
|
||||
using (packStates)
|
||||
{
|
||||
TotalBytes = packStates.Call<long>("totalBytes");
|
||||
PackStates = ConvertPackStatesJavaMapToDictionary(packStates);
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, AssetPackState> ConvertPackStatesJavaMapToDictionary(
|
||||
AndroidJavaObject packStates)
|
||||
{
|
||||
using (var javaMap = packStates.Call<AndroidJavaObject>("packStates"))
|
||||
{
|
||||
return PlayCoreHelper.ConvertJavaMap<string, AndroidJavaObject>(javaMap)
|
||||
.ToDictionary(kvp => kvp.Key, kvp => new AssetPackState(kvp.Value));
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var stateDescription = new StringBuilder();
|
||||
stateDescription.AppendFormat("total bytes: {0}\n", TotalBytes);
|
||||
stateDescription.AppendLine("pack names: " + string.Join(", ", PackStates.Keys.ToArray()));
|
||||
|
||||
return stateDescription.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b31a4c75852ef49b18cecbbae7c55449
|
||||
timeCreated: 1549325414
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps Play Core's AssetPackLocation which represents the location of an asset pack on disk.
|
||||
/// </summary>
|
||||
internal enum AssetPackStorageMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the asset pack is unpackaged into a folder containing individual asset files.
|
||||
/// Assets contained by this asset pack can be accessed via standard File APIs.
|
||||
/// </summary>
|
||||
StorageFiles = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the asset pack is installed as APKs containing asset files.
|
||||
/// Assets contained by this asset pack can be accessed via Asset Manager.
|
||||
/// </summary>
|
||||
ApkAssets = 1,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bba029dc886c42318f5344e02844a7ea
|
||||
timeCreated: 1562870321
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,138 @@
|
||||
// Copyright 2019 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 System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
internal class PlayAssetBundleRequestImpl : PlayAssetBundleRequest
|
||||
{
|
||||
internal readonly PlayAssetPackRequestImpl PackRequest;
|
||||
|
||||
private readonly AssetDeliveryUpdateHandler _updateHandler;
|
||||
private AssetDeliveryStatus _loadingStatus;
|
||||
private AssetDeliveryErrorCode _loadingError;
|
||||
|
||||
public PlayAssetBundleRequestImpl(PlayAssetPackRequestImpl packRequest,
|
||||
AssetDeliveryUpdateHandler updateHandler)
|
||||
{
|
||||
PackRequest = packRequest;
|
||||
_updateHandler = updateHandler;
|
||||
_loadingStatus = AssetDeliveryStatus.Pending;
|
||||
_loadingError = AssetDeliveryErrorCode.NoError;
|
||||
PackRequest.Completed += OnPackRequestCompleted;
|
||||
}
|
||||
|
||||
public override event Action<PlayAssetBundleRequest> Completed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
value.Invoke(this);
|
||||
return;
|
||||
}
|
||||
|
||||
base.Completed += value;
|
||||
}
|
||||
remove { base.Completed -= value; }
|
||||
}
|
||||
|
||||
public override float DownloadProgress
|
||||
{
|
||||
get { return PackRequest.DownloadProgress; }
|
||||
}
|
||||
|
||||
public override AssetDeliveryStatus Status
|
||||
{
|
||||
get { return PackRequest.Status == AssetDeliveryStatus.Available ? _loadingStatus : PackRequest.Status; }
|
||||
}
|
||||
|
||||
public override AssetDeliveryErrorCode Error
|
||||
{
|
||||
get { return PackRequest.Error == AssetDeliveryErrorCode.NoError ? _loadingError : PackRequest.Error; }
|
||||
}
|
||||
|
||||
private void OnLoadingErrorOccurred(AssetDeliveryErrorCode errorCode)
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsDone = true;
|
||||
_loadingError = errorCode;
|
||||
_loadingStatus = AssetDeliveryStatus.Failed;
|
||||
AssetBundle = null;
|
||||
InvokeCompletedEvent();
|
||||
}
|
||||
|
||||
private void OnLoadingFinished(AssetBundle loadedAssetBundle)
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DownloadProgress = 1f;
|
||||
AssetBundle = loadedAssetBundle;
|
||||
_loadingStatus = AssetDeliveryStatus.Loaded;
|
||||
IsDone = true;
|
||||
InvokeCompletedEvent();
|
||||
}
|
||||
|
||||
private void OnPackRequestCompleted(PlayAssetPackRequest packRequest)
|
||||
{
|
||||
packRequest.Completed -= OnPackRequestCompleted;
|
||||
if (packRequest.Error == AssetDeliveryErrorCode.NoError)
|
||||
{
|
||||
StartLoadingAssetBundle();
|
||||
}
|
||||
else
|
||||
{
|
||||
IsDone = true;
|
||||
InvokeCompletedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private void StartLoadingAssetBundle()
|
||||
{
|
||||
_updateHandler.StartCoroutine(CoLoadAssetBundle());
|
||||
DownloadProgress = 1f;
|
||||
_loadingStatus = AssetDeliveryStatus.Loading;
|
||||
}
|
||||
|
||||
private IEnumerator CoLoadAssetBundle()
|
||||
{
|
||||
// Assume that the AssetBundle name equals the asset pack name.
|
||||
var bundleCreateRequest = PackRequest.LoadAssetBundleAsync(PackRequest.AssetPackName);
|
||||
yield return bundleCreateRequest;
|
||||
|
||||
if (bundleCreateRequest.assetBundle == null)
|
||||
{
|
||||
OnLoadingErrorOccurred(AssetDeliveryErrorCode.AssetBundleLoadingError);
|
||||
yield break;
|
||||
}
|
||||
|
||||
OnLoadingFinished(bundleCreateRequest.assetBundle);
|
||||
}
|
||||
|
||||
public override void AttemptCancel()
|
||||
{
|
||||
PackRequest.AttemptCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2fd44a50730bf4888ac9dfa4416e0a87
|
||||
timeCreated: 1550014332
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,464 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Google.Play.Common;
|
||||
using Google.Play.Core.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal implementation of <see cref="PlayAssetDelivery"/> methods.
|
||||
/// </summary>
|
||||
internal class PlayAssetDeliveryInternal
|
||||
{
|
||||
/// <summary>
|
||||
/// The subfolder, inside the "assets" directory, into which an asset pack file is stored.
|
||||
/// This intermediate folder can be useful for targeting (by texture compression format) at build time.
|
||||
/// </summary>
|
||||
private const string AssetPackFolderName = "assetpack";
|
||||
|
||||
private readonly AssetPackManager _assetPackManager;
|
||||
private readonly AssetDeliveryUpdateHandler _updateHandler;
|
||||
|
||||
private readonly PlayRequestRepository _requestRepository = new PlayRequestRepository();
|
||||
|
||||
internal PlayAssetDeliveryInternal()
|
||||
{
|
||||
_assetPackManager = new AssetPackManager();
|
||||
_updateHandler = AssetDeliveryUpdateHandler.CreateInScene(_assetPackManager, _requestRepository);
|
||||
_updateHandler.OnStateUpdateEvent += ProcessPackStateUpdate;
|
||||
PlayCoreEventHandler.CreateInScene();
|
||||
}
|
||||
|
||||
internal bool IsDownloaded(string assetBundleName)
|
||||
{
|
||||
return _assetPackManager.GetPackLocation(assetBundleName) != null;
|
||||
}
|
||||
|
||||
internal PlayAssetBundleRequest RetrieveAssetBundleAsyncInternal(string assetBundleName)
|
||||
{
|
||||
var request = InitializeAssetBundleRequest(assetBundleName);
|
||||
InitiateRequest(request.PackRequest);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
internal PlayAssetBundleRequest RetrieveAssetBundleAsyncInternal(string assetBundleName, bool updateIfAvailable)
|
||||
{
|
||||
var request = InitializeAssetBundleRequest(assetBundleName);
|
||||
InitiateRequest(request.PackRequest, updateIfAvailable);
|
||||
return request;
|
||||
}
|
||||
|
||||
private PlayAssetBundleRequestImpl InitializeAssetBundleRequest(string assetBundleName)
|
||||
{
|
||||
if (_requestRepository.ContainsRequest(assetBundleName))
|
||||
{
|
||||
throw new ArgumentException(string.Format("There is already an active request for AssetBundle: {0}",
|
||||
assetBundleName));
|
||||
}
|
||||
|
||||
var request = CreateAssetBundleRequest(assetBundleName);
|
||||
_requestRepository.AddAssetBundleRequest(request);
|
||||
request.Completed += req => _requestRepository.RemoveRequest(assetBundleName);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
internal PlayAssetPackRequest RetrieveAssetPackAsyncInternal(string assetPackName)
|
||||
{
|
||||
var request = GetExistingAssetPackRequest(assetPackName);
|
||||
if (request != null)
|
||||
{
|
||||
return request;
|
||||
}
|
||||
|
||||
request = InitializeAssetPackRequest(assetPackName);
|
||||
InitiateRequest(request);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
internal PlayAssetPackRequest RetrieveAssetPackAsyncInternal(string assetPackName, bool updateIfAvailable)
|
||||
{
|
||||
var request = GetExistingAssetPackRequest(assetPackName);
|
||||
if (request != null)
|
||||
{
|
||||
return request;
|
||||
}
|
||||
|
||||
request = InitializeAssetPackRequest(assetPackName);
|
||||
InitiateRequest(request, updateIfAvailable);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
internal PlayAssetPackBatchRequest RetrieveAssetPackBatchAsyncInternal(IList<string> assetPackNames)
|
||||
{
|
||||
return CreateAndInitiateBatchRequest(assetPackNames, IsDownloaded);
|
||||
}
|
||||
|
||||
internal PlayAssetPackBatchRequest RetrieveAssetPackBatchAsyncInternal(IList<string> assetPackNames,
|
||||
bool updateIfAvailable)
|
||||
{
|
||||
Func<string, bool> useAvailablePack = packName => IsCurrentVersionGoodEnough(packName, updateIfAvailable);
|
||||
return CreateAndInitiateBatchRequest(assetPackNames, useAvailablePack);
|
||||
}
|
||||
|
||||
private PlayAssetPackBatchRequest CreateAndInitiateBatchRequest(IList<string> assetPackNames,
|
||||
Func<string, bool> isPackAvailable)
|
||||
{
|
||||
if (assetPackNames.Count != assetPackNames.Distinct().Count())
|
||||
{
|
||||
throw new ArgumentException("assetPackNames contains duplicate entries");
|
||||
}
|
||||
|
||||
var activeAssetBundleRequestNames = assetPackNames
|
||||
.Where(name => _requestRepository.ContainsAssetBundleRequest(name))
|
||||
.ToArray();
|
||||
|
||||
if (activeAssetBundleRequestNames.Length != 0)
|
||||
{
|
||||
throw new ArgumentException("Cannot create a new PlayAssetPackBatchRequests because there are " +
|
||||
"already PlayAssetBundleRequests for AssetBundles: {0}",
|
||||
string.Join(", ", activeAssetBundleRequestNames));
|
||||
}
|
||||
|
||||
// A subset of assetPackNames of packs that are not available on disk.
|
||||
var unavailableAssetPackNames = new List<string>();
|
||||
var requests = new List<PlayAssetPackRequestImpl>();
|
||||
foreach (var assetPackName in assetPackNames)
|
||||
{
|
||||
PlayAssetPackRequestImpl request;
|
||||
if (_requestRepository.TryGetRequest(assetPackName, out request))
|
||||
{
|
||||
requests.Add(request);
|
||||
continue;
|
||||
}
|
||||
|
||||
request = CreateAssetPackRequest(assetPackName);
|
||||
_requestRepository.AddRequest(request);
|
||||
request.Completed += req => _requestRepository.RemoveRequest(request.AssetPackName);
|
||||
requests.Add(request);
|
||||
|
||||
if (isPackAvailable.Invoke(assetPackName))
|
||||
{
|
||||
request.OnPackAvailable();
|
||||
}
|
||||
else
|
||||
{
|
||||
unavailableAssetPackNames.Add(assetPackName);
|
||||
}
|
||||
}
|
||||
|
||||
var batchRequest = new PlayAssetPackBatchRequestImpl(requests);
|
||||
var fetchTask = _assetPackManager.Fetch(unavailableAssetPackNames.ToArray());
|
||||
fetchTask.RegisterOnSuccessCallback(javaPackStates =>
|
||||
{
|
||||
batchRequest.OnInitializedInPlayCore();
|
||||
fetchTask.Dispose();
|
||||
});
|
||||
fetchTask.RegisterOnFailureCallback((reason, errorCode) =>
|
||||
{
|
||||
Debug.LogError("Failed to retrieve asset pack batch: " + reason);
|
||||
batchRequest.OnInitializationErrorOccurred(PlayCoreTranslator.TranslatePlayCoreErrorCode(errorCode));
|
||||
fetchTask.Dispose();
|
||||
});
|
||||
|
||||
return batchRequest;
|
||||
}
|
||||
|
||||
internal PlayAsyncOperation<ConfirmationDialogResult, AssetDeliveryErrorCode>
|
||||
ShowCellularDataConfirmationInternal()
|
||||
{
|
||||
var requests = _requestRepository.GetRequestsWithStatus(AssetDeliveryStatus.WaitingForWifi);
|
||||
if (requests.Count == 0)
|
||||
{
|
||||
throw new Exception("There are no active requests waiting for wifi.");
|
||||
}
|
||||
|
||||
var task = _assetPackManager.ShowCellularDataConfirmation();
|
||||
var operation = new AssetDeliveryAsyncOperation<ConfirmationDialogResult>();
|
||||
task.RegisterOnSuccessCallback(resultCode =>
|
||||
{
|
||||
operation.SetResult(ConvertToConfirmationDialogResult(resultCode));
|
||||
task.Dispose();
|
||||
});
|
||||
task.RegisterOnFailureCallback((message, errorCode) =>
|
||||
{
|
||||
operation.SetError(PlayCoreTranslator.TranslatePlayCoreErrorCode(errorCode));
|
||||
task.Dispose();
|
||||
});
|
||||
return operation;
|
||||
}
|
||||
|
||||
internal PlayAsyncOperation<ConfirmationDialogResult, AssetDeliveryErrorCode>
|
||||
ShowConfirmationDialogInternal()
|
||||
{
|
||||
var requestsAwaitingWifi = _requestRepository.GetRequestsWithStatus(AssetDeliveryStatus.WaitingForWifi);
|
||||
var requestsAwaitingConsent = _requestRepository.GetRequestsWithStatus(AssetDeliveryStatus.RequiresUserConfirmation);
|
||||
if (requestsAwaitingWifi.Count == 0 && requestsAwaitingConsent.Count == 0)
|
||||
{
|
||||
throw new Exception("There are no active requests waiting for confirmation.");
|
||||
}
|
||||
|
||||
var task = _assetPackManager.ShowConfirmationDialog();
|
||||
var operation = new AssetDeliveryAsyncOperation<ConfirmationDialogResult>();
|
||||
task.RegisterOnSuccessCallback(resultCode =>
|
||||
{
|
||||
operation.SetResult(ConvertToConfirmationDialogResult(resultCode));
|
||||
task.Dispose();
|
||||
});
|
||||
task.RegisterOnFailureCallback((message, errorCode) =>
|
||||
{
|
||||
operation.SetError(PlayCoreTranslator.TranslatePlayCoreErrorCode(errorCode));
|
||||
task.Dispose();
|
||||
});
|
||||
return operation;
|
||||
}
|
||||
|
||||
internal PlayAsyncOperation<long, AssetDeliveryErrorCode> GetDownloadSizeInternal(string assetBundleName)
|
||||
{
|
||||
var operation = new AssetDeliveryAsyncOperation<long>();
|
||||
|
||||
if (IsInstallTimeAssetBundle(assetBundleName))
|
||||
{
|
||||
operation.SetResult(0L);
|
||||
return operation;
|
||||
}
|
||||
|
||||
var task = _assetPackManager.GetPackStates(assetBundleName);
|
||||
task.RegisterOnSuccessCallback(javaPackState =>
|
||||
{
|
||||
var assetPacks = new AssetPackStates(javaPackState);
|
||||
operation.SetResult(assetPacks.TotalBytes);
|
||||
task.Dispose();
|
||||
});
|
||||
task.RegisterOnFailureCallback((message, errorCode) =>
|
||||
{
|
||||
operation.SetError(PlayCoreTranslator.TranslatePlayCoreErrorCode(errorCode));
|
||||
task.Dispose();
|
||||
});
|
||||
return operation;
|
||||
}
|
||||
|
||||
internal PlayAsyncOperation<IDictionary<string, PlayAssetPackDownloadInfo>, AssetDeliveryErrorCode>
|
||||
GetDownloadInfoInternal(IList<string> assetPackNames)
|
||||
{
|
||||
var operation = new AssetDeliveryAsyncOperation<IDictionary<string, PlayAssetPackDownloadInfo>>();
|
||||
|
||||
var task = _assetPackManager.GetPackStates(assetPackNames.ToArray());
|
||||
task.RegisterOnSuccessCallback(javaPackStates =>
|
||||
{
|
||||
operation.SetResult(PlayAssetPackDownloadInfoImpl.FromAssetPackStates(javaPackStates));
|
||||
task.Dispose();
|
||||
});
|
||||
task.RegisterOnFailureCallback((message, errorCode) =>
|
||||
{
|
||||
operation.SetError(PlayCoreTranslator.TranslatePlayCoreErrorCode(errorCode));
|
||||
task.Dispose();
|
||||
});
|
||||
return operation;
|
||||
}
|
||||
|
||||
internal PlayAsyncOperation<VoidResult, AssetDeliveryErrorCode> RemoveAssetPackInternal(
|
||||
string assetBundleName)
|
||||
{
|
||||
var operation = new AssetDeliveryAsyncOperation<VoidResult>();
|
||||
var task = _assetPackManager.RemovePack(assetBundleName);
|
||||
task.RegisterOnSuccessCallback(javaPackState =>
|
||||
{
|
||||
operation.SetResult(new VoidResult());
|
||||
task.Dispose();
|
||||
});
|
||||
task.RegisterOnFailureCallback((message, errorCode) =>
|
||||
{
|
||||
operation.SetError(AssetDeliveryErrorCode.InternalError);
|
||||
task.Dispose();
|
||||
});
|
||||
return operation;
|
||||
}
|
||||
|
||||
private AssetLocation GetAssetLocation(string assetBundleName)
|
||||
{
|
||||
var assetPath = Path.Combine(AssetPackFolderName, assetBundleName);
|
||||
return _assetPackManager.GetAssetLocation(assetBundleName, assetPath);
|
||||
}
|
||||
|
||||
private PlayAssetPackRequestImpl GetExistingAssetPackRequest(string assetPackName)
|
||||
{
|
||||
if (_requestRepository.ContainsAssetBundleRequest(assetPackName))
|
||||
{
|
||||
throw new ArgumentException(string.Format(
|
||||
"Cannot create a new PlayAssetPackRequest because there is already an active " +
|
||||
"PlayAssetBundleRequest for asset bundle: {0}",
|
||||
assetPackName));
|
||||
}
|
||||
|
||||
PlayAssetPackRequestImpl request;
|
||||
if (_requestRepository.TryGetRequest(assetPackName, out request))
|
||||
{
|
||||
Debug.Log("Returning existing active request for " + assetPackName);
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
private PlayAssetPackRequestImpl InitializeAssetPackRequest(string assetPackName)
|
||||
{
|
||||
var request = CreateAssetPackRequest(assetPackName);
|
||||
_requestRepository.AddRequest(request);
|
||||
request.Completed += req => _requestRepository.RemoveRequest(assetPackName);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
private PlayAssetPackRequestImpl CreateAssetPackRequest(string assetPackName)
|
||||
{
|
||||
return new PlayAssetPackRequestImpl(assetPackName, _assetPackManager, _requestRepository);
|
||||
}
|
||||
|
||||
private PlayAssetBundleRequestImpl CreateAssetBundleRequest(string assetBundleName)
|
||||
{
|
||||
var packRequest = CreateAssetPackRequest(assetBundleName);
|
||||
return new PlayAssetBundleRequestImpl(packRequest, _updateHandler);
|
||||
}
|
||||
|
||||
private void InitiateRequest(PlayAssetPackRequestImpl request)
|
||||
{
|
||||
StartRequest(request, IsDownloaded(request.AssetPackName));
|
||||
}
|
||||
|
||||
private void InitiateRequest(PlayAssetPackRequestImpl request, bool updateIfAvailable)
|
||||
{
|
||||
StartRequest(request, IsCurrentVersionGoodEnough(request.AssetPackName, updateIfAvailable));
|
||||
}
|
||||
|
||||
private bool IsCurrentVersionGoodEnough(string assetPackName, bool wantNewerVersion)
|
||||
{
|
||||
var packLocation = _assetPackManager.GetPackLocation(assetPackName);
|
||||
bool isCurrentVersionGoodEnough;
|
||||
if (packLocation == null)
|
||||
{
|
||||
isCurrentVersionGoodEnough= false;
|
||||
}
|
||||
else if (packLocation.PackStorageMethod == AssetPackStorageMethod.ApkAssets)
|
||||
{
|
||||
// If the pack exists as an APK, then it is an install-time pack which cannot be updated.
|
||||
isCurrentVersionGoodEnough = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// When wantNewerVersion is true,
|
||||
// we can't use the version on disk without checking if a newer version exists.
|
||||
isCurrentVersionGoodEnough = !wantNewerVersion;
|
||||
}
|
||||
|
||||
return isCurrentVersionGoodEnough;
|
||||
}
|
||||
|
||||
private void StartRequest(PlayAssetPackRequestImpl request, bool isAvailable)
|
||||
{
|
||||
if (isAvailable)
|
||||
{
|
||||
request.OnPackAvailable();
|
||||
}
|
||||
else
|
||||
{
|
||||
var fetchTask = _assetPackManager.Fetch(request.AssetPackName);
|
||||
fetchTask.RegisterOnSuccessCallback(javaPackStates =>
|
||||
{
|
||||
request.OnInitializedInPlayCore();
|
||||
fetchTask.Dispose();
|
||||
});
|
||||
fetchTask.RegisterOnFailureCallback((reason, errorCode) =>
|
||||
{
|
||||
Debug.LogErrorFormat("Failed to retrieve asset pack: {0}", reason);
|
||||
request.OnErrorOccured(PlayCoreTranslator.TranslatePlayCoreErrorCode(errorCode));
|
||||
fetchTask.Dispose();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessPackStateUpdate(AssetPackState newState)
|
||||
{
|
||||
PlayAssetPackRequestImpl request;
|
||||
if (!_requestRepository.TryGetRequest(newState.Name, out request))
|
||||
{
|
||||
Debug.LogWarningFormat(
|
||||
"Received state update \"{0}\", that is not associated with an active request.",
|
||||
newState.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateRequest(request, newState, newState.ErrorCode);
|
||||
}
|
||||
|
||||
private void UpdateRequest(PlayAssetPackRequestImpl request, AssetPackState newState, int errorCode)
|
||||
{
|
||||
if (request.IsDone)
|
||||
{
|
||||
// Ignore pack state updates associated with completed requests.
|
||||
return;
|
||||
}
|
||||
|
||||
var assetDeliveryErrorCode = PlayCoreTranslator.TranslatePlayCoreErrorCode(errorCode);
|
||||
if (assetDeliveryErrorCode != AssetDeliveryErrorCode.NoError)
|
||||
{
|
||||
request.OnErrorOccured(assetDeliveryErrorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (newState.Status == PlayCoreTranslator.AssetPackStatus.Canceled)
|
||||
{
|
||||
request.OnErrorOccured(AssetDeliveryErrorCode.Canceled);
|
||||
return;
|
||||
}
|
||||
|
||||
request.UpdateState(PlayCoreTranslator.TranslatePlayCorePackStatus(newState.Status),
|
||||
newState.BytesDownloaded,
|
||||
newState.TotalBytesToDownload);
|
||||
}
|
||||
|
||||
private bool IsInstallTimeAssetBundle(string assetBundleName)
|
||||
{
|
||||
var packLocation = _assetPackManager.GetPackLocation(assetBundleName);
|
||||
return packLocation != null && packLocation.PackStorageMethod == AssetPackStorageMethod.ApkAssets;
|
||||
}
|
||||
|
||||
private ConfirmationDialogResult ConvertToConfirmationDialogResult(int resultCode)
|
||||
{
|
||||
ConfirmationDialogResult dialogResult;
|
||||
switch (resultCode)
|
||||
{
|
||||
case ActivityResult.ResultOk:
|
||||
dialogResult = ConfirmationDialogResult.Accepted;
|
||||
break;
|
||||
case ActivityResult.ResultCancelled:
|
||||
dialogResult = ConfirmationDialogResult.Denied;
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException("Unexpected activity result: " + resultCode);
|
||||
}
|
||||
|
||||
return dialogResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85b7e6bf8e3e4b8e91cbb5716761c9ed
|
||||
timeCreated: 1583540802
|
||||
@@ -0,0 +1,95 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
public class PlayAssetPackBatchRequestImpl : PlayAssetPackBatchRequest
|
||||
{
|
||||
private readonly HashSet<string> _completedPackNames = new HashSet<string>();
|
||||
|
||||
internal PlayAssetPackBatchRequestImpl(IEnumerable<PlayAssetPackRequestImpl> requests)
|
||||
{
|
||||
Requests = requests.ToDictionary(request => request.AssetPackName,
|
||||
request => request as PlayAssetPackRequest);
|
||||
|
||||
foreach (var entry in Requests)
|
||||
{
|
||||
entry.Value.Completed += OnChildPackCompleted;
|
||||
}
|
||||
}
|
||||
|
||||
public override event Action<PlayAssetPackBatchRequest> Completed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
value.Invoke(this);
|
||||
return;
|
||||
}
|
||||
|
||||
base.Completed += value;
|
||||
}
|
||||
remove { base.Completed -= value; }
|
||||
}
|
||||
|
||||
public void OnInitializedInPlayCore()
|
||||
{
|
||||
foreach (var request in Requests.Values)
|
||||
{
|
||||
var requestImpl = request as PlayAssetPackRequestImpl;
|
||||
if (requestImpl == null)
|
||||
{
|
||||
throw new ArgumentException("Request is not a PlayAssetPackRequestImpl");
|
||||
}
|
||||
|
||||
requestImpl.OnInitializedInPlayCore();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnInitializationErrorOccurred(AssetDeliveryErrorCode errorCode)
|
||||
{
|
||||
foreach (var request in Requests.Values)
|
||||
{
|
||||
var requestImpl = request as PlayAssetPackRequestImpl;
|
||||
if (requestImpl == null)
|
||||
{
|
||||
throw new ArgumentException("Request is not a PlayAssetPackRequestImpl");
|
||||
}
|
||||
|
||||
requestImpl.OnErrorOccured(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnChildPackCompleted(PlayAssetPackRequest request)
|
||||
{
|
||||
var requestImpl = request as PlayAssetPackRequestImpl;
|
||||
if (requestImpl == null)
|
||||
{
|
||||
throw new ArgumentException("Request is not a PlayAssetPackRequestImpl");
|
||||
}
|
||||
|
||||
_completedPackNames.Add(requestImpl.AssetPackName);
|
||||
if (_completedPackNames.Count == Requests.Count && !IsDone)
|
||||
{
|
||||
IsDone = true;
|
||||
InvokeCompletedEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a740d87a2bf1401bb24681935998ecd7
|
||||
timeCreated: 1588812080
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright 2021 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Google.Play.Core.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps the subset of Play Core's AssetPackState that pertains to asset-only updates.
|
||||
/// It contains information regarding newer versions of a particular asset pack.
|
||||
/// </summary>
|
||||
public class PlayAssetPackDownloadInfoImpl : PlayAssetPackDownloadInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a dictionary with download info, keyed by asset pack name, from the asset packs contained within a PlayCore
|
||||
/// AssetPackStates object.
|
||||
/// </summary>
|
||||
/// <param name="javaAssetPackStates">
|
||||
/// The PlayCore AssetPacksStates object containing the desired asset pack info.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A dictionary, keyed by asset pack name, containing download info about the packs within the specified
|
||||
/// AssetPackStates.
|
||||
/// </returns>
|
||||
public static IDictionary<string, PlayAssetPackDownloadInfo> FromAssetPackStates(
|
||||
AndroidJavaObject javaAssetPackStates)
|
||||
{
|
||||
using (var javaMap = javaAssetPackStates.Call<AndroidJavaObject>("packStates"))
|
||||
{
|
||||
return PlayCoreHelper.ConvertJavaMap<string, AndroidJavaObject>(javaMap)
|
||||
.ToDictionary<KeyValuePair<string, AndroidJavaObject>, string, PlayAssetPackDownloadInfo>(
|
||||
kvp => kvp.Key,
|
||||
kvp => new PlayAssetPackDownloadInfoImpl(kvp.Value));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a PlayAssetPackDownloadInfoImpl from the underlying Java AssetPackState.
|
||||
/// Disposes the Java object in the process.
|
||||
/// </summary>
|
||||
/// <param name="javaAssetPackState">
|
||||
/// The PlayCore AssetPackState Java object from which to create the PlayAssetPackDownloadInfoImpl.
|
||||
/// </param>
|
||||
public PlayAssetPackDownloadInfoImpl(AndroidJavaObject javaAssetPackState)
|
||||
{
|
||||
var javaAvailability = javaAssetPackState.Call<int>("updateAvailability");
|
||||
UpdateAvailability = UpdateAvailabilityTranslator.TranslatePlayCoreUpdateAvailability(javaAvailability);
|
||||
|
||||
DownloadSize = javaAssetPackState.Call<long>("totalBytesToDownload");
|
||||
AvailableVersionTag = javaAssetPackState.Call<string>("availableVersionTag");
|
||||
InstalledVersionTag = javaAssetPackState.Call<string>("installedVersionTag");
|
||||
|
||||
javaAssetPackState.Dispose();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var stateDescription = new StringBuilder();
|
||||
stateDescription.AppendFormat("update availability: {0}\n", UpdateAvailability);
|
||||
stateDescription.AppendFormat("available version tag: {0}\n", AvailableVersionTag);
|
||||
stateDescription.AppendFormat("installed version tag: {0}\n", InstalledVersionTag);
|
||||
|
||||
return stateDescription.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3b4bb5ea9d44aa4a75c9cebdf74dc78
|
||||
timeCreated: 1621899620
|
||||
@@ -0,0 +1,183 @@
|
||||
// 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 System.IO;
|
||||
using Google.Play.Core.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
internal class PlayAssetPackRequestImpl : PlayAssetPackRequest
|
||||
{
|
||||
public readonly string AssetPackName;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the folder within an asset pack containing all the pack's assets.
|
||||
/// Asset packs packaged using the Unity packaging API will place all their assets under this folder.
|
||||
/// </summary>
|
||||
private const string AssetPackFolderName = "assetpack";
|
||||
|
||||
private readonly AssetPackManager _assetPackManager;
|
||||
private bool _initializedInPlayCore;
|
||||
private readonly PlayRequestRepository _requestRepository;
|
||||
private Action _onInitializedInPlayCore = delegate { };
|
||||
|
||||
public PlayAssetPackRequestImpl(string assetPackName, AssetPackManager assetPackManager,
|
||||
PlayRequestRepository requestRepository)
|
||||
{
|
||||
AssetPackName = assetPackName;
|
||||
_assetPackManager = assetPackManager;
|
||||
_requestRepository = requestRepository;
|
||||
}
|
||||
|
||||
public override event Action<PlayAssetPackRequest> Completed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
value.Invoke(this);
|
||||
return;
|
||||
}
|
||||
|
||||
base.Completed += value;
|
||||
}
|
||||
remove { base.Completed -= value; }
|
||||
}
|
||||
|
||||
|
||||
public void UpdateState(AssetDeliveryStatus status, long bytesDownloaded, long totalBytesToDownload)
|
||||
{
|
||||
if (totalBytesToDownload == 0L)
|
||||
{
|
||||
bool finishedDownloading = status == AssetDeliveryStatus.Available
|
||||
|| status == AssetDeliveryStatus.Loading
|
||||
|| status == AssetDeliveryStatus.Loaded;
|
||||
DownloadProgress = finishedDownloading ? 1f : 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
DownloadProgress = bytesDownloaded / (float) totalBytesToDownload;
|
||||
}
|
||||
|
||||
Status = status;
|
||||
if (Status == AssetDeliveryStatus.Available)
|
||||
{
|
||||
OnPackAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnInitializedInPlayCore()
|
||||
{
|
||||
// Execute on the main thread in case _onInitializedInPlayCore needs to check _requestRepository.
|
||||
PlayCoreEventHandler.HandleEvent(() =>
|
||||
{
|
||||
_initializedInPlayCore = true;
|
||||
_onInitializedInPlayCore();
|
||||
});
|
||||
}
|
||||
|
||||
public void OnPackAvailable()
|
||||
{
|
||||
Status = AssetDeliveryStatus.Available;
|
||||
DownloadProgress = 1f;
|
||||
if (!IsDone)
|
||||
{
|
||||
IsDone = true;
|
||||
InvokeCompletedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnErrorOccured(AssetDeliveryErrorCode errorCode)
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsDone = true;
|
||||
Error = errorCode;
|
||||
Status = AssetDeliveryStatus.Failed;
|
||||
InvokeCompletedEvent();
|
||||
}
|
||||
|
||||
public override AssetBundleCreateRequest LoadAssetBundleAsync(string assetBundlePath)
|
||||
{
|
||||
var assetLocation = GetAssetLocation(assetBundlePath);
|
||||
if (assetLocation == null)
|
||||
{
|
||||
// Check if the assetBundlePath was relative to "assets" path rather than to the "assets/assetpack"
|
||||
// path. This may be a common error, so we check for it here and warn the developer.
|
||||
if (AssetPackFolderName.Equals(assetBundlePath.Split('/')[0]))
|
||||
{
|
||||
Debug.LogError("Failed to find the asset at path {0} within the asset pack, possibly because the" +
|
||||
" path begins with \"assetpack\".");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return AssetBundle.LoadFromFileAsync(assetLocation.Path, /* crc= */ 0, assetLocation.Offset);
|
||||
}
|
||||
|
||||
public override AssetLocation GetAssetLocation(string assetPath)
|
||||
{
|
||||
var fullAssetPath = Path.Combine(AssetPackFolderName, assetPath);
|
||||
return _assetPackManager.GetAssetLocation(AssetPackName, fullAssetPath);
|
||||
}
|
||||
|
||||
public override void AttemptCancel()
|
||||
{
|
||||
if (IsDone || Status == AssetDeliveryStatus.Loaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If play core is aware of the associated pack, then we tell play core to cancel the pack download.
|
||||
// Otherwise, we notify play core after the fetch task succeeds.
|
||||
if (_initializedInPlayCore)
|
||||
{
|
||||
CancelPlayCore();
|
||||
}
|
||||
else
|
||||
{
|
||||
DeferCancelPlayCore();
|
||||
}
|
||||
|
||||
OnErrorOccured(AssetDeliveryErrorCode.Canceled);
|
||||
}
|
||||
|
||||
private void CancelPlayCore()
|
||||
{
|
||||
_assetPackManager.Cancel(AssetPackName).Dispose();
|
||||
}
|
||||
|
||||
private void DeferCancelPlayCore()
|
||||
{
|
||||
_onInitializedInPlayCore = () =>
|
||||
{
|
||||
// Only cancel if a new request hasn't been started, to avoid cancelling the new request.
|
||||
if (_requestRepository.ContainsRequest(AssetPackName))
|
||||
{
|
||||
Debug.LogFormat("Skip canceling {0}", AssetPackName);
|
||||
}
|
||||
else
|
||||
{
|
||||
CancelPlayCore();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24b88ac66b804124b880ad0b6b6f2dcc
|
||||
timeCreated: 1588102816
|
||||
@@ -0,0 +1,131 @@
|
||||
// Copyright 2019 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 System.Collections.Generic;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Translates PlayCore's AssetPackErrorCode and AssetPackStatus Java enums into their corresponding public-facing
|
||||
/// Unity enums.
|
||||
/// </summary>
|
||||
internal static class PlayCoreTranslator
|
||||
{
|
||||
private static class AssetPackErrorCode
|
||||
{
|
||||
public const int NoError = 0;
|
||||
public const int AppUnavailable = -1;
|
||||
public const int PackUnavailable = -2;
|
||||
public const int InvalidRequest = -3;
|
||||
public const int DownloadNotFound = -4;
|
||||
public const int ApiNotAvailable = -5;
|
||||
public const int NetworkError = -6;
|
||||
public const int AccessDenied = -7;
|
||||
public const int InsufficientStorage = -10;
|
||||
public const int PlayStoreNotFound = -11;
|
||||
public const int NetworkUnrestricted = -12;
|
||||
public const int AppNotOwned = -13;
|
||||
public const int ConfirmationNotRequired = -14;
|
||||
public const int UnrecognizedInstallation = -15;
|
||||
public const int InternalError = -100;
|
||||
}
|
||||
|
||||
public static class AssetPackStatus
|
||||
{
|
||||
public const int Unknown = 0;
|
||||
public const int Pending = 1;
|
||||
public const int Downloading = 2;
|
||||
public const int Transferring = 3;
|
||||
public const int Completed = 4;
|
||||
public const int Failed = 5;
|
||||
public const int Canceled = 6;
|
||||
public const int WaitingForWifi = 7;
|
||||
public const int NotInstalled = 8;
|
||||
public const int RequiresUserConfirmation = 9;
|
||||
}
|
||||
|
||||
private static readonly Dictionary<int, AssetDeliveryErrorCode> PlayCoreToAssetDeliveryErrors =
|
||||
new Dictionary<int, AssetDeliveryErrorCode>
|
||||
{
|
||||
{AssetPackErrorCode.NoError, AssetDeliveryErrorCode.NoError},
|
||||
{AssetPackErrorCode.AppUnavailable, AssetDeliveryErrorCode.AppUnavailable},
|
||||
{AssetPackErrorCode.PackUnavailable, AssetDeliveryErrorCode.BundleUnavailable},
|
||||
{AssetPackErrorCode.InvalidRequest, AssetDeliveryErrorCode.InternalError},
|
||||
{AssetPackErrorCode.ApiNotAvailable, AssetDeliveryErrorCode.InternalError},
|
||||
{AssetPackErrorCode.DownloadNotFound, AssetDeliveryErrorCode.InternalError},
|
||||
{AssetPackErrorCode.InternalError, AssetDeliveryErrorCode.InternalError},
|
||||
{AssetPackErrorCode.NetworkError, AssetDeliveryErrorCode.NetworkError},
|
||||
{AssetPackErrorCode.AccessDenied, AssetDeliveryErrorCode.AccessDenied},
|
||||
{AssetPackErrorCode.InsufficientStorage, AssetDeliveryErrorCode.InsufficientStorage},
|
||||
{AssetPackErrorCode.PlayStoreNotFound, AssetDeliveryErrorCode.PlayStoreNotFound},
|
||||
{AssetPackErrorCode.NetworkUnrestricted, AssetDeliveryErrorCode.NetworkUnrestricted},
|
||||
{AssetPackErrorCode.AppNotOwned, AssetDeliveryErrorCode.AppNotOwned},
|
||||
{AssetPackErrorCode.ConfirmationNotRequired, AssetDeliveryErrorCode.ConfirmationNotRequired},
|
||||
{AssetPackErrorCode.UnrecognizedInstallation, AssetDeliveryErrorCode.UnrecognizedInstallation},
|
||||
};
|
||||
|
||||
private static readonly Dictionary<int, AssetDeliveryStatus> PlayCoreToAssetDeliveryStatuses
|
||||
=
|
||||
new Dictionary<int, AssetDeliveryStatus>
|
||||
{
|
||||
// Unity Asset Delivery requests are started immediately, so their status is Pending even if play core
|
||||
// has not yet set its status to Pending.
|
||||
{AssetPackStatus.NotInstalled, AssetDeliveryStatus.Pending},
|
||||
{AssetPackStatus.Pending, AssetDeliveryStatus.Pending},
|
||||
{AssetPackStatus.Downloading, AssetDeliveryStatus.Retrieving},
|
||||
{AssetPackStatus.Transferring, AssetDeliveryStatus.Retrieving},
|
||||
{AssetPackStatus.Completed, AssetDeliveryStatus.Available},
|
||||
{AssetPackStatus.WaitingForWifi, AssetDeliveryStatus.WaitingForWifi},
|
||||
{AssetPackStatus.RequiresUserConfirmation, AssetDeliveryStatus.RequiresUserConfirmation},
|
||||
{AssetPackStatus.Failed, AssetDeliveryStatus.Failed},
|
||||
{AssetPackStatus.Unknown, AssetDeliveryStatus.Failed},
|
||||
{AssetPackStatus.Canceled, AssetDeliveryStatus.Failed},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Translates Play Core's AssetPackErrorCode into its corresponding public-facing AssetDeliveryErrorCode.
|
||||
/// </summary>
|
||||
/// <exception cref="NotImplementedException">
|
||||
/// Throws if the provided error code does not have a corresponding value in AssetDeliveryErrorCode.
|
||||
/// </exception>
|
||||
public static AssetDeliveryErrorCode TranslatePlayCoreErrorCode(int assetPackErrorCode)
|
||||
{
|
||||
AssetDeliveryErrorCode translatedErrorCode;
|
||||
if (!PlayCoreToAssetDeliveryErrors.TryGetValue(assetPackErrorCode, out translatedErrorCode))
|
||||
{
|
||||
throw new NotImplementedException("Unexpected error code: " + assetPackErrorCode);
|
||||
}
|
||||
|
||||
return translatedErrorCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translates Play Core's AssetPackStatus into its corresponding public-facing AssetDeliveryStatus.
|
||||
/// </summary>
|
||||
/// <exception cref="NotImplementedException">
|
||||
/// Throws if the provided status does not have a corresponding value in AssetDeliveryStatus.
|
||||
/// </exception>
|
||||
public static AssetDeliveryStatus TranslatePlayCorePackStatus(int assetPackStatus)
|
||||
{
|
||||
AssetDeliveryStatus translatedStatus;
|
||||
if (!PlayCoreToAssetDeliveryStatuses.TryGetValue(assetPackStatus, out translatedStatus))
|
||||
{
|
||||
throw new NotImplementedException("Unexpected pack status: " + assetPackStatus);
|
||||
}
|
||||
|
||||
return translatedStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 560fb67e8b05948c8aa0b6314480534d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright 2019 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Repository for active requests related to Play Asset Delivery.
|
||||
/// </summary>
|
||||
internal class PlayRequestRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains all active requests, including the <see cref="PlayAssetPackRequestImpl"/> contained within active
|
||||
/// <see cref="PlayAssetBundleRequestImpl"/>.
|
||||
/// </summary>
|
||||
private Dictionary<string, PlayAssetPackRequestImpl> _requestsByName =
|
||||
new Dictionary<string, PlayAssetPackRequestImpl>();
|
||||
|
||||
/// <summary>
|
||||
/// Contains all active asset bundle requests. Every entry should have a corresponding entry in _requestsByName
|
||||
/// for assetBundleRequest.PackRequest.
|
||||
/// </summary>
|
||||
private Dictionary<string, PlayAssetBundleRequestImpl> _assetBundleRequestsByName =
|
||||
new Dictionary<string, PlayAssetBundleRequestImpl>();
|
||||
|
||||
public void AddAssetBundleRequest(PlayAssetBundleRequestImpl assetBundleRequest)
|
||||
{
|
||||
AddRequest(assetBundleRequest.PackRequest);
|
||||
_assetBundleRequestsByName.Add(assetBundleRequest.PackRequest.AssetPackName, assetBundleRequest);
|
||||
}
|
||||
|
||||
public void AddRequest(PlayAssetPackRequestImpl request)
|
||||
{
|
||||
_requestsByName.Add(request.AssetPackName, request);
|
||||
}
|
||||
|
||||
public void RemoveRequest(string name)
|
||||
{
|
||||
_requestsByName.Remove(name);
|
||||
_assetBundleRequestsByName.Remove(name);
|
||||
}
|
||||
|
||||
public bool TryGetAssetBundleRequest(string name, out PlayAssetBundleRequestImpl assetBundleRequest)
|
||||
{
|
||||
return _assetBundleRequestsByName.TryGetValue(name, out assetBundleRequest);
|
||||
}
|
||||
|
||||
public bool TryGetRequest(string name, out PlayAssetPackRequestImpl request)
|
||||
{
|
||||
return _requestsByName.TryGetValue(name, out request);
|
||||
}
|
||||
|
||||
public IList<PlayAssetPackRequestImpl> GetRequestsWithStatus(AssetDeliveryStatus status)
|
||||
{
|
||||
return _requestsByName.Values.Where(request => request.Status == status).ToList();
|
||||
}
|
||||
|
||||
public string[] GetActiveAssetPackNames()
|
||||
{
|
||||
return _requestsByName.Keys.ToArray();
|
||||
}
|
||||
|
||||
public bool ContainsAssetBundleRequest(string name)
|
||||
{
|
||||
return _assetBundleRequestsByName.ContainsKey(name);
|
||||
}
|
||||
|
||||
public bool ContainsRequest(string name)
|
||||
{
|
||||
return _requestsByName.ContainsKey(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d8abdc8cf0340bbaae418da558de978
|
||||
timeCreated: 1558390718
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright 2021 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 System.Collections.Generic;
|
||||
|
||||
namespace Google.Play.AssetDelivery.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Translates PlayCore's AssetPackUpdateAvailability Java enum into its corresponding public-facing
|
||||
/// Unity enum.
|
||||
/// </summary>
|
||||
internal class UpdateAvailabilityTranslator
|
||||
{
|
||||
private static class PlayCoreAssetPackUpdateAvailability
|
||||
{
|
||||
public const int Unknown = 0;
|
||||
public const int UpdateNotAvailable = 1;
|
||||
public const int UpdateAvailable = 2;
|
||||
}
|
||||
|
||||
private static readonly Dictionary<int, AssetPackUpdateAvailability> PlayCoreToAssetPackUpdateAvailability
|
||||
=
|
||||
new Dictionary<int, AssetPackUpdateAvailability>
|
||||
{
|
||||
{PlayCoreAssetPackUpdateAvailability.Unknown, AssetPackUpdateAvailability.Unknown},
|
||||
{
|
||||
PlayCoreAssetPackUpdateAvailability.UpdateNotAvailable,
|
||||
AssetPackUpdateAvailability.UpdateNotAvailable
|
||||
},
|
||||
{PlayCoreAssetPackUpdateAvailability.UpdateAvailable, AssetPackUpdateAvailability.UpdateAvailable},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Translates Play Core's AssetPackUpdateAvailability into its corresponding public-facing AssetPackUpdateAvailability.
|
||||
/// </summary>
|
||||
/// <exception cref="NotImplementedException">
|
||||
/// Throws if the provided update availability does not have a corresponding value in AssetPackUpdateAvailability.
|
||||
/// </exception>
|
||||
public static AssetPackUpdateAvailability TranslatePlayCoreUpdateAvailability(
|
||||
int assetPackUpdateAvailability)
|
||||
{
|
||||
AssetPackUpdateAvailability translatedAvailability;
|
||||
if (!PlayCoreToAssetPackUpdateAvailability.TryGetValue(assetPackUpdateAvailability,
|
||||
out translatedAvailability))
|
||||
{
|
||||
throw new NotImplementedException("Unexpected pack update availability: " +
|
||||
assetPackUpdateAvailability);
|
||||
}
|
||||
|
||||
return translatedAvailability;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 686aee5c471041bba8bfb766b774885d
|
||||
timeCreated: 1621899159
|
||||
@@ -0,0 +1,92 @@
|
||||
// Copyright 2019 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.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// A <a href="https://docs.unity3d.com/ScriptReference/CustomYieldInstruction.html">CustomYieldInstruction</a>
|
||||
/// used to monitor the asynchronous retrieval of an asset pack containing an AssetBundle.
|
||||
/// </summary>
|
||||
public abstract class PlayAssetBundleRequest : CustomYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// Progress between 0 and 1 indicating the overall download progress of this request.
|
||||
///
|
||||
/// Note: If this value is equal to 1, it does not mean that the request has completed,
|
||||
/// only that the Downloading stage is finished.
|
||||
/// </summary>
|
||||
public virtual float DownloadProgress { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error that prevented this requested from completing successfully.
|
||||
/// In the case of a successful request, this will always be <see cref="AssetDeliveryErrorCode.NoError"/>.
|
||||
/// </summary>
|
||||
public virtual AssetDeliveryErrorCode Error { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this request is in the <see cref="AssetDeliveryStatus.Loaded"/> or
|
||||
/// <see cref="AssetDeliveryStatus.Failed"/> status, false otherwise.
|
||||
/// </summary>
|
||||
public bool IsDone { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// An enum indicating the status of this request (downloading, downloaded, installed etc.)
|
||||
/// If the request completed successfully, this value should be <see cref="AssetDeliveryStatus.Loaded"/>.
|
||||
/// If an error occured, it should be <see cref="AssetDeliveryStatus.Failed"/>.
|
||||
/// </summary>
|
||||
public virtual AssetDeliveryStatus Status { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AssetBundle loaded by this request.
|
||||
/// This corresponds to the AssetBundle name passed into this request.
|
||||
/// If Status is not <see cref="AssetDeliveryStatus.Loaded"/>, this value is null.
|
||||
/// </summary>
|
||||
public AssetBundle AssetBundle { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event indicating that the request is completed. If an event handler is registered after the operation has
|
||||
/// completed, and thus after this event has been invoked, then the handler will be called synchronously.
|
||||
/// </summary>
|
||||
public virtual event Action<PlayAssetBundleRequest> Completed = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <a href="https://docs.unity3d.com/ScriptReference/CustomYieldInstruction-keepWaiting.html">CustomYieldInstruction.keepWaiting</a>
|
||||
/// property so that this request can be yielded on in a coroutine.
|
||||
/// </summary>
|
||||
public override bool keepWaiting
|
||||
{
|
||||
get { return !IsDone; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels the request if possible, setting Status to <see cref="AssetDeliveryStatus.Failed"/> and
|
||||
/// Error to <see cref="AssetDeliveryErrorCode.Canceled"/>.
|
||||
/// If the request is already <see cref="AssetDeliveryStatus.Loading"/>,
|
||||
/// <see cref="AssetDeliveryStatus.Loaded"/> or <see cref="AssetDeliveryStatus.Failed"/>, then
|
||||
/// the request is left unchanged.
|
||||
/// </summary>
|
||||
public abstract void AttemptCancel();
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="Completed"/> event.
|
||||
/// </summary>
|
||||
protected void InvokeCompletedEvent()
|
||||
{
|
||||
Completed.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d2ce5aab689a45c3afaba25494614a9
|
||||
timeCreated: 1548720072
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,248 @@
|
||||
// Copyright 2019 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 System.Collections.Generic;
|
||||
using Google.Play.AssetDelivery.Internal;
|
||||
using Google.Play.Common;
|
||||
|
||||
namespace Google.Play.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods for retrieving asset packs via the Play Asset Delivery system.
|
||||
/// </summary>
|
||||
public static class PlayAssetDelivery
|
||||
{
|
||||
private static PlayAssetDeliveryInternal _instance;
|
||||
|
||||
private static PlayAssetDeliveryInternal Instance
|
||||
{
|
||||
get { return _instance ?? (_instance = new PlayAssetDeliveryInternal()); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether or not the specified asset pack is available on disk.
|
||||
/// </summary>
|
||||
/// <param name="assetPackName">The name of the desired asset pack.</param>
|
||||
/// <returns>True if the asset pack is available on disk and false if not.</returns>
|
||||
public static bool IsDownloaded(string assetPackName)
|
||||
{
|
||||
return Instance.IsDownloaded(assetPackName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a <see cref="PlayAssetBundleRequest"/> to retrieve an asset pack containing only
|
||||
/// the specified AssetBundle.
|
||||
/// Both the AssetBundle and asset pack must share the same name. Downloads the asset pack if
|
||||
/// it isn't already available on disk.
|
||||
///
|
||||
/// After download, the contained AssetBundle is loaded into memory before the request completes.
|
||||
/// </summary>
|
||||
/// <param name="assetBundleName">The name of the requested AssetBundle.</param>
|
||||
/// <returns>A request object used to monitor the asynchronous AssetBundle retrieval.</returns>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if there is already an active request with the specified name.
|
||||
/// </exception>
|
||||
public static PlayAssetBundleRequest RetrieveAssetBundleAsync(string assetBundleName)
|
||||
{
|
||||
return Instance.RetrieveAssetBundleAsyncInternal(assetBundleName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a <see cref="PlayAssetBundleRequest"/> to retrieve an asset pack containing only
|
||||
/// the specified AssetBundle.
|
||||
/// Both the AssetBundle and asset pack must share the same name. Downloads the asset pack if
|
||||
/// it isn't already available on disk.
|
||||
///
|
||||
/// After download, the contained AssetBundle is loaded into memory before the request completes.
|
||||
/// </summary>
|
||||
/// <param name="assetBundleName">The name of the requested AssetBundle.</param>
|
||||
/// <param name="updateIfAvailable">
|
||||
/// If true and the specified pack is already installed,
|
||||
/// this method will check for a newer version and download it if available.
|
||||
/// </param>
|
||||
/// <returns>A request object used to monitor the asynchronous AssetBundle retrieval.</returns>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if there is already an active request with the specified name.
|
||||
/// </exception>
|
||||
public static PlayAssetBundleRequest RetrieveAssetBundleAsync(string assetBundleName, bool updateIfAvailable)
|
||||
{
|
||||
return Instance.RetrieveAssetBundleAsyncInternal(assetBundleName, updateIfAvailable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a <see cref="PlayAssetPackRequest"/> to retrieve the specified asset pack.
|
||||
/// Downloads the asset pack if it isn't already available on disk.
|
||||
///
|
||||
/// After download, the assets and/or AssetBundles contained in the asset pack are <b>not</b>
|
||||
/// loaded into memory. To load them see <see cref="PlayAssetPackRequest.GetAssetLocation"/>
|
||||
/// or <see cref="PlayAssetPackRequest.LoadAssetBundleAsync"/>.
|
||||
/// </summary>
|
||||
/// <param name="assetPackName">The name of the requested asset pack.</param>
|
||||
/// <returns>A request object used to monitor the asynchronous asset pack retrieval.</returns>
|
||||
public static PlayAssetPackRequest RetrieveAssetPackAsync(string assetPackName)
|
||||
{
|
||||
return Instance.RetrieveAssetPackAsyncInternal(assetPackName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a <see cref="PlayAssetPackRequest"/> to retrieve the specified asset pack.
|
||||
/// Downloads the asset pack if it isn't already available on disk.
|
||||
///
|
||||
/// After download, the assets and/or AssetBundles contained in the asset pack are <b>not</b>
|
||||
/// loaded into memory. To load them see <see cref="PlayAssetPackRequest.GetAssetLocation"/>
|
||||
/// or <see cref="PlayAssetPackRequest.LoadAssetBundleAsync"/>.
|
||||
/// </summary>
|
||||
/// <param name="assetPackName">The name of the requested asset pack.</param>
|
||||
/// <param name="updateIfAvailable">
|
||||
/// If true and the specified pack is already installed,
|
||||
/// this method will check for a newer version and download it if available.
|
||||
/// </param>
|
||||
/// <returns>A request object used to monitor the asynchronous asset pack retrieval.</returns>
|
||||
public static PlayAssetPackRequest RetrieveAssetPackAsync(string assetPackName, bool updateIfAvailable)
|
||||
{
|
||||
return Instance.RetrieveAssetPackAsyncInternal(assetPackName, updateIfAvailable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a <see cref="PlayAssetPackBatchRequest"/> to retrieve the specified asset packs.
|
||||
/// Downloads the asset packs if they aren't already available on disk.
|
||||
///
|
||||
/// After download, the assets and/or AssetBundles contained in the asset pack are <b>not</b>
|
||||
/// loaded into memory. To load them use <see cref="PlayAssetPackRequest.GetAssetLocation"/>
|
||||
/// or <see cref="PlayAssetPackRequest.LoadAssetBundleAsync"/> on the values of the
|
||||
/// <see cref="PlayAssetPackBatchRequest.Requests"/> dictionary.
|
||||
/// </summary>
|
||||
/// <param name="assetPackNames">A list of requested asset packs.</param>
|
||||
/// <returns>A request object used to monitor the asynchronous asset pack batch retrieval.</returns>
|
||||
/// <exception cref="ArgumentException">Throws if assetPackNames contains duplicate entries.</exception>
|
||||
public static PlayAssetPackBatchRequest RetrieveAssetPackBatchAsync(IList<string> assetPackNames)
|
||||
{
|
||||
return Instance.RetrieveAssetPackBatchAsyncInternal(assetPackNames);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a <see cref="PlayAssetPackBatchRequest"/> to retrieve the specified asset packs.
|
||||
/// Downloads the asset packs if they aren't already available on disk.
|
||||
///
|
||||
/// After download, the assets and/or AssetBundles contained in the asset pack are <b>not</b>
|
||||
/// loaded into memory. To load them use <see cref="PlayAssetPackRequest.GetAssetLocation"/>
|
||||
/// or <see cref="PlayAssetPackRequest.LoadAssetBundleAsync"/> on the values of the
|
||||
/// <see cref="PlayAssetPackBatchRequest.Requests"/> dictionary.
|
||||
/// </summary>
|
||||
/// <param name="assetPackNames">A list of requested asset packs.</param>
|
||||
/// <param name="updateIfAvailable">
|
||||
/// If true and any of the specified packs are already installed,
|
||||
/// this method will check for newer versions of them and download them if available.
|
||||
/// </param>
|
||||
/// <returns>A request object used to monitor the asynchronous asset pack batch retrieval.</returns>
|
||||
/// <exception cref="ArgumentException">Throws if assetPackNames contains duplicate entries.</exception>
|
||||
public static PlayAssetPackBatchRequest RetrieveAssetPackBatchAsync(IList<string> assetPackNames,
|
||||
bool updateIfAvailable)
|
||||
{
|
||||
return Instance.RetrieveAssetPackBatchAsyncInternal(assetPackNames, updateIfAvailable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a PlayAsyncOperation to determine the download size in bytes of the specified asset pack.
|
||||
/// If the specified asset pack's delivery mode is install-time, then the download size will always be 0.
|
||||
/// </summary>
|
||||
public static PlayAsyncOperation<long, AssetDeliveryErrorCode> GetDownloadSize(string assetPackName)
|
||||
{
|
||||
return Instance.GetDownloadSizeInternal(assetPackName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a PlayAsyncOperation to gather download information about the specified asset packs.
|
||||
/// This includes download size and information about asset pack updates.
|
||||
/// </summary>
|
||||
/// <param name="assetPackNames">A list of asset packs.</param>
|
||||
/// <returns>
|
||||
/// A PlayAsyncOperation with a Dictionary result keyed by asset pack name,
|
||||
/// containing download info about the specified packs.
|
||||
/// </returns>
|
||||
public static PlayAsyncOperation<IDictionary<string, PlayAssetPackDownloadInfo>, AssetDeliveryErrorCode>
|
||||
GetDownloadInfo(IList<string> assetPackNames)
|
||||
{
|
||||
return Instance.GetDownloadInfoInternal(assetPackNames);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a PlayAsyncOperation to delete the specified asset pack from internal storage.
|
||||
/// If the specified asset pack is currently being retrieved, this method will not cancel the
|
||||
/// retrieval. If the specified asset pack contains any AssetBundles that are already loaded into
|
||||
/// memory, the AssetBundles will <b>not</b> be unloaded.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An async operation object used to monitor the asset pack removal. If the files are deleted
|
||||
/// successfully or if the files don't exist, the returned operation will complete successfully.
|
||||
/// Otherwise, the operation will complete with an error code.
|
||||
/// </returns>
|
||||
public static PlayAsyncOperation<VoidResult, AssetDeliveryErrorCode> RemoveAssetPack(string assetPackName)
|
||||
{
|
||||
return Instance.RemoveAssetPackInternal(assetPackName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a confirmation dialog for all currently downloading asset packs that are
|
||||
/// <see cref="AssetDeliveryStatus.WaitingForWifi"/>.
|
||||
/// If the user accepts the dialog, then those asset packs are downloaded over cellular data.
|
||||
///
|
||||
/// A <see cref="PlayAssetBundleRequest"/> is set to <see cref="AssetDeliveryStatus.WaitingForWifi"/> if
|
||||
/// the user is currently not on a Wi-Fi connection and the AssetBundle is large or the user has set
|
||||
/// their download preference in the Play Store to only download apps over Wi-Fi. By showing this
|
||||
/// dialog, the app can ask the user if they accept downloading the asset packs over cellular data
|
||||
/// instead of waiting for Wi-Fi.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="PlayAsyncOperation{ConfirmationDialogResult, AssetDeliveryErrorCode}"/> that completes
|
||||
/// once the dialog has been accepted, denied, or closed.
|
||||
/// </returns>
|
||||
public static PlayAsyncOperation<ConfirmationDialogResult, AssetDeliveryErrorCode>
|
||||
ShowCellularDataConfirmation()
|
||||
{
|
||||
return Instance.ShowCellularDataConfirmationInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a dialog that asks the user for consent to download packs that are currently in
|
||||
/// either the <see cref="AssetDeliveryStatus.RequiresUserConfirmation"/> state or the
|
||||
/// <see cref="AssetDeliveryStatus.WaitingForWifi"/> state.
|
||||
///
|
||||
/// A <see cref="PlayAssetBundleRequest"/> is set to
|
||||
/// <see cref="AssetDeliveryStatus.RequiresUserConfirmation"/> If the download is not able
|
||||
/// to proceed without user consent. By showing this dialog, the app can ask the user if
|
||||
/// they accept downloading the asset packs through Google Play. If the app has not been
|
||||
/// installed by Play, an update may be triggered to ensure that a valid version is
|
||||
/// installed. This will cause the app to restart and all asset requests to be cancelled.
|
||||
/// These assets should be requested again after the app restarts.
|
||||
///
|
||||
/// A <see cref="PlayAssetBundleRequest"/> is set to
|
||||
/// <see cref="AssetDeliveryStatus.WaitingForWifi"/> if the user is currently not on a Wi-Fi
|
||||
/// connection and the AssetBundle is large or the user has set their download preference in
|
||||
/// the Play Store to only download apps over Wi-Fi. By showing this dialog, the app can ask
|
||||
/// the user if they accept downloading the asset packs over cellular data instead of
|
||||
/// waiting for Wi-Fi.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="PlayAsyncOperation{ConfirmationDialogResult, AssetDeliveryErrorCode}"/>
|
||||
/// that completes once the dialog has been accepted, denied, or closed.
|
||||
/// </returns>
|
||||
public static PlayAsyncOperation<ConfirmationDialogResult, AssetDeliveryErrorCode>
|
||||
ShowConfirmationDialog()
|
||||
{
|
||||
return Instance.ShowConfirmationDialogInternal();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e93d382fc6b64f72b7e5099c10836cf
|
||||
timeCreated: 1548718888
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,62 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Google.Play.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// A <a href="https://docs.unity3d.com/ScriptReference/CustomYieldInstruction.html">CustomYieldInstruction</a>
|
||||
/// used to monitor the asynchronous retrieval of a batch of asset packs.
|
||||
/// </summary>
|
||||
public abstract class PlayAssetPackBatchRequest : CustomYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// A dictionary of asset pack requests, keyed by name, that are present in this batch.
|
||||
/// </summary>
|
||||
public IDictionary<string, PlayAssetPackRequest> Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if all requests in this batch are in either the <see cref="AssetDeliveryStatus.Available"/> or
|
||||
/// <see cref="AssetDeliveryStatus.Failed"/> status, false otherwise.
|
||||
/// </summary>
|
||||
public bool IsDone { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event indicating that all the requests in this batch are complete. If an event handler is registered after
|
||||
/// the operation has completed, and thus after this event has been invoked, then the handler will be called
|
||||
/// synchronously.
|
||||
/// </summary>
|
||||
public virtual event Action<PlayAssetPackBatchRequest> Completed = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <a href="https://docs.unity3d.com/ScriptReference/CustomYieldInstruction-keepWaiting.html">CustomYieldInstruction.keepWaiting</a>
|
||||
/// property so that this request can be yielded on in a coroutine.
|
||||
/// </summary>
|
||||
public override bool keepWaiting
|
||||
{
|
||||
get { return !IsDone; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="Completed"/> event.
|
||||
/// </summary>
|
||||
protected void InvokeCompletedEvent()
|
||||
{
|
||||
Completed.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f40dc8f7ed954772bc3e54feaad0e837
|
||||
timeCreated: 1588791101
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
namespace Google.Play.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// Download information about a particular asset pack.
|
||||
/// </summary>
|
||||
public abstract class PlayAssetPackDownloadInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The asset pack's download size in bytes.
|
||||
/// If the asset pack's delivery mode is install-time, then the download size will always be 0.
|
||||
/// </summary>
|
||||
public long DownloadSize { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// An enum describing whether or not a newer version of the asset pack is available for download.
|
||||
/// </summary>
|
||||
public AssetPackUpdateAvailability UpdateAvailability { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The version tag of the latest available version of the asset pack. This field might match
|
||||
/// <see cref="InstalledVersionTag"/>, in which case no update is available.
|
||||
///
|
||||
/// <para>
|
||||
/// The tag is set by the developer at upload-time and can be used to identify an asset pack version.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>Empty string if the asset pack does not exist or no information is available.</para>
|
||||
/// </summary>
|
||||
public string AvailableVersionTag { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the version tag of the currently installed asset pack. If no version tag was set for this
|
||||
/// pack version then the app version code will be returned instead.
|
||||
///
|
||||
/// <para>
|
||||
/// The tag is set by the developer at upload-time and can be used to identify an asset pack version.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// Empty string if no version of this pack is currently installed.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public string InstalledVersionTag { get; protected set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b5b3ff2c7b244e4836a9fcbe42448e2
|
||||
timeCreated: 1621901087
|
||||
@@ -0,0 +1,103 @@
|
||||
// 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.AssetDelivery
|
||||
{
|
||||
/// <summary>
|
||||
/// A <a href="https://docs.unity3d.com/ScriptReference/CustomYieldInstruction.html">CustomYieldInstruction</a>
|
||||
/// used to monitor the asynchronous retrieval of an asset pack.
|
||||
/// </summary>
|
||||
public abstract class PlayAssetPackRequest : CustomYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// Progress between 0 and 1 indicating the overall download progress of this request.
|
||||
/// Note: If this value is equal to 1, it does not mean that the request has completed,
|
||||
/// only that the Downloading stage is finished.
|
||||
/// </summary>
|
||||
public float DownloadProgress { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error that prevented this requested from completing successfully.
|
||||
/// In the case of a successful request, this will always be <see cref="AssetDeliveryErrorCode.NoError"/>.
|
||||
/// </summary>
|
||||
public AssetDeliveryErrorCode Error { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this request is in the <see cref="AssetDeliveryStatus.Available"/> or
|
||||
/// <see cref="AssetDeliveryStatus.Failed"/> status, false otherwise.
|
||||
/// </summary>
|
||||
public bool IsDone { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// An enum indicating the status of this request (downloading, downloaded, installed etc.)
|
||||
/// If the request completed successfully, this value should be <see cref="AssetDeliveryStatus.Available"/>.
|
||||
/// If an error occured, it should be <see cref="AssetDeliveryStatus.Failed"/>.
|
||||
/// </summary>
|
||||
public AssetDeliveryStatus Status { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event indicating that the request is completed. If an event handler is registered after the operation has
|
||||
/// completed, and thus after this event has been invoked, then the handler will be called synchronously.
|
||||
/// </summary>
|
||||
public virtual event Action<PlayAssetPackRequest> Completed = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <a href="https://docs.unity3d.com/ScriptReference/CustomYieldInstruction-keepWaiting.html">CustomYieldInstruction.keepWaiting</a>
|
||||
/// property so that this request can be yielded on in a coroutine.
|
||||
/// </summary>
|
||||
public override bool keepWaiting
|
||||
{
|
||||
get { return !IsDone; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the location of an asset at the specified path within this asset pack.
|
||||
/// </summary>
|
||||
/// <param name="assetPath">The path within this asset pack pointing to the desired asset.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="AssetLocation"/> object describing the path, offset and size of a the requested asset file
|
||||
/// within the asset pack.
|
||||
/// </returns>
|
||||
public abstract AssetLocation GetAssetLocation(string assetPath);
|
||||
|
||||
/// <summary>
|
||||
/// Loads the AssetBundle located at the specified path within this asset pack.
|
||||
/// </summary>
|
||||
/// <param name="assetBundlePath">The path within this asset pack pointing to the desired AssetBundle.</param>
|
||||
/// <returns>
|
||||
/// An <a href="https://docs.unity3d.com/ScriptReference/AssetBundleCreateRequest.html">
|
||||
/// AssetBundleCreateRequest</a> that can be yielded on until the AssetBundle is loaded.
|
||||
/// </returns>
|
||||
public abstract AssetBundleCreateRequest LoadAssetBundleAsync(string assetBundlePath);
|
||||
|
||||
/// <summary>
|
||||
/// Cancels the request if possible, setting Status to <see cref="AssetDeliveryStatus.Failed"/> and
|
||||
/// Error to <see cref="AssetDeliveryErrorCode.Canceled"/>.
|
||||
/// If the request is already <see cref="AssetDeliveryStatus.Available"/>
|
||||
/// or <see cref="AssetDeliveryStatus.Failed"/>, then the request is left unchanged.
|
||||
/// </summary>
|
||||
public abstract void AttemptCancel();
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="Completed"/> event.
|
||||
/// </summary>
|
||||
protected void InvokeCompletedEvent()
|
||||
{
|
||||
Completed.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff97ef6fdbb2491fb530d8567185e132
|
||||
timeCreated: 1587769068
|
||||
Reference in New Issue
Block a user