Skip to content

Commit

Permalink
Move to Gradle 7 and Kotlin with auto signing
Browse files Browse the repository at this point in the history
  • Loading branch information
CaramelFur committed Oct 30, 2021
1 parent 665bd2a commit 712e951
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 200 deletions.
2 changes: 0 additions & 2 deletions app/.settings/org.eclipse.buildship.core.prefs

This file was deleted.

67 changes: 42 additions & 25 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,31 +1,48 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

android {
compileSdkVersion 31
buildToolsVersion '31.0.0'

defaultConfig {
applicationId 'com.google.android.apps.photos'
minSdkVersion 29
targetSdkVersion 31
versionCode 2
versionName '1.1.0'
}

/*signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
// Optional, specify signing versions used
v3SigningEnabled true
def localProperties = new Properties()
localProperties.load(new FileInputStream(rootProject.file("local.properties")))

compileSdkVersion 31
buildToolsVersion '31.0.0'

defaultConfig {
applicationId 'com.google.android.apps.photos'
minSdkVersion 29
targetSdkVersion 31
versionCode 4
versionName "1.1.1"
}

signingConfigs {
release {
storeFile file(localProperties["RELEASE_STORE_FILE"])
storePassword localProperties["RELEASE_STORE_PASSWORD"]
keyAlias localProperties["RELEASE_KEY_ALIAS"]
keyPassword localProperties["RELEASE_KEY_PASSWORD"]

enableV3Signing = true
enableV4Signing = true
}
}
}

buildTypes {
release {
signingConfig signingConfigs.release
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
}
}
}*/
}


}
9 changes: 5 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.google.android.apps.photos">

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Expand All @@ -12,12 +13,12 @@

<application
android:allowBackup="false"
android:label="@string/app_name">
android:label="@string/app_name"
tools:ignore="DataExtractionRules,MissingApplicationIcon">
<activity
android:name="com.google.android.apps.photos.MainActivity"
android:clearTaskOnLaunch="true"
android:exported="true"
android:label="@string/app_name"
android:noHistory="true"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
Expand All @@ -42,7 +43,6 @@
android:name="com.google.android.apps.photos.BlankActivity"
android:clearTaskOnLaunch="true"
android:exported="true"
android:label="@string/app_name"
android:noHistory="true"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
Expand All @@ -54,6 +54,7 @@
<!-- I still have no clue what this service is supposed to do -->
<service
android:name="com.google.android.apps.photos.cameraassistant.CameraAssistantService"
android:exported="true"/>
android:exported="true"
tools:ignore="ExportedService" />
</application>
</manifest>
19 changes: 9 additions & 10 deletions app/src/main/java/com/google/android/apps/photos/BlankActivity.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package com.google.android.apps.photos;
package com.google.android.apps.photos

import android.app.Activity;
import android.os.Bundle;
import android.app.Activity
import android.os.Bundle

public class BlankActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
finish();
}
}
class BlankActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
finish()
}
}
250 changes: 126 additions & 124 deletions app/src/main/java/com/google/android/apps/photos/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,132 +1,134 @@
package com.google.android.apps.photos;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.util.Log;
import android.net.Uri;

import android.database.Cursor;
import android.provider.MediaStore;
import android.content.Context;
import android.app.PendingIntent;
import android.Manifest;
import android.content.pm.PackageManager;

public class MainActivity extends Activity {
// Polling settings for checking if the URI is finsihed yet
private static final int waitMS = 100;
private static final int maximumSeconds = 30000;
private static final int iterations = maximumSeconds * 1000 / waitMS;

// Random integer to identify app in permission callback
private static final int PERMISSIONS_INT = 755009201;

private PendingIntent cameraRelaunchIntent;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

Intent receivedIntent = getIntent();

// Extract all necessary information from the intent
// We store the relaunch intent in this class so it can be used in callbacks
// (In this case that is just the permission callback)
String SessionId = receivedIntent.getStringExtra("external_session_id");
Uri uri = Uri.parse(receivedIntent.getData().toString());
String type = receivedIntent.getType();
Uri processingURI = (Uri) receivedIntent.getParcelableExtra("processing_uri_intent_extra");
this.cameraRelaunchIntent = (PendingIntent) receivedIntent.getParcelableExtra("CAMERA_RELAUNCH_INTENT_EXTRA");

// Make sure there is even a session id, the call is probably invalid if this is gone
if (SessionId == null) {
finish();
return;
package com.google.android.apps.photos

import android.Manifest
import android.app.Activity
import android.app.PendingIntent
import android.content.Context
import android.os.Bundle
import android.content.Intent
import android.content.pm.PackageManager
import android.database.Cursor
import android.net.Uri
import android.provider.MediaStore
import android.util.Log
import java.lang.Exception

class MainActivity : Activity() {
private var cameraRelaunchIntent: PendingIntent? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val receivedIntent = this.intent

// Extract all necessary information from the intent
// We store the relaunch intent in this class so it can be used in callbacks
// (In this case that is just the permission callback)
val sessionId = receivedIntent.getStringExtra("external_session_id")
val uri = Uri.parse(receivedIntent.data.toString())
val type = receivedIntent.type
val processingURI: Uri? =
receivedIntent.getParcelableExtra("processing_uri_intent_extra")
cameraRelaunchIntent =
receivedIntent.getParcelableExtra("CAMERA_RELAUNCH_INTENT_EXTRA")

// Make sure there is even a session id, the call is probably invalid if this is gone
if (sessionId == null) return finish()

// Make sure that we have the READ_EXTERNAL_STORAGE permission,
// for some stupid reason we need this permission to check if a URI is pending
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
Log.i("PhotosShim", "No READ_EXTERNAL_STORAGE permission, requesting it")
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), PERMISSIONS_INT)
// We can now quit the app, as GCam wil relaunch it again automatically
return quit()
}

