Skip to content

Commit

Permalink
Games: Improve the archive, achievements, and ranking functions (#2576)
Browse files Browse the repository at this point in the history
Co-authored-by: Marvin W <[email protected]>
  • Loading branch information
DaVinci9196 and mar-v-in authored Dec 18, 2024
1 parent 76f1aba commit 6cae97d
Show file tree
Hide file tree
Showing 60 changed files with 5,047 additions and 29 deletions.
2 changes: 2 additions & 0 deletions play-services-auth-base/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,6 @@ dependencies {
api project(':play-services-basement')
api project(':play-services-base')
api project(':play-services-tasks')

annotationProcessor project(':safe-parcel-processor')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

package org.microg.gms.utils

import android.graphics.Bitmap
import kotlin.math.sqrt

object BitmapUtils {

fun getBitmapSize(bitmap: Bitmap?): Int {
if (bitmap != null) {
return bitmap.height * bitmap.rowBytes
}
return 0
}

fun scaledBitmap(bitmap: Bitmap, maxSize: Float): Bitmap {
val height: Int = bitmap.getHeight()
val width: Int = bitmap.getWidth()
val sqrt =
sqrt(((maxSize) / ((width.toFloat()) / (height.toFloat()) * ((bitmap.getRowBytes() / width).toFloat()))).toDouble())
.toInt()
return Bitmap.createScaledBitmap(
bitmap,
(((sqrt.toFloat()) / (height.toFloat()) * (width.toFloat())).toInt()),
sqrt,
true
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,28 @@
package com.google.android.gms.common.images;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import androidx.collection.LruCache;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* This class is used to load images from the network and handles local caching for you.
Expand All @@ -21,6 +43,157 @@ public class ImageManager {
* @return A new ImageManager.
*/
public static ImageManager create(Context context) {
throw new UnsupportedOperationException();
if (INSTANCE == null) {
synchronized (ImageManager.class) {
if (INSTANCE == null) {
INSTANCE = new ImageManager(context);
}
}
}
return INSTANCE;
}

public static final String TAG = "ImageManager";
private static volatile ImageManager INSTANCE;
private final LruCache<String, Bitmap> memoryCache;
private final ExecutorService executorService;
private final Handler handler;
private final Context context;

private ImageManager(Context context) {
this.context = context.getApplicationContext();
this.handler = new Handler(Looper.getMainLooper());
this.executorService = Executors.newFixedThreadPool(4);

final int cacheSize = (int) (Runtime.getRuntime().maxMemory() / 1024 / 8);
this.memoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(@NonNull String key, @NonNull Bitmap bitmap) {
return bitmap.getByteCount() / 1024;
}
};
}

/**
* Compress Bitmap
*/
public byte[] compressBitmap(Bitmap bitmap, Bitmap.CompressFormat format, int quality) {
Log.d(TAG, "compressBitmap width: " + bitmap.getWidth() + " height:" + bitmap.getHeight());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(format, quality, byteArrayOutputStream);
byte[] bitmapBytes = byteArrayOutputStream.toByteArray();
bitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);
Log.d(TAG, "compressBitmap compress width: " + bitmap.getWidth() + " height:" + bitmap.getHeight());
return bitmapBytes;
}

public byte[] compressBitmap(Bitmap original, int newWidth, int newHeight) {
Log.d(TAG, "compressBitmap width: " + original.getWidth() + " height:" + original.getHeight());
Bitmap target = Bitmap.createScaledBitmap(original, newWidth, newHeight, true);
Log.d(TAG, "compressBitmap target width: " + target.getWidth() + " height:" + target.getHeight());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
target.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}

public void loadImage(final String url, final ImageView imageView) {
if (imageView == null) {
Log.d(TAG, "loadImage: imageView is null");
return;
}
final Bitmap cachedBitmap = getBitmapFromCache(url);
if (cachedBitmap != null) {
Log.d(TAG, "loadImage from cached");
imageView.setImageBitmap(cachedBitmap);
} else {
Log.d(TAG, "loadImage from net");
imageView.setTag(url);
executorService.submit(() -> {
final Bitmap bitmap = downloadBitmap(url);
if (bitmap != null) {
addBitmapToCache(url, bitmap);
if (imageView.getTag().equals(url)) {
handler.post(() -> imageView.setImageBitmap(bitmap));
}
}
});
}
}

private Bitmap getBitmapFromCache(String key) {
Bitmap bitmap = memoryCache.get(key);
if (bitmap == null) {
bitmap = getBitmapFromDiskCache(key);
}
return bitmap;
}

private void addBitmapToCache(String key, Bitmap bitmap) {
if (getBitmapFromCache(key) == null) {
memoryCache.put(key, bitmap);
addBitmapToDiskCache(key, bitmap);
}
}

private Bitmap getBitmapFromDiskCache(String key) {
File file = getDiskCacheFile(key);
if (file.exists()) {
return BitmapFactory.decodeFile(file.getAbsolutePath());
}
return null;
}

private void addBitmapToDiskCache(String key, Bitmap bitmap) {
File file = getDiskCacheFile(key);
try (FileOutputStream outputStream = new FileOutputStream(file)) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
} catch (IOException e) {
Log.e(TAG, "addBitmapToDiskCache: ", e);
}
}

private File getDiskCacheFile(String key) {
File cacheDir = context.getCacheDir();
return new File(cacheDir, md5(key));
}

private String md5(String s) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte[] messageDigest = digest.digest();
StringBuilder hexString = new StringBuilder();
for (byte b : messageDigest) {
StringBuilder h = new StringBuilder(Integer.toHexString(0xFF & b));
while (h.length() < 2) h.insert(0, "0");
hexString.append(h);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "md5: ", e);
}
return "";
}

@WorkerThread
private Bitmap downloadBitmap(String url) {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(url).openConnection();
connection.connect();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
return BitmapFactory.decodeStream(inputStream);
}
} catch (IOException e) {
Log.d(TAG, "downloadBitmap: ", e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
return null;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.common.util;

import android.os.ParcelFileDescriptor;

import androidx.annotation.NonNull;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public final class IOUtils {
private IOUtils() {
}

public static void closeQuietly(ParcelFileDescriptor parcelFileDescriptor) {
if (parcelFileDescriptor != null) {
try {
parcelFileDescriptor.close();
} catch (IOException unused) {
}
}
}

public static long copyStream(@NonNull InputStream inputStream, @NonNull OutputStream outputStream) throws IOException {
return copyStream(inputStream, outputStream, false, 1024);
}

public static boolean isGzipByteBuffer(@NonNull byte[] bArr) {
if (bArr.length > 1) {
if ((((bArr[1] & 255) << 8) | (bArr[0] & 255)) == 35615) {
return true;
}
}
return false;
}

public static byte[] readInputStreamFully(@NonNull InputStream inputStream) throws IOException {
return readInputStreamFully(inputStream, true);
}

public static byte[] toByteArray(@NonNull InputStream inputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bArr = new byte[4096];
while (true) {
int read = inputStream.read(bArr);
if (read == -1) {
return byteArrayOutputStream.toByteArray();
}
byteArrayOutputStream.write(bArr, 0, read);
}
}


public static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException unused) {
}
}
}

public static long copyStream(@NonNull InputStream inputStream, @NonNull OutputStream outputStream, boolean z, int i) throws IOException {
byte[] bArr = new byte[i];
long j = 0;
while (true) {
try {
int read = inputStream.read(bArr, 0, i);
if (read == -1) {
break;
}
j += read;
outputStream.write(bArr, 0, read);
} catch (Throwable th) {
if (z) {
closeQuietly(inputStream);
closeQuietly(outputStream);
}
throw th;
}
}
if (z) {
closeQuietly(inputStream);
closeQuietly(outputStream);
}
return j;
}

public static byte[] readInputStreamFully(@NonNull InputStream inputStream, boolean z) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
copyStream(inputStream, byteArrayOutputStream, z, 1024);
return byteArrayOutputStream.toByteArray();
}

}
1 change: 1 addition & 0 deletions play-services-core-proto/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ apply plugin: 'kotlin'

dependencies {
implementation "com.squareup.wire:wire-runtime:$wireVersion"
api "com.squareup.wire:wire-grpc-client:$wireVersion"
}

wire {
Expand Down
Loading

0 comments on commit 6cae97d

Please sign in to comment.