Log.i(
"PhotosShim", "SessionId: '" + sessionId +
"', URI:'" + uri +
"', type: '" + type +
"', processingURI: '" + processingURI + "'"
)

// Keep polling the URI to see if it has stopped being pending
var success = false
for (i in 0 until iterations) {
if (!isUriPending(applicationContext, uri)) {
success = true
break
}
Log.i("PhotosShim", "Pending...")
sleep(waitMS.toLong())
}
if (!success) return quit()

// If the URI is not pending anymore we send an implicit intent
// so you can now handle the image with any gallery you want
val intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.setDataAndType(uri, "image/*")
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
finish()
}

// Make sure that we have the READ_EXTERNAL_STORAGE permission,
// we sadly need this permission to check if a URI is pending
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
Log.i("PhotosShim", "No permission, requesting them");

requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSIONS_INT);

quit();
return;
// Try to relaunch the camera and then quit this app
private fun quit() {
try {
cameraRelaunchIntent?.send()
} catch (e: Exception) {
Log.e("PhotosShim", "Error sending intent", e)
}
finish()
}

Log.i("PhotosShim", "SessionId: '" + SessionId + "', URI:'" + uri + "', type: '" + type + "', processingURI: '"
+ processingURI + "'");

// Keep polling the URI to see if it has stopped being pending
boolean success = false;
for (int i = 0; i < iterations; i++) {
if (!isUriPending(getApplicationContext(), uri)) {
success = true;
break;
}

Log.i("PhotosShim", "Pending...");

try {
Thread.sleep(waitMS);
} catch (Exception e) {
Log.e("PhotosShim", "Error sleeping", e);
break;
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
if (requestCode != PERMISSIONS_INT) return // Check if this result is for us
if (permissions.isEmpty() || grantResults.isEmpty()) return // Check if has useful data
// And if it has the correct permission we can quit to relaunch with the right privileges
if (permissions[0] == Manifest.permission.READ_EXTERNAL_STORAGE) quit()
}

if (!success) {
quit();
return;
}

// If the URI is not pending anymore we send an implicit intent
// so you can now handle the image with any gallery you want

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "image/*");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}

private void quit() {
try {
if (this.cameraRelaunchIntent != null)
this.cameraRelaunchIntent.send();
} catch (Exception e) {
Log.e("PhotosShim", "Error sending intent", e);
}
finish();
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode != PERMISSIONS_INT)
return;
if (permissions.length == 0 || grantResults.length == 0)
return;

if (permissions[0].equals(Manifest.permission.READ_EXTERNAL_STORAGE))
quit();
}

public static boolean isUriPending(Context context, Uri contentUri) {
Cursor cursor = null;
boolean result;
try {
String[] proj = {MediaStore.Images.Media.IS_PENDING};
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
cursor.moveToFirst();
int column_index_data = cursor.getColumnIndex(proj[0]);
result = cursor.getInt(column_index_data) != 0;
} finally {
if (cursor != null)
cursor.close();
companion object {
// Polling settings for checking if the URI is finished yet
private const val waitMS = 100
private const val maximumSeconds = 30000
private const val iterations = maximumSeconds * 1000 / waitMS

// Random integer to identify app in permission callback
private const val PERMISSIONS_INT = 755009201

// Check if a URI for an image is still being processed by Google Camera
fun isUriPending(context: Context, contentUri: Uri): Boolean {
val proj = arrayOf(MediaStore.Images.Media.IS_PENDING)

val cursor = context.contentResolver
.query(contentUri, proj, null, null, null)
val result =
if (cursor != null) {
// Get the data of the IS_PENDING property on the first result
cursor.moveToFirst()
val columnIndexData = cursor.getColumnIndex(proj[0])
cursor.getInt(columnIndexData) != 0
} else {
false
}
cursor?.close()

return result
}

// Simple function to sleep while catching any thread errors
fun sleep(millis: Long) {
try {
Thread.sleep(millis)
} catch (e: Exception) {
Log.e("PhotosShim", "Error sleeping", e)
}
}
}
return result;
}
}
Loading

0 comments on commit 712e951

Please sign in to comment.