From aae974ec5b255330b527621fabdbdd82fa77648c Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 12 Jul 2020 19:02:35 +0200 Subject: [PATCH 01/51] Complete play-services-tasks implementation --- play-services-tasks/build.gradle | 15 +- .../src/main/AndroidManifest.xml | 15 +- .../android/gms/tasks/CancellationToken.java | 28 ++ .../gms/tasks/CancellationTokenSource.java | 46 ++++ .../android/gms/tasks/Continuation.java | 18 +- .../DuplicateTaskCompletionException.java | 32 +++ .../android/gms/tasks/OnCanceledListener.java | 22 ++ .../android/gms/tasks/OnCompleteListener.java | 18 +- .../android/gms/tasks/OnFailureListener.java | 18 +- .../android/gms/tasks/OnSuccessListener.java | 18 +- .../gms/tasks/OnTokenCanceledListener.java | 24 ++ .../gms/tasks/RuntimeExecutionException.java | 18 +- .../gms/tasks/SuccessContinuation.java | 28 ++ .../com/google/android/gms/tasks/Task.java | 86 ++++++- .../gms/tasks/TaskCompletionSource.java | 70 ++++- .../android/gms/tasks/TaskExecutors.java | 33 +++ .../com/google/android/gms/tasks/Tasks.java | 18 +- .../gms/tasks/CancellationTokenImpl.java | 32 +++ .../microg/gms/tasks/CancelledExecutor.java | 34 +++ .../microg/gms/tasks/CompletedExecutor.java | 33 +++ .../gms/tasks/ContinuationExecutor.java | 46 ++++ .../gms/tasks/ContinuationWithExecutor.java | 52 ++++ .../org/microg/gms/tasks/FailureExecutor.java | 33 +++ .../tasks/SuccessContinuationExecutor.java | 54 ++++ .../org/microg/gms/tasks/SuccessExecutor.java | 33 +++ .../java/org/microg/gms/tasks/TaskImpl.java | 240 ++++++++++++++++++ .../org/microg/gms/tasks/UpdateExecutor.java | 27 ++ .../org/microg/gms/tasks/UpdateListener.java | 14 + .../UpdateListenerLifecycleObserver.java | 98 +++++++ 29 files changed, 1071 insertions(+), 132 deletions(-) create mode 100644 play-services-tasks/src/main/java/com/google/android/gms/tasks/CancellationToken.java create mode 100644 play-services-tasks/src/main/java/com/google/android/gms/tasks/CancellationTokenSource.java create mode 100644 play-services-tasks/src/main/java/com/google/android/gms/tasks/DuplicateTaskCompletionException.java create mode 100644 play-services-tasks/src/main/java/com/google/android/gms/tasks/OnCanceledListener.java create mode 100644 play-services-tasks/src/main/java/com/google/android/gms/tasks/OnTokenCanceledListener.java create mode 100644 play-services-tasks/src/main/java/com/google/android/gms/tasks/SuccessContinuation.java create mode 100644 play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskExecutors.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/CancellationTokenImpl.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/CancelledExecutor.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/CompletedExecutor.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/ContinuationExecutor.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/ContinuationWithExecutor.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/FailureExecutor.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/SuccessContinuationExecutor.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/SuccessExecutor.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/TaskImpl.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateExecutor.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateListener.java create mode 100644 play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateListenerLifecycleObserver.java diff --git a/play-services-tasks/build.gradle b/play-services-tasks/build.gradle index 7d1eb81f..bb8662f8 100644 --- a/play-services-tasks/build.gradle +++ b/play-services-tasks/build.gradle @@ -1,17 +1,6 @@ /* - * Copyright 2013-2015 microG Project Team - * - * 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 - * - * http://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. + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 */ apply plugin: 'com.android.library' diff --git a/play-services-tasks/src/main/AndroidManifest.xml b/play-services-tasks/src/main/AndroidManifest.xml index 68340930..c7b833fe 100644 --- a/play-services-tasks/src/main/AndroidManifest.xml +++ b/play-services-tasks/src/main/AndroidManifest.xml @@ -1,18 +1,7 @@ diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/CancellationToken.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/CancellationToken.java new file mode 100644 index 00000000..00563c5b --- /dev/null +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/CancellationToken.java @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. + */ + +package com.google.android.gms.tasks; + +import org.microg.gms.common.PublicApi; + +@PublicApi +public abstract class CancellationToken { + /** + * Checks if cancellation has been requested from the {@link CancellationTokenSource}. + * + * @return {@code true} if cancellation is requested, {@code false} otherwise + */ + public abstract boolean isCancellationRequested(); + + /** + * Adds an {@link OnTokenCanceledListener} to this {@link CancellationToken}. + * + * @param listener the listener that will fire once the cancellation request succeeds. + */ + public abstract CancellationToken onCanceledRequested(OnTokenCanceledListener listener); +} diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/CancellationTokenSource.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/CancellationTokenSource.java new file mode 100644 index 00000000..044b0466 --- /dev/null +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/CancellationTokenSource.java @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. + */ + +package com.google.android.gms.tasks; + +import org.microg.gms.common.PublicApi; +import org.microg.gms.tasks.CancellationTokenImpl; + +/** + * Creates a new {@link CancellationToken} or cancels one that has already created. There is a 1:1 {@link CancellationTokenSource} to {@link CancellationToken} relationship. + *

+ * To create a {@link CancellationToken}, create a {@link CancellationTokenSource} first and then call {@link #getToken()} to get the {@link CancellationToken} for this {@link CancellationTokenSource}. + * + * @see CancellationToken + */ +@PublicApi +public class CancellationTokenSource { + private CancellationTokenImpl token = new CancellationTokenImpl(); + + /** + * Creates a new {@link CancellationTokenSource} instance. + */ + public CancellationTokenSource() { + } + + /** + * Cancels the {@link CancellationToken} if cancellation has not been requested yet. + */ + public void cancel() { + token.cancel(); + } + + /** + * Gets the {@link CancellationToken} for this {@link CancellationTokenSource}. + * + * @return the {@link CancellationToken} that can be passed to asynchronous {@link Task} to cancel the Task. + */ + public CancellationToken getToken() { + return token; + } +} diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/Continuation.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/Continuation.java index 26b69a81..7057ca71 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/Continuation.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/Continuation.java @@ -1,17 +1,9 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. + * SPDX-FileCopyrightText: 2016, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. */ package com.google.android.gms.tasks; diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/DuplicateTaskCompletionException.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/DuplicateTaskCompletionException.java new file mode 100644 index 00000000..81eaa700 --- /dev/null +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/DuplicateTaskCompletionException.java @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. + */ + +package com.google.android.gms.tasks; + +import org.microg.gms.common.PublicApi; + +/** + * An exception indicating that something attempted to set a result, exception, or cancellation on a {@link Task} that was already completed. + */ +@PublicApi +public class DuplicateTaskCompletionException extends IllegalStateException { + + private DuplicateTaskCompletionException(String s) { + super(s); + } + + /** + * Creates a DuplicateTaskCompletionException from a {@link Task}. + * + * The {@link Task} must be complete. + */ + public static DuplicateTaskCompletionException of(Task task) { + if (!task.isComplete()) throw new IllegalStateException("Task is not yet completed"); + return new DuplicateTaskCompletionException("Task is already completed"); + } +} diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnCanceledListener.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnCanceledListener.java new file mode 100644 index 00000000..32fd7b0f --- /dev/null +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnCanceledListener.java @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. + */ + +package com.google.android.gms.tasks; + +import org.microg.gms.common.PublicApi; + +/** + * Listener called when a {@link Task} is canceled. + */ +@PublicApi +public interface OnCanceledListener { + /** + * Called when the Task is canceled successfully. + */ + public abstract void onCanceled(); +} diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnCompleteListener.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnCompleteListener.java index 2035472c..7cff8dcf 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnCompleteListener.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnCompleteListener.java @@ -1,17 +1,9 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. + * SPDX-FileCopyrightText: 2016, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. */ package com.google.android.gms.tasks; diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnFailureListener.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnFailureListener.java index c6e1124b..e9391531 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnFailureListener.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnFailureListener.java @@ -1,17 +1,9 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. + * SPDX-FileCopyrightText: 2016, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. */ package com.google.android.gms.tasks; diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnSuccessListener.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnSuccessListener.java index f6e6fbdd..5460c0a9 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnSuccessListener.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnSuccessListener.java @@ -1,17 +1,9 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. + * SPDX-FileCopyrightText: 2016, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. */ package com.google.android.gms.tasks; diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnTokenCanceledListener.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnTokenCanceledListener.java new file mode 100644 index 00000000..0ad2d686 --- /dev/null +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/OnTokenCanceledListener.java @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. + */ + +package com.google.android.gms.tasks; + +import org.microg.gms.common.PublicApi; + +/** + * Listener called when a {@link CancellationToken} is canceled successfully. + * + * @see CancellationToken#onCanceledRequested(OnTokenCanceledListener) + */ +@PublicApi +public interface OnTokenCanceledListener { + /** + * Called when the {@link CancellationToken} is canceled successfully. + */ + void onCanceled(); +} diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/RuntimeExecutionException.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/RuntimeExecutionException.java index 99482115..a15dfbe3 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/RuntimeExecutionException.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/RuntimeExecutionException.java @@ -1,17 +1,9 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. + * SPDX-FileCopyrightText: 2016, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. */ package com.google.android.gms.tasks; diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/SuccessContinuation.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/SuccessContinuation.java new file mode 100644 index 00000000..3feb598e --- /dev/null +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/SuccessContinuation.java @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. + */ + +package com.google.android.gms.tasks; + +import org.microg.gms.common.PublicApi; + +/** + * A function that is called to continue execution then a {@link Task} succeeds. + * @see Task#onSuccessTask + */ +@PublicApi +public interface SuccessContinuation { + /** + * Returns the result of applying this SuccessContinuation to Task. + *

+ * The SuccessContinuation only happens then the Task is successful. If the previous Task fails, the onSuccessTask continuation will be skipped and failure listeners will be invoked. + * + * @param result the result of completed Task + * @throws Exception if the result couldn't be produced + */ + Task then(TResult result) throws Exception; +} diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/Task.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/Task.java index b9963173..f7223779 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/Task.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/Task.java @@ -1,17 +1,9 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. + * SPDX-FileCopyrightText: 2016, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. */ package com.google.android.gms.tasks; @@ -31,6 +23,42 @@ public abstract class Task { public Task() { } + /** + * Adds a listener that is called if the Task is canceled. + *

+ * The listener will be called on main application thread. If the Task has already been canceled, a call to the listener will be immediately scheduled. If multiple listeners are added, they will be called in the order in which they were added. + * + * @return this Task + */ + public Task addOnCanceledListener(OnCanceledListener listener) { + throw new UnsupportedOperationException("addOnCanceledListener is not implemented"); + } + + /** + * Adds a listener that is called if the Task is canceled. + *

+ * If the Task has already been canceled, a call to the listener will be immediately scheduled. If multiple listeners are added, they will be called in the order in which they were added. + * + * @param executor the executor to use to call the listener + * @return this Task + */ + public Task addOnCanceledListener(Executor executor, OnCanceledListener listener) { + throw new UnsupportedOperationException("addOnCanceledListener is not implemented"); + } + + /** + * Adds an Activity-scoped listener that is called if the Task is canceled. + *

+ * The listener will be called on main application thread. If the Task has already been canceled, a call to the listener will be immediately scheduled. If multiple listeners are added, they will be called in the order in which they were added. + *

+ * The listener will be automatically removed during {@link Activity#onStop()}. + * + * @return this Task + */ + public Task addOnCanceledListener(Activity activity, OnCanceledListener listener) { + throw new UnsupportedOperationException("addOnCanceledListener is not implemented"); + } + /** * Adds a listener that is called when the Task completes. *

@@ -184,7 +212,7 @@ public abstract class Task { * @param executor the executor to use to call the Continuation * @see Continuation#then(Task) */ - public Task continueWithTask(Executor executor, Continuation> var2) { + public Task continueWithTask(Executor executor, Continuation> continuation) { throw new UnsupportedOperationException("continueWithTask is not implemented"); } @@ -211,6 +239,11 @@ public abstract class Task { */ public abstract TResult getResult(Class exceptionType) throws X; + /** + * Returns {@code true} if the Task is canceled; {@code false} otherwise. + */ + public abstract boolean isCanceled(); + /** * Returns {@code true} if the Task is complete; {@code false} otherwise. */ @@ -221,4 +254,29 @@ public abstract class Task { */ public abstract boolean isSuccessful(); + /** + * Returns a new Task that will be completed with the result of applying the specified SuccessContinuation to this Task when this Task completes successfully. If the previous Task fails, the onSuccessTask completion will be skipped and failure listeners will be invoked. + *

+ * The SuccessContinuation will be called on the main application thread. + *

+ * If the previous Task is canceled, the returned Task will also be canceled and the SuccessContinuation would not execute. + * + * @see SuccessContinuation#then + */ + public Task onSuccessTask(SuccessContinuation successContinuation) { + throw new UnsupportedOperationException("onSuccessTask is not implemented"); + } + + /** + * Returns a new Task that will be completed with the result of applying the specified SuccessContinuation to this Task when this Task completes successfully. If the previous Task fails, the onSuccessTask completion will be skipped and failure listeners will be invoked. + *

+ * If the previous Task is canceled, the returned Task will also be canceled and the SuccessContinuation would not execute. + * + * @param executor the executor to use to call the SuccessContinuation + * @see SuccessContinuation#then + */ + public Task onSuccessTask(Executor executor, SuccessContinuation successContinuation) { + throw new UnsupportedOperationException("onSuccessTask is not implemented"); + } + } diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskCompletionSource.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskCompletionSource.java index 32def519..00c4a972 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskCompletionSource.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskCompletionSource.java @@ -1,22 +1,15 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. + * SPDX-FileCopyrightText: 2016, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. */ package com.google.android.gms.tasks; import org.microg.gms.common.PublicApi; +import org.microg.gms.tasks.TaskImpl; /** * Provides the ability to create an incomplete {@link Task} and later complete it by either @@ -24,29 +17,78 @@ import org.microg.gms.common.PublicApi; */ @PublicApi public class TaskCompletionSource { + private TaskImpl task = new TaskImpl<>(); + + /** + * Creates an instance of {@link TaskCompletionSource}. + */ public TaskCompletionSource() { } + /** + * Creates an instance of {@link TaskCompletionSource} with a {@link CancellationToken} so that the Task can be set to canceled when {@link CancellationToken} is canceled. + */ + public TaskCompletionSource(CancellationToken token) { + token.onCanceledRequested(() -> { + try { + task.cancel(); + } catch (DuplicateTaskCompletionException ignored) { + } + }); + } + /** * Returns the Task. */ public Task getTask() { - return null; + return task; } /** * Completes the Task with the specified exception. + * * @throws IllegalStateException if the Task is already complete */ public void setException(Exception e) { + task.setException(e); + } + /** + * Completes the Task with the specified exception, unless the Task has already completed. + * If the Task has already completed, the call does nothing. + * + * @return {@code true} if the exception was set successfully, {@code false} otherwise + */ + public boolean trySetException(Exception e) { + try { + setException(e); + return true; + } catch (DuplicateTaskCompletionException ignored) { + return false; + } } /** * Completes the Task with the specified result. + * * @throws IllegalStateException if the Task is already complete */ public void setResult(TResult result) { + task.setResult(result); + } + /** + * Completes the Task with the specified result, unless the Task has already completed. + * If the Task has already completed, the call does nothing. + * + * @return {@code true} if the result was set successfully, {@code false} otherwise + */ + public boolean trySetResult(TResult result) { + try { + setResult(result); + return true; + } catch (DuplicateTaskCompletionException ignored) { + return false; + } } } diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskExecutors.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskExecutors.java new file mode 100644 index 00000000..c4947e13 --- /dev/null +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskExecutors.java @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. + */ + +package com.google.android.gms.tasks; + +import android.os.Handler; +import android.os.Looper; + +import org.microg.gms.common.PublicApi; + +import java.util.concurrent.Executor; + +/** + * Standard {@link Executor} instances for use with {@link Task}. + */ +@PublicApi +public final class TaskExecutors { + /** + * An Executor that uses the main application thread. + */ + public static final Executor MAIN_THREAD = new Executor() { + private Handler handler = new Handler(Looper.getMainLooper()); + @Override + public void execute(Runnable command) { + handler.post(command); + } + }; +} diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java index 41f31c7b..43452562 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java @@ -1,17 +1,9 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. + * SPDX-FileCopyrightText: 2016, microG Project Team + * SPDX-License-Identifier: Apache-2.0 AND CC-BY-4.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. */ package com.google.android.gms.tasks; diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/CancellationTokenImpl.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/CancellationTokenImpl.java new file mode 100644 index 00000000..b2a69096 --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/CancellationTokenImpl.java @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import com.google.android.gms.tasks.CancellationToken; +import com.google.android.gms.tasks.DuplicateTaskCompletionException; +import com.google.android.gms.tasks.OnTokenCanceledListener; + +public class CancellationTokenImpl extends CancellationToken { + private TaskImpl task = new TaskImpl<>(); + + @Override + public boolean isCancellationRequested() { + return task.isComplete(); + } + + @Override + public CancellationToken onCanceledRequested(OnTokenCanceledListener listener) { + task.addOnSuccessListener(aVoid -> listener.onCanceled()); + return this; + } + + public void cancel() { + try { + task.cancel(); + } catch (DuplicateTaskCompletionException ignored) { + } + } +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/CancelledExecutor.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/CancelledExecutor.java new file mode 100644 index 00000000..6b495749 --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/CancelledExecutor.java @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import com.google.android.gms.tasks.OnCanceledListener; +import com.google.android.gms.tasks.Task; + +import java.util.concurrent.Executor; + +public class CancelledExecutor extends UpdateExecutor { + private OnCanceledListener listener; + + public CancelledExecutor(Executor executor, OnCanceledListener listener) { + super(executor); + this.listener = listener; + } + + @Override + public void onTaskUpdate(Task task) { + if (task.isCanceled()) { + execute(() -> listener.onCanceled()); + } + } + + @Override + public void cancel() { + super.cancel(); + listener = null; + } +} + diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/CompletedExecutor.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/CompletedExecutor.java new file mode 100644 index 00000000..18267d7f --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/CompletedExecutor.java @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; + +import java.util.concurrent.Executor; + +public class CompletedExecutor extends UpdateExecutor { + private OnCompleteListener listener; + + public CompletedExecutor(Executor executor, OnCompleteListener listener) { + super(executor); + this.listener = listener; + } + + @Override + public void onTaskUpdate(Task task) { + if (task.isComplete()) { + execute(() -> listener.onComplete(task)); + } + } + + @Override + public void cancel() { + super.cancel(); + listener = null; + } +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/ContinuationExecutor.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/ContinuationExecutor.java new file mode 100644 index 00000000..33606df3 --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/ContinuationExecutor.java @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import com.google.android.gms.tasks.Continuation; +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.TaskCompletionSource; + +import java.util.concurrent.Executor; + +public class ContinuationExecutor extends UpdateExecutor { + private Continuation continuation; + private TaskCompletionSource completionSource = new TaskCompletionSource<>(); + + public ContinuationExecutor(Executor executor, Continuation continuation) { + super(executor); + this.continuation = continuation; + } + + @Override + public void onTaskUpdate(Task task) { + if (task.isComplete()) { + execute(() -> { + try { + completionSource.setResult(continuation.then(task)); + } catch (Exception e) { + completionSource.setException(e); + } + }); + } + } + + public Task getTask() { + return completionSource.getTask(); + } + + @Override + public void cancel() { + super.cancel(); + continuation = null; + completionSource = null; + } +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/ContinuationWithExecutor.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/ContinuationWithExecutor.java new file mode 100644 index 00000000..6ec69b0d --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/ContinuationWithExecutor.java @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import com.google.android.gms.tasks.Continuation; +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.TaskCompletionSource; + +import java.util.concurrent.Executor; + +public class ContinuationWithExecutor extends UpdateExecutor { + private Continuation> continuation; + private TaskCompletionSource completionSource = new TaskCompletionSource<>(); + + public ContinuationWithExecutor(Executor executor, Continuation> continuation) { + super(executor); + this.continuation = continuation; + } + + @Override + public void onTaskUpdate(Task task) { + if (task.isComplete()) { + execute(() -> { + try { + continuation.then(task).addOnCompleteListener(this, (subTask) -> { + if (subTask.isSuccessful()) { + completionSource.setResult(subTask.getResult()); + } else { + completionSource.setException(subTask.getException()); + } + }); + } catch (Exception e) { + completionSource.setException(e); + } + }); + } + } + + public Task getTask() { + return completionSource.getTask(); + } + + @Override + public void cancel() { + super.cancel(); + continuation = null; + completionSource = null; + } +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/FailureExecutor.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/FailureExecutor.java new file mode 100644 index 00000000..3a670337 --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/FailureExecutor.java @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.Task; + +import java.util.concurrent.Executor; + +public class FailureExecutor extends UpdateExecutor { + private OnFailureListener listener; + + public FailureExecutor(Executor executor, OnFailureListener listener) { + super(executor); + this.listener = listener; + } + + @Override + public void onTaskUpdate(Task task) { + if (task.isComplete() && !task.isSuccessful() && !task.isCanceled()) { + execute(() -> listener.onFailure(task.getException())); + } + } + + @Override + public void cancel() { + super.cancel(); + listener = null; + } +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/SuccessContinuationExecutor.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/SuccessContinuationExecutor.java new file mode 100644 index 00000000..963ae64f --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/SuccessContinuationExecutor.java @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import com.google.android.gms.tasks.SuccessContinuation; +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.TaskCompletionSource; + +import java.util.concurrent.Executor; + +public class SuccessContinuationExecutor extends UpdateExecutor { + private SuccessContinuation continuation; + private TaskCompletionSource completionSource = new TaskCompletionSource<>(); + + public SuccessContinuationExecutor(Executor executor, SuccessContinuation continuation) { + super(executor); + this.continuation = continuation; + } + + @Override + public void onTaskUpdate(Task task) { + if (task.isSuccessful()) { + execute(() -> { + try { + continuation.then(task.getResult()).addOnCompleteListener(this, (subTask) -> { + if (subTask.isSuccessful()) { + completionSource.setResult(subTask.getResult()); + } else { + completionSource.setException(subTask.getException()); + } + }); + } catch (Exception e) { + completionSource.setException(e); + } + }); + } else { + completionSource.setException(task.getException()); + } + } + + public Task getTask() { + return completionSource.getTask(); + } + + @Override + public void cancel() { + super.cancel(); + continuation = null; + completionSource = null; + } +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/SuccessExecutor.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/SuccessExecutor.java new file mode 100644 index 00000000..da6816d0 --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/SuccessExecutor.java @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.android.gms.tasks.Task; + +import java.util.concurrent.Executor; + +public class SuccessExecutor extends UpdateExecutor { + private OnSuccessListener listener; + + public SuccessExecutor(Executor executor, OnSuccessListener listener) { + super(executor); + this.listener = listener; + } + + @Override + public void onTaskUpdate(Task task) { + if (task.isSuccessful()) { + execute(() -> listener.onSuccess(task.getResult())); + } + } + + @Override + public void cancel() { + super.cancel(); + listener = null; + } +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/TaskImpl.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/TaskImpl.java new file mode 100644 index 00000000..ae5c42f1 --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/TaskImpl.java @@ -0,0 +1,240 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import android.app.Activity; + +import com.google.android.gms.tasks.Continuation; +import com.google.android.gms.tasks.DuplicateTaskCompletionException; +import com.google.android.gms.tasks.OnCanceledListener; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.android.gms.tasks.RuntimeExecutionException; +import com.google.android.gms.tasks.SuccessContinuation; +import com.google.android.gms.tasks.Task; + +import java.util.Queue; +import java.util.concurrent.CancellationException; +import java.util.concurrent.Executor; +import java.util.concurrent.LinkedBlockingQueue; + +import static com.google.android.gms.tasks.TaskExecutors.MAIN_THREAD; + +public class TaskImpl extends Task { + private final Object lock = new Object(); + private boolean completed; + private boolean cancelled; + private TResult result; + private Exception exception; + private Queue> completionQueue = new LinkedBlockingQueue<>(); + + @Override + public Task addOnCanceledListener(OnCanceledListener listener) { + return addOnCanceledListener(MAIN_THREAD, listener); + } + + @Override + public Task addOnCanceledListener(Executor executor, OnCanceledListener listener) { + return enqueueOrInvoke(new CancelledExecutor<>(executor, listener)); + } + + @Override + public Task addOnCanceledListener(Activity activity, OnCanceledListener listener) { + return enqueueOrInvoke(activity, new CancelledExecutor<>(MAIN_THREAD, listener)); + } + + @Override + public Task addOnCompleteListener(OnCompleteListener listener) { + return addOnCompleteListener(MAIN_THREAD, listener); + } + + @Override + public Task addOnCompleteListener(Executor executor, OnCompleteListener listener) { + return enqueueOrInvoke(new CompletedExecutor<>(executor, listener)); + } + + @Override + public Task addOnCompleteListener(Activity activity, OnCompleteListener listener) { + return enqueueOrInvoke(activity, new CompletedExecutor<>(MAIN_THREAD, listener)); + } + + @Override + public Task addOnFailureListener(OnFailureListener listener) { + return addOnFailureListener(MAIN_THREAD, listener); + } + + @Override + public Task addOnFailureListener(Executor executor, OnFailureListener listener) { + return enqueueOrInvoke(new FailureExecutor<>(executor, listener)); + } + + @Override + public Task addOnFailureListener(Activity activity, OnFailureListener listener) { + return enqueueOrInvoke(activity, new FailureExecutor<>(MAIN_THREAD, listener)); + } + + @Override + public Task addOnSuccessListener(OnSuccessListener listener) { + return addOnSuccessListener(MAIN_THREAD, listener); + } + + @Override + public Task addOnSuccessListener(Executor executor, OnSuccessListener listener) { + return enqueueOrInvoke(new SuccessExecutor<>(executor, listener)); + } + + @Override + public Task addOnSuccessListener(Activity activity, OnSuccessListener listener) { + return enqueueOrInvoke(activity, new SuccessExecutor<>(MAIN_THREAD, listener)); + } + + @Override + public Task continueWith(Continuation continuation) { + return continueWith(MAIN_THREAD, continuation); + } + + @Override + public Task continueWith(Executor executor, Continuation continuation) { + ContinuationExecutor c = new ContinuationExecutor<>(executor, continuation); + enqueueOrInvoke(c); + return c.getTask(); + } + + @Override + public Task continueWithTask(Continuation> continuation) { + return continueWithTask(MAIN_THREAD, continuation); + } + + @Override + public Task continueWithTask(Executor executor, Continuation> continuation) { + ContinuationWithExecutor c = new ContinuationWithExecutor<>(executor, continuation); + enqueueOrInvoke(c); + return c.getTask(); + } + + @Override + public Exception getException() { + synchronized (lock) { + return exception; + } + } + + @Override + public TResult getResult() { + synchronized (lock) { + if (!completed) throw new IllegalStateException("Task is not yet complete"); + if (cancelled) throw new CancellationException("Task is canceled"); + if (exception != null) throw new RuntimeExecutionException(exception); + return result; + } + } + + @Override + public TResult getResult(Class exceptionType) throws X { + synchronized (lock) { + if (!completed) throw new IllegalStateException("Task is not yet complete"); + if (cancelled) throw new CancellationException("Task is canceled"); + if (exceptionType.isInstance(exception)) throw exceptionType.cast(exception); + if (exception != null) throw new RuntimeExecutionException(exception); + return result; + } + } + + @Override + public boolean isCanceled() { + synchronized (lock) { + return cancelled; + } + } + + @Override + public boolean isComplete() { + synchronized (lock) { + return completed; + } + } + + @Override + public boolean isSuccessful() { + synchronized (lock) { + return completed && !cancelled && exception == null; + } + } + + private void registerActivityStop(Activity activity, UpdateListener listener) { + UpdateListenerLifecycleObserver.getObserverForActivity(activity).registerActivityStopListener(listener); + } + + private Task enqueueOrInvoke(Activity activity, UpdateListener listener) { + synchronized (lock) { + if (completed) { + listener.onTaskUpdate(this); + } else { + completionQueue.offer(listener); + registerActivityStop(activity, listener); + } + } + return this; + } + + private Task enqueueOrInvoke(UpdateListener listener) { + synchronized (lock) { + if (completed) { + listener.onTaskUpdate(this); + } else { + completionQueue.offer(listener); + } + } + return this; + } + + private void notifyQueue() { + UpdateListener listener; + while ((listener = completionQueue.poll()) != null) { + listener.onTaskUpdate(this); + } + } + + public void cancel() { + synchronized (lock) { + if (completed) throw DuplicateTaskCompletionException.of(this); + this.completed = true; + this.cancelled = true; + notifyQueue(); + } + } + + public void setResult(TResult result) { + synchronized (lock) { + if (completed) throw DuplicateTaskCompletionException.of(this); + this.completed = true; + this.result = result; + notifyQueue(); + } + } + + public void setException(Exception exception) { + synchronized (lock) { + if (completed) throw DuplicateTaskCompletionException.of(this); + this.completed = true; + this.exception = exception; + notifyQueue(); + } + } + + @Override + public Task onSuccessTask(SuccessContinuation successContinuation) { + return onSuccessTask(MAIN_THREAD, successContinuation); + } + + @Override + public Task onSuccessTask(Executor executor, SuccessContinuation successContinuation) { + SuccessContinuationExecutor c = new SuccessContinuationExecutor<>(executor, successContinuation); + enqueueOrInvoke(c); + return c.getTask(); + } +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateExecutor.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateExecutor.java new file mode 100644 index 00000000..6c448646 --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateExecutor.java @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import java.util.concurrent.Executor; + +public abstract class UpdateExecutor implements UpdateListener, Executor { + private Executor executor; + + public UpdateExecutor(Executor executor) { + this.executor = executor; + } + + @Override + public void execute(Runnable runnable) { + if (executor == null) return; + executor.execute(runnable); + } + + @Override + public void cancel() { + executor = null; + } +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateListener.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateListener.java new file mode 100644 index 00000000..d28c265a --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateListener.java @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import com.google.android.gms.tasks.Task; + +public interface UpdateListener { + void onTaskUpdate(Task task); + + void cancel(); +} diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateListenerLifecycleObserver.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateListenerLifecycleObserver.java new file mode 100644 index 00000000..dd307c50 --- /dev/null +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/UpdateListenerLifecycleObserver.java @@ -0,0 +1,98 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.tasks; + +import android.app.Activity; +import android.app.Application; +import android.os.Bundle; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; +import java.util.WeakHashMap; + +public class UpdateListenerLifecycleObserver { + private static WeakHashMap> map = new WeakHashMap<>(); + private static boolean activityLifecycleCallbacksRegistered = false; + private List>> list = new ArrayList<>(); + + public synchronized static UpdateListenerLifecycleObserver getObserverForActivity(Activity activity) { + WeakReference ref = map.get(activity); + if (ref != null) { + UpdateListenerLifecycleObserver observer = ref.get(); + if (observer != null) { + return observer; + } + } + + if (!activityLifecycleCallbacksRegistered) { + activity.getApplication().registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks()); + activityLifecycleCallbacksRegistered = true; + } + + UpdateListenerLifecycleObserver newInstance = new UpdateListenerLifecycleObserver(); + map.put(activity, new WeakReference<>(newInstance)); + return newInstance; + } + + private UpdateListenerLifecycleObserver() { + } + + public synchronized void registerActivityStopListener(UpdateListener listener) { + list.add(new WeakReference<>(listener)); + } + + public synchronized void onStop() { + for (WeakReference> ref : list) { + UpdateListener listener = ref.get(); + listener.cancel(); + } + list.clear(); + } + + private static class MyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + + } + + @Override + public void onActivityStarted(Activity activity) { + + } + + @Override + public void onActivityResumed(Activity activity) { + + } + + @Override + public void onActivityPaused(Activity activity) { + + } + + @Override + public void onActivityStopped(Activity activity) { + WeakReference ref = map.get(activity); + if (ref != null) { + UpdateListenerLifecycleObserver observer = ref.get(); + if (observer != null) { + observer.onStop(); + } + } + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + + } + + @Override + public void onActivityDestroyed(Activity activity) { + + } + } +} From 396965f4077a916ec0d42e8c4f1acdc9b174bd28 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 26 Jul 2020 11:59:27 +0200 Subject: [PATCH 02/51] Major changes to core and settings ui --- .../gms/common/ForegroundServiceContext.java | 2 +- play-services-core/build.gradle | 5 + .../ui/SwitchBarResourceSettingsFragment.java | 14 +- .../src/main/res/drawable/self_check.xml | 13 +- .../src/main/AndroidManifest.xml | 62 ++--- .../microg/gms/checkin/CheckinManager.java | 4 +- .../org/microg/gms/checkin/CheckinPrefs.java | 47 ++++ .../microg/gms/checkin/CheckinService.java | 4 +- .../microg/gms/checkin/TriggerReceiver.java | 3 +- .../gms/snet/SafetyNetClientServiceImpl.java | 1 + .../org/microg/gms/ui/CheckinFragment.java | 60 ----- .../microg/gms/ui/GcmAdvancedFragment.java | 11 - .../org/microg/gms/ui/GcmAppFragment.java | 224 ---------------- .../java/org/microg/gms/ui/GcmFragment.java | 240 ------------------ .../org/microg/gms/ui/SafetyNetFragment.java | 82 ------ .../org/microg/gms/ui/SettingsActivity.java | 114 ++------- .../gms/ui/SettingsDashboardActivity.java | 39 +++ .../org/microg/gms/ui/SettingsFragment.java | 97 +++++++ .../gms/ui/UnifiedBackendDetailsActivity.java | 18 -- .../gms/ui/UnifiedBackendListActivity.java | 32 --- .../org/microg/gms/ui/AppIconPreference.kt | 24 ++ .../gms/ui/DeviceRegistrationFragment.kt | 45 ++++ .../DeviceRegistrationPreferencesFragment.kt | 57 +++++ .../org/microg/gms/ui/PreferenceSwitchBar.kt | 10 + .../gms/ui/PushNotificationAllAppsFragment.kt | 115 +++++++++ .../gms/ui/PushNotificationAppFragment.kt | 58 +++++ .../PushNotificationAppPreferencesFragment.kt | 134 ++++++++++ .../microg/gms/ui/PushNotificationFragment.kt | 72 ++++++ .../ui/PushNotificationPreferencesFragment.kt | 121 +++++++++ .../org/microg/gms/ui/SafetyNetFragment.kt | 61 +++++ .../gms/ui/SafetyNetPreferencesFragment.kt | 17 ++ .../main/res/drawable-hdpi/ic_map_marker.png | Bin 1171 -> 0 bytes .../main/res/drawable-ldpi/add_account.png | Bin 169 -> 0 bytes .../main/res/drawable-mdpi/add_account.png | Bin 195 -> 0 bytes .../main/res/drawable-mdpi/ic_map_marker.png | Bin 791 -> 0 bytes .../main/res/drawable-xhdpi/add_account.png | Bin 328 -> 0 bytes .../main/res/drawable-xhdpi/ic_map_marker.png | Bin 1587 -> 0 bytes .../main/res/drawable-xxhdpi/add_account.png | Bin 428 -> 0 bytes .../res/drawable-xxhdpi/ic_map_marker.png | Bin 2388 -> 0 bytes .../main/res/drawable-xxxhdpi/add_account.png | Bin 586 -> 0 bytes .../res/drawable-xxxhdpi/ic_map_marker.png | Bin 3228 -> 0 bytes .../src/main/res/drawable/dots_horizontal.xml | 11 +- .../ic_add_account.xml} | 3 +- .../{certificate.xml => ic_certificate.xml} | 11 +- .../{gcm_bell.xml => ic_cloud_bell.xml} | 13 +- .../{device_login.xml => ic_device_login.xml} | 13 +- .../src/main/res/drawable/ic_expand_apps.xml | 19 ++ .../src/main/res/drawable/ic_info_outline.xml | 17 ++ .../src/main/res/drawable/ic_map_marker.xml | 17 ++ .../src/main/res/layout/ask_gcm.xml | 2 +- .../layout/device_registration_fragment.xml | 41 +++ .../layout/preference_category_no_label.xml | 9 + .../res/layout/preference_progress_bar.xml | 17 ++ .../main/res/layout/preference_switch_bar.xml | 73 ++++++ .../layout/push_notification_app_fragment.xml | 82 ++++++ .../res/layout/push_notification_fragment.xml | 45 ++++ .../main/res/layout/safety_net_fragment.xml | 45 ++++ .../res/layout/settings_root_activity.xml | 19 ++ .../src/main/res/navigation/nav_settings.xml | 152 +++++++++++ .../src/main/res/values/strings.xml | 2 + .../src/main/res/xml/preferences_checkin.xml | 22 -- .../xml/preferences_device_registration.xml | 24 ++ .../res/xml/preferences_gcm_app_detail.xml | 35 --- .../xml/preferences_push_notifications.xml | 40 +++ ...references_push_notifications_all_apps.xml | 39 +++ .../preferences_push_notifications_app.xml | 43 ++++ ...ces_snet.xml => preferences_safetynet.xml} | 16 +- .../src/main/res/xml/preferences_start.xml | 80 +++--- 68 files changed, 1712 insertions(+), 964 deletions(-) create mode 100644 play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/CheckinFragment.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/GcmAppFragment.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/GcmFragment.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/SafetyNetFragment.java create mode 100644 play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java create mode 100644 play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendDetailsActivity.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendListActivity.java create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBar.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetPreferencesFragment.kt delete mode 100644 play-services-core/src/main/res/drawable-hdpi/ic_map_marker.png delete mode 100644 play-services-core/src/main/res/drawable-ldpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-mdpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-mdpi/ic_map_marker.png delete mode 100644 play-services-core/src/main/res/drawable-xhdpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-xhdpi/ic_map_marker.png delete mode 100644 play-services-core/src/main/res/drawable-xxhdpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-xxhdpi/ic_map_marker.png delete mode 100644 play-services-core/src/main/res/drawable-xxxhdpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-xxxhdpi/ic_map_marker.png rename play-services-core/src/main/res/{drawable-anydpi-v21/add_account.xml => drawable/ic_add_account.xml} (92%) rename play-services-core/src/main/res/drawable/{certificate.xml => ic_certificate.xml} (71%) rename play-services-core/src/main/res/drawable/{gcm_bell.xml => ic_cloud_bell.xml} (79%) rename play-services-core/src/main/res/drawable/{device_login.xml => ic_device_login.xml} (58%) create mode 100644 play-services-core/src/main/res/drawable/ic_expand_apps.xml create mode 100644 play-services-core/src/main/res/drawable/ic_info_outline.xml create mode 100644 play-services-core/src/main/res/drawable/ic_map_marker.xml create mode 100644 play-services-core/src/main/res/layout/device_registration_fragment.xml create mode 100644 play-services-core/src/main/res/layout/preference_category_no_label.xml create mode 100644 play-services-core/src/main/res/layout/preference_progress_bar.xml create mode 100644 play-services-core/src/main/res/layout/preference_switch_bar.xml create mode 100644 play-services-core/src/main/res/layout/push_notification_app_fragment.xml create mode 100644 play-services-core/src/main/res/layout/push_notification_fragment.xml create mode 100644 play-services-core/src/main/res/layout/safety_net_fragment.xml create mode 100644 play-services-core/src/main/res/layout/settings_root_activity.xml create mode 100644 play-services-core/src/main/res/navigation/nav_settings.xml delete mode 100644 play-services-core/src/main/res/xml/preferences_checkin.xml create mode 100644 play-services-core/src/main/res/xml/preferences_device_registration.xml delete mode 100644 play-services-core/src/main/res/xml/preferences_gcm_app_detail.xml create mode 100644 play-services-core/src/main/res/xml/preferences_push_notifications.xml create mode 100644 play-services-core/src/main/res/xml/preferences_push_notifications_all_apps.xml create mode 100644 play-services-core/src/main/res/xml/preferences_push_notifications_app.xml rename play-services-core/src/main/res/xml/{preferences_snet.xml => preferences_safetynet.xml} (70%) diff --git a/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java b/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java index 50c3445f..3c2a7dbe 100644 --- a/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java +++ b/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java @@ -73,7 +73,7 @@ public class ForegroundServiceContext extends ContextWrapper { return new Notification.Builder(context, channel.getId()) .setOngoing(true) .setContentTitle("Running in background") - //.setSmallIcon(R.drawable.gcm_bell) + //.setSmallIcon(R.drawable.ic_cloud_bell) .build(); } } diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle index b55d79ef..8ee555cb 100644 --- a/play-services-core/build.gradle +++ b/play-services-core/build.gradle @@ -15,6 +15,8 @@ */ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' configurations { mapboxImplementation @@ -58,6 +60,8 @@ dependencies { implementation "androidx.navigation:navigation-ui:$navigationVersion" implementation "androidx.navigation:navigation-fragment-ktx:$navigationVersion" implementation "androidx.navigation:navigation-ui-ktx:$navigationVersion" + + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" } android { @@ -87,6 +91,7 @@ android { sourceSets { main { java.srcDirs += 'src/main/protos-java' + java.srcDirs += 'src/main/kotlin' } } diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBarResourceSettingsFragment.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBarResourceSettingsFragment.java index 950ac8b2..b2b33e3b 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBarResourceSettingsFragment.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBarResourceSettingsFragment.java @@ -29,24 +29,22 @@ public abstract class SwitchBarResourceSettingsFragment extends ResourceSettings public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - AbstractSettingsActivity activity = (AbstractSettingsActivity) getActivity(); - - switchBar = activity.getSwitchBar(); - switchBar.show(); - switchCompat = switchBar.getSwitch(); +// switchBar = activity.getSwitchBar(); +// switchBar.show(); +// switchCompat = switchBar.getSwitch(); } @Override public void onDestroyView() { super.onDestroyView(); - switchBar.hide(); +// switchBar.hide(); } @Override public void onResume() { super.onResume(); if (!listenerSetup) { - switchBar.addOnSwitchChangeListener(this); +// switchBar.addOnSwitchChangeListener(this); listenerSetup = true; } } @@ -54,7 +52,7 @@ public abstract class SwitchBarResourceSettingsFragment extends ResourceSettings @Override public void onPause() { if (listenerSetup) { - switchBar.removeOnSwitchChangeListener(this); +// switchBar.removeOnSwitchChangeListener(this); listenerSetup = false; } super.onPause(); diff --git a/play-services-core/microg-ui-tools/src/main/res/drawable/self_check.xml b/play-services-core/microg-ui-tools/src/main/res/drawable/self_check.xml index 92b47890..714b5e11 100644 --- a/play-services-core/microg-ui-tools/src/main/res/drawable/self_check.xml +++ b/play-services-core/microg-ui-tools/src/main/res/drawable/self_check.xml @@ -16,12 +16,13 @@ --> + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorAccent" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml index e6dee201..6b58afd7 100644 --- a/play-services-core/src/main/AndroidManifest.xml +++ b/play-services-core/src/main/AndroidManifest.xml @@ -106,15 +106,15 @@ android:allowBackup="false" android:extractNativeLibs="false" android:icon="@mipmap/ic_core_service_app" - android:label="@string/gms_app_name"> + android:label="@string/gms_app_name" + android:theme="@style/Theme.AppCompat.DayNight"> - + + @@ -410,8 +411,7 @@ android:name="org.microg.gms.ui.SettingsActivity" android:icon="@mipmap/ic_microg_settings" android:label="@string/gms_settings_name" - android:roundIcon="@mipmap/ic_microg_settings" - android:theme="@style/Theme.AppCompat.DayNight"> + android:roundIcon="@mipmap/ic_microg_settings"> @@ -423,13 +423,18 @@ + + + android:targetActivity="org.microg.gms.ui.SettingsActivity"> @@ -452,52 +457,25 @@ - - - - - - - - + android:label="@string/pref_about_title" /> + android:label="@string/gms_settings_name" /> + android:label="@string/service_name_snet" /> + android:label="@string/service_name_snet" /> + android:label="@string/self_check_title" /> - + @@ -507,9 +485,7 @@ - + diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java index 4b67bdd5..631db813 100644 --- a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java @@ -33,8 +33,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import static org.microg.gms.checkin.TriggerReceiver.PREF_ENABLE_CHECKIN; - public class CheckinManager { private static final long MIN_CHECKIN_INTERVAL = 3 * 60 * 60 * 1000; // 3 hours @@ -43,7 +41,7 @@ public class CheckinManager { LastCheckinInfo info = LastCheckinInfo.read(context); if (!force && info.lastCheckin > System.currentTimeMillis() - MIN_CHECKIN_INTERVAL) return null; - if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREF_ENABLE_CHECKIN, false)) + if (!CheckinPrefs.get(context).isEnabled()) return null; List accounts = new ArrayList(); AccountManager accountManager = AccountManager.get(context); diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java new file mode 100644 index 00000000..d18914b6 --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.checkin; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +public class CheckinPrefs implements SharedPreferences.OnSharedPreferenceChangeListener { + public static final String PREF_ENABLE_CHECKIN = "checkin_enable_service"; + private static CheckinPrefs INSTANCE; + + public static CheckinPrefs get(Context context) { + if (INSTANCE == null) { + if (context == null) return new CheckinPrefs(null); + INSTANCE = new CheckinPrefs(context.getApplicationContext()); + } + return INSTANCE; + } + + private SharedPreferences preferences; + private boolean checkinEnabled = false; + + private CheckinPrefs(Context context) { + if (context != null) { + preferences = PreferenceManager.getDefaultSharedPreferences(context); + preferences.registerOnSharedPreferenceChangeListener(this); + update(); + } + } + + private void update() { + checkinEnabled = preferences.getBoolean(PREF_ENABLE_CHECKIN, false); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + update(); + } + + public boolean isEnabled() { + return checkinEnabled; + } +} diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java index fd31234a..1f775a93 100644 --- a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java @@ -34,8 +34,6 @@ import org.microg.gms.common.ForegroundServiceContext; import org.microg.gms.gcm.McsService; import org.microg.gms.people.PeopleManager; -import static org.microg.gms.checkin.TriggerReceiver.PREF_ENABLE_CHECKIN; - public class CheckinService extends IntentService { private static final String TAG = "GmsCheckinSvc"; public static final String BIND_ACTION = "com.google.android.gms.checkin.BIND_TO_SERVICE"; @@ -58,7 +56,7 @@ public class CheckinService extends IntentService { protected void onHandleIntent(Intent intent) { try { ForegroundServiceContext.completeForegroundService(this, intent, TAG); - if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PREF_ENABLE_CHECKIN, false)) { + if (CheckinPrefs.get(this).isEnabled()) { LastCheckinInfo info = CheckinManager.checkin(this, intent.getBooleanExtra(EXTRA_FORCE_CHECKIN, false)); if (info != null) { Log.d(TAG, "Checked in as " + Long.toHexString(info.androidId)); diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java b/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java index b52a7133..123d76d3 100644 --- a/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java @@ -31,7 +31,6 @@ import static org.microg.gms.checkin.CheckinService.EXTRA_FORCE_CHECKIN; public class TriggerReceiver extends WakefulBroadcastReceiver { private static final String TAG = "GmsCheckinTrigger"; - public static final String PREF_ENABLE_CHECKIN = "checkin_enable_service"; private static final long REGULAR_CHECKIN_INTERVAL = 12 * 60 * 60 * 1000; // 12 hours @Override @@ -40,7 +39,7 @@ public class TriggerReceiver extends WakefulBroadcastReceiver { boolean force = "android.provider.Telephony.SECRET_CODE".equals(intent.getAction()); ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREF_ENABLE_CHECKIN, false) || force) { + if (CheckinPrefs.get(context).isEnabled() || force) { if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction()) && LastCheckinInfo.read(context).lastCheckin > System.currentTimeMillis() - REGULAR_CHECKIN_INTERVAL) { return; diff --git a/play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java b/play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java index 848d1343..8cae71e7 100644 --- a/play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java @@ -80,6 +80,7 @@ public class SafetyNetClientServiceImpl extends ISafetyNetService.Stub { bundle.putString("contentBinding", attestation.getPayloadHashBase64()); RemoteDroidGuardConnector.Result dg = conn.guard("attest", Long.toString(LastCheckinInfo.read(context).androidId), bundle); if (!SafetyNetPrefs.get(context).isOfficial() || dg != null && dg.getStatusCode() == 0 && dg.getResult() != null) { + Log.d(TAG, dg == null ? "No dg result" : ("Status: " + dg.getStatusCode() + ", error:" + dg.getErrorMsg())); if (dg != null && dg.getStatusCode() == 0 && dg.getResult() != null) { attestation.setDroidGaurdResult(Base64.encodeToString(dg.getResult(), Base64.NO_WRAP + Base64.NO_PADDING + Base64.URL_SAFE)); } diff --git a/play-services-core/src/main/java/org/microg/gms/ui/CheckinFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/CheckinFragment.java deleted file mode 100644 index aee8642f..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/CheckinFragment.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2017 microG Project Team - * - * 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 - * - * http://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. - */ - -package org.microg.gms.ui; - -import android.os.Bundle; -import android.preference.PreferenceManager; - -import androidx.fragment.app.Fragment; - -import com.google.android.gms.R; - -import org.microg.tools.ui.AbstractSettingsActivity; -import org.microg.tools.ui.SwitchBarResourceSettingsFragment; - -import static org.microg.gms.checkin.TriggerReceiver.PREF_ENABLE_CHECKIN; - -public class CheckinFragment extends SwitchBarResourceSettingsFragment { - - public CheckinFragment() { - preferencesResource = R.xml.preferences_checkin; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - switchBar.setChecked(PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean(PREF_ENABLE_CHECKIN, false)); - } - - @Override - public void onSwitchBarChanged(boolean isChecked) { - PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putBoolean(PREF_ENABLE_CHECKIN, isChecked).apply(); - } - - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new CheckinFragment(); - } - } -} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java index e7c846f2..0b66c013 100644 --- a/play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java +++ b/play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java @@ -94,15 +94,4 @@ public class GcmAdvancedFragment extends ResourceSettingsFragment { } return (heartbeatMs / 60000) + " minutes"; } - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new GcmAdvancedFragment(); - } - } } diff --git a/play-services-core/src/main/java/org/microg/gms/ui/GcmAppFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/GcmAppFragment.java deleted file mode 100644 index 232a2d65..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/GcmAppFragment.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.microg.gms.ui; - -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Bundle; -import android.provider.Settings; -import android.text.format.DateUtils; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.appcompat.app.AlertDialog; -import androidx.fragment.app.Fragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; -import androidx.preference.SwitchPreference; - -import com.google.android.gms.R; - -import org.microg.gms.gcm.GcmDatabase; -import org.microg.gms.gcm.PushRegisterManager; -import org.microg.tools.ui.AbstractSettingsActivity; -import org.microg.tools.ui.ResourceSettingsFragment; - -import java.util.List; - -import static android.text.format.DateUtils.FORMAT_SHOW_TIME; -import static android.text.format.DateUtils.MINUTE_IN_MILLIS; -import static android.text.format.DateUtils.WEEK_IN_MILLIS; - -public class GcmAppFragment extends ResourceSettingsFragment { - public static final String EXTRA_PACKAGE_NAME = "package_name"; - - public static final String PREF_WAKE_FOR_DELIVERY = "gcm_app_wake_for_delivery"; - public static final String PREF_ALLOW_REGISTER = "gcm_app_allow_register"; - public static final String PREF_REGISTER_DETAILS = "gcm_app_register_details"; - public static final String PREF_MESSAGE_DETAILS = "gcm_app_message_details"; - - protected String packageName; - private String appName; - private GcmDatabase database; - - public GcmAppFragment() { - preferencesResource = R.xml.preferences_gcm_app_detail; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - packageName = getArguments().getString(EXTRA_PACKAGE_NAME); - - AbstractSettingsActivity activity = (AbstractSettingsActivity) getActivity(); - - if (packageName != null && activity != null) { - activity.setCustomBarLayout(R.layout.app_bar); - try { - PackageManager pm = activity.getPackageManager(); - ApplicationInfo info = pm.getApplicationInfo(packageName, 0); - ((ImageView) activity.findViewById(R.id.app_icon)).setImageDrawable(pm.getApplicationIcon(info)); - appName = pm.getApplicationLabel(info).toString(); - ((TextView) activity.findViewById(R.id.app_name)).setText(appName); - View view = activity.findViewById(R.id.app_bar); - view.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(); - intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); - Uri uri = Uri.fromParts("package", packageName, null); - intent.setData(uri); - getContext().startActivity(intent); - } - }); - view.setClickable(true); - } catch (Exception e) { - appName = packageName; - ((TextView) activity.findViewById(R.id.app_name)).setText(packageName); - } - } - - database = new GcmDatabase(getContext()); - updateAppDetails(); - } - - @Override - public void onPause() { - super.onPause(); - database.close(); - } - - @Override - public void onResume() { - super.onResume(); - if (database != null) { - updateAppDetails(); - } - } - - private void updateAppDetails() { - GcmDatabase.App app = database.getApp(packageName); - if (app == null) { - getActivity().finish(); - return; - } - PreferenceScreen root = getPreferenceScreen(); - - SwitchPreference wakeForDelivery = (SwitchPreference) root.findPreference(PREF_WAKE_FOR_DELIVERY); - wakeForDelivery.setChecked(app.wakeForDelivery); - wakeForDelivery.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (newValue instanceof Boolean) { - database.setAppWakeForDelivery(packageName, (Boolean) newValue); - return true; - } - return false; - } - }); - - SwitchPreference allowRegister = (SwitchPreference) root.findPreference(PREF_ALLOW_REGISTER); - allowRegister.setChecked(app.allowRegister); - allowRegister.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (newValue instanceof Boolean) { - if (!(boolean) newValue) { - final List registrations = database.getRegistrationsByApp(packageName); - if (!registrations.isEmpty()) { - showUnregisterConfirm(registrations, getString(R.string.gcm_unregister_after_deny_message)); - } - } - database.setAppAllowRegister(packageName, (Boolean) newValue); - return true; - } - return false; - } - }); - - Preference registerDetails = root.findPreference(PREF_REGISTER_DETAILS); - final List registrations = database.getRegistrationsByApp(packageName); - if (registrations.isEmpty()) { - registerDetails.setTitle(""); - registerDetails.setSelectable(false); - registerDetails.setSummary(R.string.gcm_not_registered); - } else { - StringBuilder sb = new StringBuilder(); - for (GcmDatabase.Registration registration : registrations) { - if (sb.length() != 0) sb.append("\n"); - if (registration.timestamp == 0) { - sb.append(getString(R.string.gcm_registered)); - } else { - sb.append(getString(R.string.gcm_registered_since, DateUtils.getRelativeDateTimeString(getContext(), registration.timestamp, MINUTE_IN_MILLIS, WEEK_IN_MILLIS, FORMAT_SHOW_TIME))); - } - } - registerDetails.setTitle(R.string.gcm_unregister_app); - registerDetails.setSummary(sb.toString()); - registerDetails.setSelectable(true); - registerDetails.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showUnregisterConfirm(registrations, getString(R.string.gcm_unregister_confirm_message)); - return true; - } - }); - } - - Preference messageDetails = root.findPreference(PREF_MESSAGE_DETAILS); - if (app.totalMessageCount == 0) { - messageDetails.setSummary(R.string.gcm_no_message_yet); - } else { - String s = getString(R.string.gcm_messages_counter, app.totalMessageCount, app.totalMessageBytes); - if (app.lastMessageTimestamp != 0) { - s += "\n" + getString(R.string.gcm_last_message_at, DateUtils.getRelativeDateTimeString(getContext(), app.lastMessageTimestamp, MINUTE_IN_MILLIS, WEEK_IN_MILLIS, FORMAT_SHOW_TIME)); - } - messageDetails.setSummary(s); - } - } - - private void showUnregisterConfirm(final List registrations, String unregisterConfirmDesc) { - new AlertDialog.Builder(getContext()) - .setTitle(getString(R.string.gcm_unregister_confirm_title, appName)) - .setMessage(unregisterConfirmDesc) - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - new Thread(new Runnable() { - @Override - public void run() { - for (GcmDatabase.Registration registration : registrations) { - PushRegisterManager.unregister(getContext(), registration.packageName, registration.signature, null, null); - } - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - updateAppDetails(); - } - }); - } - }).start(); - } - }) - .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // Do nothing - } - }).show(); - } - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - GcmAppFragment fragment = new GcmAppFragment(); - fragment.setArguments(getIntent().getExtras()); - return fragment; - } - } -} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/GcmFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/GcmFragment.java deleted file mode 100644 index 6c4ee0db..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/GcmFragment.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. - */ - -package org.microg.gms.ui; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.text.format.DateUtils; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; - -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceGroup; -import androidx.preference.PreferenceScreen; -import androidx.preference.PreferenceViewHolder; - -import com.google.android.gms.R; - -import org.microg.gms.gcm.GcmDatabase; -import org.microg.gms.gcm.GcmPrefs; -import org.microg.gms.gcm.McsConstants; -import org.microg.gms.gcm.McsService; -import org.microg.gms.gcm.TriggerReceiver; -import org.microg.tools.ui.AbstractSettingsActivity; -import org.microg.tools.ui.DimmableIconPreference; -import org.microg.tools.ui.SwitchBarResourceSettingsFragment; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import static android.text.format.DateUtils.FORMAT_SHOW_TIME; -import static android.text.format.DateUtils.MINUTE_IN_MILLIS; -import static android.text.format.DateUtils.WEEK_IN_MILLIS; - -public class GcmFragment extends SwitchBarResourceSettingsFragment { - - public static final String PREF_GCM_STATUS = "pref_gcm_status"; - public static final String PREF_GCM_APPS = "gcm_apps"; - - private GcmDatabase database; - - private final int MENU_ADVANCED = Menu.FIRST; - - public GcmFragment() { - preferencesResource = R.xml.preferences_gcm; - } - - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - setHasOptionsMenu(true); - switchBar.setChecked(GcmPrefs.get(getContext()).isEnabled()); - } - - @Override - public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { - super.onCreatePreferences(savedInstanceState, rootKey); - - database = new GcmDatabase(getContext()); - - updateContent(); - } - - @Override - public void onResume() { - super.onResume(); - updateContent(); - } - - @Override - public void onPause() { - super.onPause(); - database.close(); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case MENU_ADVANCED: - Intent intent = new Intent(getContext(), GcmAdvancedFragment.AsActivity.class); - startActivity(intent); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - @Override - public void onSwitchBarChanged(boolean isChecked) { - getPreferenceManager().getSharedPreferences().edit().putBoolean(GcmPrefs.PREF_ENABLE_GCM, isChecked).apply(); - if (!isChecked) { - McsService.stop(getContext()); - } else { - getContext().sendBroadcast(new Intent(TriggerReceiver.FORCE_TRY_RECONNECT, null, getContext(), TriggerReceiver.class)); - } - updateContent(); - } - - private static void addPreferencesSorted(List prefs, PreferenceGroup container) { - // If there's some items to display, sort the items and add them to the container. - Collections.sort(prefs, new Comparator() { - @Override - public int compare(Preference lhs, Preference rhs) { - return lhs.getTitle().toString().toLowerCase().compareTo(rhs.getTitle().toString().toLowerCase()); - } - }); - for (Preference entry : prefs) { - container.addPreference(entry); - } - } - - private void updateContent() { - PreferenceScreen root = getPreferenceScreen(); - - if (McsService.isConnected()) { - root.findPreference(PREF_GCM_STATUS).setSummary(getString(R.string.gcm_state_connected, DateUtils.getRelativeTimeSpanString(McsService.getStartTimestamp(), System.currentTimeMillis(), 0))); - } else { - root.findPreference(PREF_GCM_STATUS).setSummary(getString(R.string.gcm_state_disconnected)); - } - - PreferenceCategory appList = (PreferenceCategory) root.findPreference(PREF_GCM_APPS); - appList.removeAll(); - List list = database.getAppList(); - if (!list.isEmpty()) { - List appListPrefs = new ArrayList<>(); - PackageManager pm = getContext().getPackageManager(); - for (GcmDatabase.App app : list) { - try { - pm.getApplicationInfo(app.packageName, 0); - appListPrefs.add(new GcmAppPreference(getPreferenceManager().getContext(), app)); - } catch (PackageManager.NameNotFoundException e) { - final List registrations = database.getRegistrationsByApp(app.packageName); - if (registrations.isEmpty()) { - database.removeApp(app.packageName); - } else { - appListPrefs.add(new GcmAppPreference(getPreferenceManager().getContext(), app)); - } - } - } - addPreferencesSorted(appListPrefs, appList); - } else { - // If there's no item to display, add a "None" item. - Preference banner = new Preference(getPreferenceManager().getContext()); - banner.setLayoutResource(R.layout.list_no_item); - banner.setTitle(R.string.list_no_item_none); - banner.setSelectable(false); - appList.addPreference(banner); - } - } - - public static class GcmAppPreference extends DimmableIconPreference implements Preference.OnPreferenceClickListener { - - private GcmDatabase database; - private GcmDatabase.App app; - - public GcmAppPreference(Context context, GcmDatabase.App app) { - super(context); - this.app = app; - this.database = new GcmDatabase(context); - setKey(app.packageName); - - PackageManager packageManager = context.getPackageManager(); - try { - ApplicationInfo applicationInfo = packageManager.getApplicationInfo(app.packageName, 0); - setTitle(packageManager.getApplicationLabel(applicationInfo)); - setIcon(packageManager.getApplicationIcon(applicationInfo)); - } catch (PackageManager.NameNotFoundException e) { - setTitle(app.packageName); - setIcon(android.R.drawable.sym_def_app_icon); - } - setOnPreferenceClickListener(this); - updateViewDetails(); - } - - private void updateViewDetails() { - if (database.getRegistrationsByApp(app.packageName).isEmpty()) { - setSummary(R.string.gcm_not_registered); - } else if (app.lastMessageTimestamp > 0) { - setSummary(getContext().getString(R.string.gcm_last_message_at, DateUtils.getRelativeDateTimeString(getContext(), app.lastMessageTimestamp, MINUTE_IN_MILLIS, WEEK_IN_MILLIS, FORMAT_SHOW_TIME))); - } else { - setSummary(R.string.gcm_no_message_yet); - } - database.close(); - } - - @Override - public void onBindViewHolder(PreferenceViewHolder view) { - updateViewDetails(); - super.onBindViewHolder(view); - } - - @Override - public boolean onPreferenceClick(Preference preference) { - Intent intent = new Intent(getContext(), GcmAppFragment.AsActivity.class); - intent.putExtra(GcmAppFragment.EXTRA_PACKAGE_NAME, app.packageName); - getContext().startActivity(intent); - return true; - } - } - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new GcmFragment(); - } - } -} \ No newline at end of file diff --git a/play-services-core/src/main/java/org/microg/gms/ui/SafetyNetFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/SafetyNetFragment.java deleted file mode 100644 index 3756aff8..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/SafetyNetFragment.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2017 microG Project Team - * - * 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 - * - * http://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. - */ - -package org.microg.gms.ui; - -import android.content.Intent; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; - -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import com.google.android.gms.R; - -import org.microg.gms.snet.SafetyNetPrefs; -import org.microg.tools.ui.AbstractSettingsActivity; -import org.microg.tools.ui.SwitchBarResourceSettingsFragment; - -public class SafetyNetFragment extends SwitchBarResourceSettingsFragment { - private final int MENU_ADVANCED = Menu.FIRST; - - public SafetyNetFragment() { - preferencesResource = R.xml.preferences_snet; - } - - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - setHasOptionsMenu(true); - switchBar.setChecked(SafetyNetPrefs.get(getContext()).isEnabled()); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case MENU_ADVANCED: - Intent intent = new Intent(getContext(), SafetyNetAdvancedFragment.AsActivity.class); - startActivity(intent); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - @Override - public void onSwitchBarChanged(boolean isChecked) { - SafetyNetPrefs.get(getContext()).setEnabled(isChecked); - } - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new SafetyNetFragment(); - } - } -} \ No newline at end of file diff --git a/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java index 965872ff..05befb86 100644 --- a/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java +++ b/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java @@ -1,112 +1,34 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. - */ - package org.microg.gms.ui; import android.os.Bundle; -import android.preference.PreferenceManager; -import android.text.TextUtils; import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; +import androidx.appcompat.app.AppCompatActivity; +import androidx.navigation.NavController; +import androidx.navigation.fragment.NavHostFragment; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; import com.google.android.gms.R; -import org.microg.gms.gcm.GcmDatabase; -import org.microg.gms.gcm.GcmPrefs; -import org.microg.gms.snet.SafetyNetPrefs; -//import org.microg.nlp.Preferences; -import org.microg.tools.ui.AbstractDashboardActivity; -import org.microg.tools.ui.ResourceSettingsFragment; +public class SettingsActivity extends AppCompatActivity { + private AppBarConfiguration appBarConfiguration; -import static org.microg.gms.checkin.TriggerReceiver.PREF_ENABLE_CHECKIN; - -public class SettingsActivity extends AbstractDashboardActivity { - - public SettingsActivity() { - preferencesResource = R.xml.preferences_start; - addCondition(Conditions.GCM_BATTERY_OPTIMIZATIONS); - addCondition(Conditions.PERMISSIONS); + private NavController getNavController() { + return ((NavHostFragment)getSupportFragmentManager().findFragmentById(R.id.navhost)).getNavController(); } @Override - protected Fragment getFragment() { - return new FragmentImpl(); + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.settings_root_activity); + + appBarConfiguration = new AppBarConfiguration.Builder(getNavController().getGraph()).build(); + NavigationUI.setupActionBarWithNavController(this, getNavController(), appBarConfiguration); } - public static class FragmentImpl extends ResourceSettingsFragment { - - public static final String PREF_ABOUT = "pref_about"; - public static final String PREF_GCM = "pref_gcm"; - public static final String PREF_SNET = "pref_snet"; -// public static final String PREF_UNIFIEDNLP = "pref_unifiednlp"; - public static final String PREF_CHECKIN = "pref_checkin"; - - public FragmentImpl() { - preferencesResource = R.xml.preferences_start; - } - - @Override - public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { - super.onCreatePreferences(savedInstanceState, rootKey); - updateDetails(); - } - - @Override - public void onResume() { - super.onResume(); - updateDetails(); - } - - private void updateDetails() { - findPreference(PREF_ABOUT).setSummary(getString(R.string.about_version_str, AboutFragment.getSelfVersion(getContext()))); - if (GcmPrefs.get(getContext()).isEnabled()) { - GcmDatabase database = new GcmDatabase(getContext()); - int regCount = database.getRegistrationList().size(); - database.close(); - findPreference(PREF_GCM).setSummary(getString(R.string.abc_capital_on) + " / " + getResources().getQuantityString(R.plurals.gcm_registered_apps_counter, regCount, regCount)); - } else { - findPreference(PREF_GCM).setSummary(R.string.abc_capital_off); - } - - if (SafetyNetPrefs.get(getContext()).isEnabled()) { - String snet_info = ""; - - if (SafetyNetPrefs.get(getContext()).isOfficial()) { - snet_info = getString(R.string.pref_snet_status_official_info); - } else if (SafetyNetPrefs.get(getContext()).isSelfSigned()) { - snet_info = getString(R.string.pref_snet_status_self_signed_info); - } else if (SafetyNetPrefs.get(getContext()).isThirdParty()) { - snet_info = getString(R.string.pref_snet_status_third_party_info); - } - - findPreference(PREF_SNET).setSummary(getString(R.string.service_status_enabled) + " / " + snet_info); - } else { - findPreference(PREF_SNET).setSummary(R.string.service_status_disabled); - } - -// Preferences unifiedNlPrefs = new Preferences(getContext()); -// int backendCount = TextUtils.isEmpty(unifiedNlPrefs.getLocationBackends()) ? 0 : -// Preferences.splitBackendString(unifiedNlPrefs.getLocationBackends()).length; -// backendCount += TextUtils.isEmpty(unifiedNlPrefs.getGeocoderBackends()) ? 0 : -// Preferences.splitBackendString(unifiedNlPrefs.getGeocoderBackends()).length; -// findPreference(PREF_UNIFIEDNLP).setSummary(getResources().getQuantityString(R.plurals.pref_unifiednlp_summary, backendCount, backendCount)); - - boolean checkinEnabled = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean(PREF_ENABLE_CHECKIN, false); - findPreference(PREF_CHECKIN).setSummary(checkinEnabled ? R.string.service_status_enabled : R.string.service_status_disabled); - } + @Override + public boolean onSupportNavigateUp() { + return NavigationUI.navigateUp(getNavController(), appBarConfiguration) || super.onSupportNavigateUp(); } } diff --git a/play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java new file mode 100644 index 00000000..f3b62c1d --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013-2017 microG Project Team + * + * 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 + * + * http://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. + */ + +package org.microg.gms.ui; + +import androidx.fragment.app.Fragment; + +import com.google.android.gms.R; + +//import org.microg.nlp.Preferences; +import org.microg.tools.ui.AbstractDashboardActivity; + +public class SettingsDashboardActivity extends AbstractDashboardActivity { + + public SettingsDashboardActivity() { + preferencesResource = R.xml.preferences_start; + addCondition(Conditions.GCM_BATTERY_OPTIMIZATIONS); + addCondition(Conditions.PERMISSIONS); + } + + @Override + protected Fragment getFragment() { + return new SettingsFragment(); + } + +} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java new file mode 100644 index 00000000..482152e6 --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java @@ -0,0 +1,97 @@ +package org.microg.gms.ui; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.navigation.fragment.NavHostFragment; + +import com.google.android.gms.R; + +import org.microg.gms.checkin.CheckinPrefs; +import org.microg.gms.gcm.GcmDatabase; +import org.microg.gms.gcm.GcmPrefs; +import org.microg.gms.snet.SafetyNetPrefs; +import org.microg.tools.ui.ResourceSettingsFragment; + +public class SettingsFragment extends ResourceSettingsFragment { + + public static final String PREF_ABOUT = "pref_about"; + public static final String PREF_GCM = "pref_gcm"; + public static final String PREF_SNET = "pref_snet"; + public static final String PREF_UNIFIEDNLP = "pref_unifiednlp"; + public static final String PREF_CHECKIN = "pref_checkin"; + + public SettingsFragment() { + preferencesResource = R.xml.preferences_start; + } + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { + super.onCreatePreferences(savedInstanceState, rootKey); + updateDetails(); + } + + @Override + public void onResume() { + super.onResume(); + updateDetails(); + } + + private void updateDetails() { + findPreference(PREF_ABOUT).setSummary(getString(R.string.about_version_str, AboutFragment.getSelfVersion(getContext()))); + findPreference(PREF_ABOUT).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openAbout); + return true; + }); + if (GcmPrefs.get(getContext()).isEnabled()) { + GcmDatabase database = new GcmDatabase(getContext()); + int regCount = database.getRegistrationList().size(); + database.close(); + findPreference(PREF_GCM).setSummary(getString(R.string.service_status_enabled_short) + " - " + getResources().getQuantityString(R.plurals.gcm_registered_apps_counter, regCount, regCount)); + } else { + findPreference(PREF_GCM).setSummary(R.string.service_status_disabled_short); + } + findPreference(PREF_GCM).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openGcmSettings); + return true; + }); + + if (SafetyNetPrefs.get(getContext()).isEnabled()) { + String snet_info = ""; + + if (SafetyNetPrefs.get(getContext()).isOfficial()) { + snet_info = getString(R.string.pref_snet_status_official_info); + } else if (SafetyNetPrefs.get(getContext()).isSelfSigned()) { + snet_info = getString(R.string.pref_snet_status_self_signed_info); + } else if (SafetyNetPrefs.get(getContext()).isThirdParty()) { + snet_info = getString(R.string.pref_snet_status_third_party_info); + } + + findPreference(PREF_SNET).setSummary(getString(R.string.service_status_enabled_short)); + } else { + findPreference(PREF_SNET).setSummary(R.string.service_status_disabled_short); + } + findPreference(PREF_SNET).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openSafetyNetSettings); + return true; + }); + +// Preferences unifiedNlPrefs = new Preferences(getContext()); +// int backendCount = TextUtils.isEmpty(unifiedNlPrefs.getLocationBackends()) ? 0 : +// Preferences.splitBackendString(unifiedNlPrefs.getLocationBackends()).length; +// backendCount += TextUtils.isEmpty(unifiedNlPrefs.getGeocoderBackends()) ? 0 : +// Preferences.splitBackendString(unifiedNlPrefs.getGeocoderBackends()).length; +// findPreference(PREF_UNIFIEDNLP).setSummary(getResources().getQuantityString(R.plurals.pref_unifiednlp_summary, backendCount, backendCount)); + findPreference(PREF_UNIFIEDNLP).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openUnifiedNlpSettings); + return true; + }); + + boolean checkinEnabled = CheckinPrefs.get(getContext()).isEnabled(); + findPreference(PREF_CHECKIN).setSummary(checkinEnabled ? R.string.service_status_enabled_short : R.string.service_status_disabled_short); + findPreference(PREF_CHECKIN).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openCheckinSettings); + return true; + }); + } +} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendDetailsActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendDetailsActivity.java deleted file mode 100644 index 6f786653..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendDetailsActivity.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.microg.gms.ui; - -import androidx.fragment.app.Fragment; - -import org.microg.nlp.ui.BackendDetailsFragment; -import org.microg.nlp.ui.BackendListFragment; -import org.microg.tools.ui.AbstractSettingsActivity; - -public class UnifiedBackendDetailsActivity extends AbstractSettingsActivity { - public UnifiedBackendDetailsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new BackendDetailsFragment(); - } -} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendListActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendListActivity.java deleted file mode 100644 index 7bfd0aff..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendListActivity.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.microg.gms.ui; - -import android.os.Bundle; -import android.util.Log; - -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; - -import org.microg.nlp.ui.BackendListFragment; -import org.microg.tools.ui.AbstractSettingsActivity; - -public class UnifiedBackendListActivity extends AppCompatActivity { - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - try { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } catch (Exception e) { - Log.w("GmsCoreSettingUi", e); - } - getSupportFragmentManager().beginTransaction().add(new BackendListFragment(), null).commit(); - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - finish(); - } -} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt new file mode 100644 index 00000000..97bcca1d --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.content.Context +import android.util.DisplayMetrics +import android.widget.ImageView +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder + +class AppIconPreference(context: Context) : Preference(context) { + override fun onBindViewHolder(holder: PreferenceViewHolder?) { + super.onBindViewHolder(holder) + val icon = holder?.findViewById(android.R.id.icon) + if (icon is ImageView) { + icon.adjustViewBounds = true + icon.scaleType = ImageView.ScaleType.CENTER_INSIDE + icon.maxHeight = (32.0 * context.resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT).toInt() + } + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt new file mode 100644 index 00000000..68f30f72 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.content.Intent +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import androidx.preference.PreferenceManager +import com.google.android.gms.R +import com.google.android.gms.databinding.DeviceRegistrationFragmentBinding +import org.microg.gms.checkin.CheckinPrefs +import org.microg.gms.checkin.CheckinPrefs.PREF_ENABLE_CHECKIN +import org.microg.gms.checkin.TriggerReceiver + +class DeviceRegistrationFragment : Fragment(R.layout.device_registration_fragment) { + private lateinit var binding: DeviceRegistrationFragmentBinding + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = DeviceRegistrationFragmentBinding.inflate(inflater, container, false) + binding.switchBarCallback = object : PreferenceSwitchBarCallback { + override fun onChecked(newStatus: Boolean) { + PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(PREF_ENABLE_CHECKIN, newStatus).commit() + if (newStatus) { + requireContext().sendOrderedBroadcast(Intent(requireContext(), TriggerReceiver::class.java), null) + } + binding.checkinEnabled = newStatus + } + } + return binding.root + } + + override fun onResume() { + super.onResume() + lifecycleScope.launchWhenResumed { + binding.checkinEnabled = CheckinPrefs.get(context).isEnabled + } + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt new file mode 100644 index 00000000..9bc63cfe --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.os.Handler +import android.text.format.DateUtils +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import com.google.android.gms.R +import org.microg.gms.checkin.CheckinPrefs +import org.microg.gms.checkin.LastCheckinInfo + +class DeviceRegistrationPreferencesFragment : PreferenceFragmentCompat() { + private lateinit var statusCategory: PreferenceCategory + private lateinit var status: Preference + private val handler = Handler() + private val updateRunnable = Runnable { updateStatus() } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_device_registration) + } + + override fun onBindPreferences() { + statusCategory = preferenceScreen.findPreference("prefcat_device_registration_status") ?: statusCategory + status = preferenceScreen.findPreference("pref_device_registration_status") ?: status + } + + override fun onResume() { + super.onResume() + updateStatus() + } + + override fun onPause() { + super.onPause() + handler.removeCallbacks(updateRunnable) + } + + private fun updateStatus() { + handler.postDelayed(updateRunnable, UPDATE_INTERVAL) + statusCategory.isVisible = CheckinPrefs.get(context).isEnabled + val checkinInfo = LastCheckinInfo.read(requireContext()) + status.summary = if (checkinInfo.lastCheckin > 0) { + "Last registration: " + DateUtils.getRelativeTimeSpanString(checkinInfo.lastCheckin, System.currentTimeMillis(), 0) + } else { + "Not registered" + } + } + + companion object { + private const val UPDATE_INTERVAL = 1000L + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBar.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBar.kt new file mode 100644 index 00000000..b66f1119 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBar.kt @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +interface PreferenceSwitchBarCallback { + fun onChecked(newStatus: Boolean) +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt new file mode 100644 index 00000000..a55b007d --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt @@ -0,0 +1,115 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.text.format.DateUtils +import androidx.appcompat.content.res.AppCompatResources +import androidx.core.os.bundleOf +import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import com.google.android.gms.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.microg.gms.gcm.GcmDatabase + +class PushNotificationAllAppsFragment : PreferenceFragmentCompat() { + private lateinit var database: GcmDatabase + private lateinit var registered: PreferenceCategory + private lateinit var unregistered: PreferenceCategory + private lateinit var registeredNone: Preference + private lateinit var unregisteredNone: Preference + private lateinit var progress: Preference + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + database = GcmDatabase(context) + } + + override fun onResume() { + super.onResume() + updateContent() + } + + override fun onPause() { + super.onPause() + database.close() + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_push_notifications_all_apps) + registered = preferenceScreen.findPreference("prefcat_push_apps_registered") ?: registered + unregistered = preferenceScreen.findPreference("prefcat_push_apps_unregistered") ?: unregistered + registeredNone = preferenceScreen.findPreference("pref_push_apps_registered_none") ?: registeredNone + unregisteredNone = preferenceScreen.findPreference("pref_push_apps_unregistered_none") ?: unregisteredNone + progress = preferenceScreen.findPreference("pref_push_apps_all_progress") ?: progress + } + + private fun updateContent() { + lifecycleScope.launchWhenResumed { + val context = requireContext() + val apps = withContext(Dispatchers.IO) { + val res = database.appList.map { app -> + try { + app to context.packageManager.getApplicationInfo(app.packageName, 0) + } catch (ignored: Exception) { + app to null + } + }.map { (app, applicationInfo) -> + val pref = AppIconPreference(context) + pref.title = applicationInfo?.loadLabel(context.packageManager) ?: app.packageName + pref.summary = when { + app.lastMessageTimestamp > 0 -> getString(R.string.gcm_last_message_at, DateUtils.getRelativeTimeSpanString(app.lastMessageTimestamp)) + else -> null + } + pref.icon = applicationInfo?.loadIcon(context.packageManager) + ?: AppCompatResources.getDrawable(context, android.R.mipmap.sym_def_app_icon) + pref.onPreferenceClickListener = Preference.OnPreferenceClickListener { + findNavController().navigate(R.id.openGcmAppDetailsFromAll, bundleOf( + "package" to app.packageName + )) + true + } + pref.key = "pref_push_app_" + app.packageName + pref to (database.getRegistrationsByApp(app.packageName)) + }.sortedBy { + it.first.title.toString().toLowerCase() + }.mapIndexed { idx, pair -> + pair.first.order = idx + pair + } + database.close() + res + } + registered.removeAll() + registered.isVisible = true + unregistered.removeAll() + unregistered.isVisible = true + + var hadRegistered = false + var hadUnregistered = false + + for (pair in apps) { + if (pair.second.isEmpty()) { + unregistered.addPreference(pair.first) + hadUnregistered = true + } else { + registered.addPreference(pair.first) + hadRegistered = true + } + } + + registeredNone.isVisible = !hadRegistered + unregisteredNone.isVisible = !hadUnregistered + if (!hadRegistered) registered.addPreference(registeredNone) + if (!hadUnregistered) unregistered.addPreference(unregisteredNone) + progress.isVisible = false + } + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt new file mode 100644 index 00000000..5699ec07 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.provider.Settings +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.content.res.AppCompatResources +import androidx.fragment.app.Fragment +import androidx.fragment.app.findFragment +import androidx.lifecycle.lifecycleScope +import com.google.android.gms.R +import com.google.android.gms.databinding.PushNotificationAppFragmentBinding + + +class PushNotificationAppFragment : Fragment(R.layout.push_notification_fragment) { + lateinit var binding: PushNotificationAppFragmentBinding + val packageName: String? + get() = arguments?.getString("package") + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = PushNotificationAppFragmentBinding.inflate(inflater, container, false) + binding.callbacks = object : PushNotificationAppFragmentCallbacks { + override fun onAppClicked() { + val intent = Intent() + intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS + val uri: Uri = Uri.fromParts("package", packageName, null) + intent.data = uri + context!!.startActivity(intent) + } + } + childFragmentManager.findFragmentById(R.id.sub_preferences)?.arguments = arguments + return binding.root + } + + override fun onResume() { + super.onResume() + lifecycleScope.launchWhenResumed { + val pm = requireContext().packageManager + val applicationInfo = packageName?.let { pm.getApplicationInfo(it, 0) } + binding.appName = applicationInfo?.loadLabel(pm)?.toString() ?: packageName + binding.appIcon = applicationInfo?.loadIcon(pm) + ?: AppCompatResources.getDrawable(requireContext(), android.R.mipmap.sym_def_app_icon) + } + } +} + +interface PushNotificationAppFragmentCallbacks { + fun onAppClicked() +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt new file mode 100644 index 00000000..b327349e --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt @@ -0,0 +1,134 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.text.format.DateUtils +import androidx.appcompat.app.AlertDialog +import androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.TwoStatePreference +import com.google.android.gms.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.microg.gms.gcm.GcmDatabase +import org.microg.gms.gcm.PushRegisterManager + +class PushNotificationAppPreferencesFragment : PreferenceFragmentCompat() { + private lateinit var wakeForDelivery: TwoStatePreference + private lateinit var allowRegister: TwoStatePreference + private lateinit var status: Preference + private lateinit var unregister: Preference + private lateinit var unregisterCat: PreferenceCategory + + private lateinit var database: GcmDatabase + private val packageName: String? + get() = arguments?.getString("package") + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_push_notifications_app) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + database = GcmDatabase(context) + } + + override fun onBindPreferences() { + wakeForDelivery = preferenceScreen.findPreference("pref_push_app_wake_for_delivery") ?: wakeForDelivery + allowRegister = preferenceScreen.findPreference("pref_push_app_allow_register") ?: allowRegister + unregister = preferenceScreen.findPreference("pref_push_app_unregister") ?: unregister + unregisterCat = preferenceScreen.findPreference("prefcat_push_app_unregister") ?: unregisterCat + status = preferenceScreen.findPreference("pref_push_app_status") ?: status + wakeForDelivery.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> + database.setAppWakeForDelivery(packageName, newValue as Boolean) + database.close() + true + } + allowRegister.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> + val enabled = newValue as? Boolean ?: return@OnPreferenceChangeListener false + if (!enabled) { + val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList() + if (registrations.isNotEmpty()) { + showUnregisterConfirm(R.string.gcm_unregister_after_deny_message) + } + } + database.setAppAllowRegister(packageName, enabled) + database.close() + true + } + unregister.onPreferenceClickListener = Preference.OnPreferenceClickListener { + showUnregisterConfirm(R.string.gcm_unregister_confirm_message) + true + } + } + + + private fun showUnregisterConfirm(unregisterConfirmDesc: Int) { + val pm = requireContext().packageManager + val applicationInfo = packageName?.let { pm.getApplicationInfo(it, 0) } + AlertDialog.Builder(requireContext()) + .setTitle(getString(R.string.gcm_unregister_confirm_title, applicationInfo?.loadLabel(pm) + ?: packageName)) + .setMessage(unregisterConfirmDesc) + .setPositiveButton(android.R.string.yes) { _, _ -> unregister() } + .setNegativeButton(android.R.string.no) { _, _ -> }.show() + } + + private fun unregister() { + lifecycleScope.launchWhenResumed { + withContext(Dispatchers.IO) { + for (registration in database.getRegistrationsByApp(packageName)) { + PushRegisterManager.unregister(context, registration.packageName, registration.signature, null, null) + } + } + updateDetails() + } + } + + override fun onResume() { + super.onResume() + updateDetails() + } + + private fun updateDetails() { + lifecycleScope.launchWhenResumed { + val app = packageName?.let { database.getApp(it) } + wakeForDelivery.isChecked = app?.wakeForDelivery ?: true + allowRegister.isChecked = app?.allowRegister ?: true + val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList() + unregisterCat.isVisible = registrations.isNotEmpty() + + val sb = StringBuilder() + if ((app?.totalMessageCount ?: 0L) == 0L) { + sb.append(getString(R.string.gcm_no_message_yet)) + } else { + sb.append(getString(R.string.gcm_messages_counter, app?.totalMessageCount, app?.totalMessageBytes)) + if (app?.lastMessageTimestamp != 0L) { + sb.append("\n").append(getString(R.string.gcm_last_message_at, DateUtils.getRelativeDateTimeString(context, app?.lastMessageTimestamp ?: 0L, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))) + } + } + for (registration in registrations) { + sb.append("\n") + if (registration.timestamp == 0L) { + sb.append(getString(R.string.gcm_registered)) + } else { + sb.append(getString(R.string.gcm_registered_since, DateUtils.getRelativeDateTimeString(context, registration.timestamp, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))) + } + } + status.summary = sb.toString() + + database.close() + } + } + + override fun onPause() { + super.onPause() + database.close() + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt new file mode 100644 index 00000000..fcdc6965 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package org.microg.gms.ui + +import android.content.Intent +import android.os.Bundle +import android.view.* +import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController +import androidx.preference.* +import com.google.android.gms.R +import com.google.android.gms.databinding.PushNotificationFragmentBinding +import org.microg.gms.checkin.CheckinPrefs +import org.microg.gms.gcm.GcmPrefs +import org.microg.gms.gcm.McsService +import org.microg.gms.gcm.TriggerReceiver + +class PushNotificationFragment : Fragment(R.layout.push_notification_fragment) { + lateinit var binding: PushNotificationFragmentBinding + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = PushNotificationFragmentBinding.inflate(inflater, container, false) + binding.switchBarCallback = object : PreferenceSwitchBarCallback { + override fun onChecked(newStatus: Boolean) { + PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(GcmPrefs.PREF_ENABLE_GCM, newStatus).apply() + if (!newStatus) { + McsService.stop(context) + } else { + requireContext().sendBroadcast(Intent(TriggerReceiver.FORCE_TRY_RECONNECT, null, context, TriggerReceiver::class.java)) + } + binding.gcmEnabled = newStatus + } + } + return binding.root + } + + override fun onResume() { + super.onResume() + lifecycleScope.launchWhenResumed { + binding.gcmEnabled = GcmPrefs.get(context).isEnabled + binding.checkinEnabled = CheckinPrefs.get(context).isEnabled + } + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + setHasOptionsMenu(true) + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return when (item.itemId) { + MENU_ADVANCED -> { + findNavController().navigate(R.id.openGcmAdvancedSettings) + true + } + else -> super.onOptionsItemSelected(item) + } + } + + companion object { + private const val MENU_ADVANCED = Menu.FIRST + } +} + diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt new file mode 100644 index 00000000..f855ea54 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.os.Handler +import android.text.format.DateUtils +import androidx.core.os.bundleOf +import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import com.google.android.gms.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.microg.gms.gcm.GcmDatabase +import org.microg.gms.gcm.GcmPrefs +import org.microg.gms.gcm.McsService + +class PushNotificationPreferencesFragment : PreferenceFragmentCompat() { + private lateinit var pushStatusCategory: PreferenceCategory + private lateinit var pushStatus: Preference + private lateinit var pushApps: PreferenceCategory + private lateinit var pushAppsAll: Preference + private lateinit var pushAppsNone: Preference + private lateinit var database: GcmDatabase + private val handler = Handler() + private val updateRunnable = Runnable { updateStatus() } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + database = GcmDatabase(context) + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_push_notifications) + } + + override fun onBindPreferences() { + pushStatusCategory = preferenceScreen.findPreference("prefcat_push_status") ?: pushStatusCategory + pushStatus = preferenceScreen.findPreference("pref_push_status") ?: pushStatus + pushApps = preferenceScreen.findPreference("prefcat_push_apps") ?: pushApps + pushAppsAll = preferenceScreen.findPreference("pref_push_apps_all") ?: pushAppsAll + pushAppsNone = preferenceScreen.findPreference("pref_push_apps_none") ?: pushAppsNone + pushAppsAll.onPreferenceClickListener = Preference.OnPreferenceClickListener { + findNavController().navigate(R.id.openAllGcmApps) + true + } + } + + override fun onResume() { + super.onResume() + updateStatus() + updateContent() + } + + override fun onPause() { + super.onPause() + database.close() + handler.removeCallbacks(updateRunnable) + } + + private fun updateStatus() { + handler.postDelayed(updateRunnable, UPDATE_INTERVAL) + pushStatusCategory.isVisible = GcmPrefs.get(context).isEnabled + pushStatus.summary = if (McsService.isConnected()) { + "Connected since: " + DateUtils.getRelativeTimeSpanString(McsService.getStartTimestamp(), System.currentTimeMillis(), 0) + } else { + "Disconnected" + } + } + + private fun updateContent() { + lifecycleScope.launchWhenResumed { + val context = requireContext() + val (apps, showAll) = withContext(Dispatchers.IO) { + val apps = database.appList.sortedByDescending { it.lastMessageTimestamp } + val res = apps.map { app -> + try { + app to context.packageManager.getApplicationInfo(app.packageName, 0) + } catch (ignored: Exception) { + null + } + }.filterNotNull().take(3).mapIndexed { idx, (app, applicationInfo) -> + val pref = AppIconPreference(context) + pref.order = idx + pref.title = applicationInfo.loadLabel(context.packageManager) + pref.icon = applicationInfo.loadIcon(context.packageManager) + pref.onPreferenceClickListener = Preference.OnPreferenceClickListener { + findNavController().navigate(R.id.openGcmAppDetails, bundleOf( + "package" to app.packageName + )) + true + } + pref.key = "pref_push_app_" + app.packageName + pref + }.let { it to (it.size < apps.size) } + database.close() + res + } + pushAppsAll.isVisible = showAll + pushApps.removeAll() + for (app in apps) { + pushApps.addPreference(app) + } + if (showAll) { + pushApps.addPreference(pushAppsAll) + } else if (apps.isEmpty()) { + pushApps.addPreference(pushAppsNone) + } + } + } + + companion object { + private const val UPDATE_INTERVAL = 1000L + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetFragment.kt new file mode 100644 index 00000000..b611a1ac --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetFragment.kt @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.view.* +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import com.google.android.gms.R +import com.google.android.gms.databinding.SafetyNetFragmentBinding +import org.microg.gms.checkin.CheckinPrefs +import org.microg.gms.snet.SafetyNetPrefs + +class SafetyNetFragment : Fragment(R.layout.safety_net_fragment) { + + private lateinit var binding: SafetyNetFragmentBinding + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = SafetyNetFragmentBinding.inflate(inflater, container, false) + binding.switchBarCallback = object : PreferenceSwitchBarCallback { + override fun onChecked(newStatus: Boolean) { + SafetyNetPrefs.get(requireContext()).isEnabled = newStatus + binding.safetynetEnabled = newStatus + } + } + return binding.root + } + + override fun onResume() { + super.onResume() + binding.checkinEnabled = CheckinPrefs.get(requireContext()).isEnabled + binding.safetynetEnabled = SafetyNetPrefs.get(requireContext()).isEnabled + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + setHasOptionsMenu(true) + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return when (item.itemId) { + MENU_ADVANCED -> { + findNavController().navigate(R.id.openSafetyNetAdvancedSettings) + true + } + else -> super.onOptionsItemSelected(item) + } + } + + companion object { + private const val MENU_ADVANCED = Menu.FIRST + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetPreferencesFragment.kt new file mode 100644 index 00000000..2a4b4ab2 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetPreferencesFragment.kt @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import androidx.preference.PreferenceFragmentCompat +import com.google.android.gms.R + +class SafetyNetPreferencesFragment : PreferenceFragmentCompat() { + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_safetynet) + } +} diff --git a/play-services-core/src/main/res/drawable-hdpi/ic_map_marker.png b/play-services-core/src/main/res/drawable-hdpi/ic_map_marker.png deleted file mode 100644 index 58c9a14bdce994e234e8ace0096ceef307d308e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1171 zcmV;E1Z?|>P)%*^Z?8ylM-c@V(k>EZh#@@ucxTWPo3cm6kE zN~xzs}FZL{2sujjsjC6Y$~Wc{rwrL{B52+Z@mmoi#=0H&fSy1$npJvWtlUDh@S z1MqA{-xaNO-?@}}t~jo31@=T16Uk22ga+PBwQa#3%jnBI$ql?&Yny|SyqCq7B+0?7 zIkS4R*0ur@k*sgLr>fQJXg^cxIpw&vIT(PSvY1F7isSffKVKZjXGtD%S=$PX4It-uNA43`VGJVgP3nct_H+)_}hAV3&mC zB@vl1h&e{m1ma&JdC3F{uvi3>{36dFEy0XyTD@p0rB(nO9uU`ct@VUykkvaC$#VmO zvaV$X*6Z~?2XK1;T({F&g8^%`S`SFpil!o2YqeSr1_lNIrBdlr05=Qdx|!CnlJ(Zv z;^N{~5Cr!DoGb`zu2!pAZ<^-Xknw&0JjpfJL?qXI-#?!#N8Uk%VfdPeTy>Evm5@9h zMbS5TlH}e(O9!yv2nqle@@@5bOcLBVSGu6BG zdfmDau~RNPnp8@C4dA$C{8g>>>o8pG?j@Jo)Y9wq-h|yFxt_*4fpQIocDsFtv0s)G4XwW7Ju#A_tR?Xb*{qx=P^4w``pOL z$Pd`NkG8S3we@nd*>t{g0SfGKHJi<~biV!97lM$SE(!`Lu73;w=yWqK}HKU3gcrR4Tm>;PQ?`m(yc~s?h&ZZL3G0s!Clk5;SI%|X;1h{7=3 lABN%nhdqv=h8oI^{sctzRI9O@YcT)-002ovPDHLkV1k}U8(jbZ diff --git a/play-services-core/src/main/res/drawable-ldpi/add_account.png b/play-services-core/src/main/res/drawable-ldpi/add_account.png deleted file mode 100644 index c84ada96285da895e3908ea5986386d1c4896e6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|m3OrpLLn;`zo?>Kc2oP|+D1FK5 z_6hYBWdRwSxmr`0nlub*PhBu*vErB0+wZ9{<1y2ZtS51uiiOid7hmj8>s1qevEWkt zZ$Xx6I~tZYel^=9Q7kP61T=Nnm>3Pp~8JkPc8 ziiB@K^p?QlD_p7%%64eJJ5(wyvtD5CzjKEhf7LMlsW=}Wy}N49uBge;Sx0y8ZoT5! zW2MdcaIx^>T{Rav0)5Rq{JPdBm{#rDdWJpc&X+22=}D7=KC?%=PmSZ)d+Oq~C3B-R uR=?GhFk0*k}3<^7zS)sXUP@^ z!Nx+cR*w{>GgTV@V6+g#NI(v|1CyHsj@x?{nSf|+XLdFcgnY1Y%=_Lqznj~eodwSI zpNU+Wgb?Au!NDvu&jPpxU__U`1NcNlP2cyMLWs`42BIj6?h?^`X1-i#B>KV352Tcj z0r05<2_eExr}LDEZkPE6%=|nI!#lRCWd$UJxS*8U05Dkw<~O|#f?!Gr(KQ)sHfc(! z)e0~GFsU=DuTT_4Hvqh|g)dMaz=V|YL)8^pG5C4_-s`Jpm}|u}Ss{=RA_Op9VA=FM zZ(K?_A*Gz~JZ~JpW`TcNXSx9?rRo5N2b6b$Aec##WcPR=Ns`?l2xb864CoownQlPL zJTj<8MCnO?Wg$d|h*FnKBM=c?DhU4OQY*?d0s&A3!B<>rMVUsRTCMh_U=@~6xIz`GE46QffVp#S-(X__i#UaLyO%xh_y zDwEIZftly|BLI69c=mLLQC2`%mbHl}bEP4oEX%U?sR04N;o;#bfR+PKOZQsI8mQ4| z>@o9VSsG?uY&06yKX<7^SDL0T05nUqGGWkAsUS)fg%Rj z@jF0~f25Q!d|V-(d4-QK6cNZU;vI(xL0EvoxFj8EDi8)%U+#m}J#Ik~L=rVDbQiG7N4pSzj0&|!mB$W^7fJSq@ akpTe1pLQv<$B6d;0000VfEVKfi2`aQGVwtoiC{EQB=QW&3Lzzt{WD02 znHa$CPN!|M36dIp;LR+NM1nQJC}`S7QSnb~NHIc5Km(|yu&|cSJw9}{T?k5d?!7aG z?C*8weCNAg@4d5gXA3lF(4aws2Dd8|M^ndfn#$$!(?s+vGd~945daSXNCuab0h|Re zNJKv|^B2ivvfpu>(K|YzEnBuMF->y=fL8(BTW9%S0QUL5zo(<4<2cR1o)cF%05H$@{gUH2 z&8h^I1r*$^7RQmw4J;14C_%{*vu%5k5aL^?zmbUyw6wIWXXdvN{?7P!rBZpYSS2$isFpN(CEDX_OPT=v&uw#_kq)pRY9eXlC6F4P(knOHpmz9u zQw+eDtd9aIkFo)sueU%5F+XgxkhOJttVK4Ux^KNiv?7&C&8W97l}gPZq7_kitVQ-V z|67Q%*|TQNT32sTP%}Fsj}u4*L`0#EH;HJ6ZQD~`F1BsYC!!rudQ=jS5F+d$`CK7H zPdc4maH|W`>GT32L=S+u5qkt6`79=cIBFQi6##dKC|_t8#?f3Zr}JU;iV)(c%owH5 zaI)F#M*v=yl+khA0Ra15*L_7sK>9q0i1stHY(OnUG%*k&HD_-`v|m<3`p9*3bo2m# zt4cgpP1=6!LeaU;yUudAzTSXM{XYoB-HjYFR&We4rKT<&{jUJ_p( zHG?8LRwxu6SD~fs#i0d&@nx;yz!-o$G%d*Y_crDUo0*ENJbLY-qlxpfQ zn#p8(iD+3gv5dpaeeLb-mTFz4OKd{aFx~(lw5KwO2zn|<=@P5b+uM7_vaI_7Jf$_3 zNp`!g`<@PAEi(uJDwWDM0B5vCGRc{smlm`IR4f)ph-kAe{VGJXxmYZYXw%m{fNVDV zF@P5}$scfC_a&YFwauU^zVB}eexj=sX1?tE{wCf2wQSP0^!N9VSeA7ez)F?6M3nJ7 zFU+gx`ugZ@Q0lBIHy4CT%e^r93Z-Y;JWS~ z0M<(mi~+0Isb-SYU9N7%2GB!4r1uzhzbRejWl*j|> z?CiWMgjfyWQXOTNgb=GcJ3AwPdlGp-0N{DvaUz=PM$1IB&hxzEad?e%52~fNw|Bs@ zteF6Abu7{m^}bU}EHkLesZ*zH07w4kk|V)2u@P%PrBcaHBob=?oV>}$CliUp8kOhE zVVD;GfMVPBqe6(UF!=+ii-uu5lh5aWj@w(TGpI@s#9EC1;L-=Mb~=PJ?Z{@c8?)K$ l#<+bnXwaZRg9dj7{{m4zB!0b=EolG%002ovPDHLkV1it<)_DK` diff --git a/play-services-core/src/main/res/drawable-xxhdpi/add_account.png b/play-services-core/src/main/res/drawable-xxhdpi/add_account.png deleted file mode 100644 index 53264c28081b15179fa6a094fa09ff5819d6e0fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 428 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 diff --git a/play-services-core/src/main/res/drawable/dots_horizontal.xml b/play-services-core/src/main/res/drawable/dots_horizontal.xml index 5c71aeb7..4110aed7 100644 --- a/play-services-core/src/main/res/drawable/dots_horizontal.xml +++ b/play-services-core/src/main/res/drawable/dots_horizontal.xml @@ -1,13 +1,14 @@ + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorControlNormal" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + diff --git a/play-services-core/src/main/res/drawable-anydpi-v21/add_account.xml b/play-services-core/src/main/res/drawable/ic_add_account.xml similarity index 92% rename from play-services-core/src/main/res/drawable-anydpi-v21/add_account.xml rename to play-services-core/src/main/res/drawable/ic_add_account.xml index aa8b898a..1ff91a0e 100644 --- a/play-services-core/src/main/res/drawable-anydpi-v21/add_account.xml +++ b/play-services-core/src/main/res/drawable/ic_add_account.xml @@ -2,6 +2,7 @@ @@ -10,4 +11,4 @@ - \ No newline at end of file + diff --git a/play-services-core/src/main/res/drawable/certificate.xml b/play-services-core/src/main/res/drawable/ic_certificate.xml similarity index 71% rename from play-services-core/src/main/res/drawable/certificate.xml rename to play-services-core/src/main/res/drawable/ic_certificate.xml index 6091e969..780e4db4 100644 --- a/play-services-core/src/main/res/drawable/certificate.xml +++ b/play-services-core/src/main/res/drawable/ic_certificate.xml @@ -1,13 +1,14 @@ + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorAccent" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + diff --git a/play-services-core/src/main/res/drawable/gcm_bell.xml b/play-services-core/src/main/res/drawable/ic_cloud_bell.xml similarity index 79% rename from play-services-core/src/main/res/drawable/gcm_bell.xml rename to play-services-core/src/main/res/drawable/ic_cloud_bell.xml index 89a1cae4..0f41c719 100644 --- a/play-services-core/src/main/res/drawable/gcm_bell.xml +++ b/play-services-core/src/main/res/drawable/ic_cloud_bell.xml @@ -1,11 +1,12 @@ + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorAccent" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + android:pathData="M 12 4 C 9.11 4 6.5996094 5.6392969 5.3496094 8.0292969 C 2.3396094 8.3592969 0 10.9 0 14 A 6 6 0 0 0 6 20 L 19 20 A 5 5 0 0 0 24 15 C 24 12.36 21.949609 10.219297 19.349609 10.029297 C 18.669609 6.5892969 15.64 4 12 4 z M 12 7.5 A 0.5 0.5 0 0 1 12.5 8 L 12.5 8.5390625 C 13.92 8.7790625 15 10.015 15 11.5 L 15 14.5 L 16.5 16 L 7.5 16 L 9 14.5 L 9 11.5 C 9 10.015 10.08 8.7790625 11.5 8.5390625 L 11.5 8 A 0.5 0.5 0 0 1 12 7.5 z M 11 16.5 L 13 16.5 A 1 1 0 0 1 12 17.5 A 1 1 0 0 1 11 16.5 z" /> + diff --git a/play-services-core/src/main/res/drawable/device_login.xml b/play-services-core/src/main/res/drawable/ic_device_login.xml similarity index 58% rename from play-services-core/src/main/res/drawable/device_login.xml rename to play-services-core/src/main/res/drawable/ic_device_login.xml index f1a4e1e4..c0bce50c 100644 --- a/play-services-core/src/main/res/drawable/device_login.xml +++ b/play-services-core/src/main/res/drawable/ic_device_login.xml @@ -1,11 +1,12 @@ + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorAccent" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + android:pathData="M10,17.25V14H3V10H10V6.75L15.25,12L10,17.25M8,2H17A2,2 0 0,1 19,4V20A2,2 0 0,1 17,22H8A2,2 0 0,1 6,20V16H8V20H17V4H8V8H6V4A2,2 0 0,1 8,2Z" /> + diff --git a/play-services-core/src/main/res/drawable/ic_expand_apps.xml b/play-services-core/src/main/res/drawable/ic_expand_apps.xml new file mode 100644 index 00000000..20634f05 --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_expand_apps.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/play-services-core/src/main/res/drawable/ic_info_outline.xml b/play-services-core/src/main/res/drawable/ic_info_outline.xml new file mode 100644 index 00000000..8e049cce --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_info_outline.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/play-services-core/src/main/res/drawable/ic_map_marker.xml b/play-services-core/src/main/res/drawable/ic_map_marker.xml new file mode 100644 index 00000000..b97f8b8d --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_map_marker.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/play-services-core/src/main/res/layout/ask_gcm.xml b/play-services-core/src/main/res/layout/ask_gcm.xml index 9d3e8be8..a5c20212 100644 --- a/play-services-core/src/main/res/layout/ask_gcm.xml +++ b/play-services-core/src/main/res/layout/ask_gcm.xml @@ -48,7 +48,7 @@ android:layout_width="36dip" android:layout_height="36dip" android:scaleType="fitCenter" - android:src="@drawable/gcm_bell" + android:src="@drawable/ic_cloud_bell" android:tint="?attr/colorAccent"> diff --git a/play-services-core/src/main/res/layout/device_registration_fragment.xml b/play-services-core/src/main/res/layout/device_registration_fragment.xml new file mode 100644 index 00000000..0f0648dc --- /dev/null +++ b/play-services-core/src/main/res/layout/device_registration_fragment.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/preference_category_no_label.xml b/play-services-core/src/main/res/layout/preference_category_no_label.xml new file mode 100644 index 00000000..31b8b654 --- /dev/null +++ b/play-services-core/src/main/res/layout/preference_category_no_label.xml @@ -0,0 +1,9 @@ + + + + diff --git a/play-services-core/src/main/res/layout/preference_progress_bar.xml b/play-services-core/src/main/res/layout/preference_progress_bar.xml new file mode 100644 index 00000000..bd0eb7e0 --- /dev/null +++ b/play-services-core/src/main/res/layout/preference_progress_bar.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/play-services-core/src/main/res/layout/preference_switch_bar.xml b/play-services-core/src/main/res/layout/preference_switch_bar.xml new file mode 100644 index 00000000..08ad6530 --- /dev/null +++ b/play-services-core/src/main/res/layout/preference_switch_bar.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/push_notification_app_fragment.xml b/play-services-core/src/main/res/layout/push_notification_app_fragment.xml new file mode 100644 index 00000000..4f63f961 --- /dev/null +++ b/play-services-core/src/main/res/layout/push_notification_app_fragment.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/push_notification_fragment.xml b/play-services-core/src/main/res/layout/push_notification_fragment.xml new file mode 100644 index 00000000..e9611b83 --- /dev/null +++ b/play-services-core/src/main/res/layout/push_notification_fragment.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/safety_net_fragment.xml b/play-services-core/src/main/res/layout/safety_net_fragment.xml new file mode 100644 index 00000000..e97378ae --- /dev/null +++ b/play-services-core/src/main/res/layout/safety_net_fragment.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/settings_root_activity.xml b/play-services-core/src/main/res/layout/settings_root_activity.xml new file mode 100644 index 00000000..a592e38d --- /dev/null +++ b/play-services-core/src/main/res/layout/settings_root_activity.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/play-services-core/src/main/res/navigation/nav_settings.xml b/play-services-core/src/main/res/navigation/nav_settings.xml new file mode 100644 index 00000000..4a7a5246 --- /dev/null +++ b/play-services-core/src/main/res/navigation/nav_settings.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/values/strings.xml b/play-services-core/src/main/res/values/strings.xml index 66b626ce..cfc7fd85 100644 --- a/play-services-core/src/main/res/values/strings.xml +++ b/play-services-core/src/main/res/values/strings.xml @@ -61,6 +61,8 @@ This can take a couple of minutes." Enabled Automatic Manual + On + Off Advanced None diff --git a/play-services-core/src/main/res/xml/preferences_checkin.xml b/play-services-core/src/main/res/xml/preferences_checkin.xml deleted file mode 100644 index 45c982a7..00000000 --- a/play-services-core/src/main/res/xml/preferences_checkin.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/xml/preferences_device_registration.xml b/play-services-core/src/main/res/xml/preferences_device_registration.xml new file mode 100644 index 00000000..886ec0b7 --- /dev/null +++ b/play-services-core/src/main/res/xml/preferences_device_registration.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/play-services-core/src/main/res/xml/preferences_gcm_app_detail.xml b/play-services-core/src/main/res/xml/preferences_gcm_app_detail.xml deleted file mode 100644 index 3dc8186a..00000000 --- a/play-services-core/src/main/res/xml/preferences_gcm_app_detail.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications.xml b/play-services-core/src/main/res/xml/preferences_push_notifications.xml new file mode 100644 index 00000000..06c8fb8a --- /dev/null +++ b/play-services-core/src/main/res/xml/preferences_push_notifications.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications_all_apps.xml b/play-services-core/src/main/res/xml/preferences_push_notifications_all_apps.xml new file mode 100644 index 00000000..6c0f2d36 --- /dev/null +++ b/play-services-core/src/main/res/xml/preferences_push_notifications_all_apps.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml b/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml new file mode 100644 index 00000000..fad13b22 --- /dev/null +++ b/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/xml/preferences_snet.xml b/play-services-core/src/main/res/xml/preferences_safetynet.xml similarity index 70% rename from play-services-core/src/main/res/xml/preferences_snet.xml rename to play-services-core/src/main/res/xml/preferences_safetynet.xml index 8a60cf3e..e0a2ed84 100644 --- a/play-services-core/src/main/res/xml/preferences_snet.xml +++ b/play-services-core/src/main/res/xml/preferences_safetynet.xml @@ -16,16 +16,20 @@ --> + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> - + android:selectable="false" + android:summary="@string/snet_intro" /> + + android:title="@string/pref_snet_testdrive_title" /> - \ No newline at end of file + diff --git a/play-services-core/src/main/res/xml/preferences_start.xml b/play-services-core/src/main/res/xml/preferences_start.xml index c51f7dc5..b48d5b7a 100644 --- a/play-services-core/src/main/res/xml/preferences_start.xml +++ b/play-services-core/src/main/res/xml/preferences_start.xml @@ -14,75 +14,59 @@ ~ limitations under the License. --> - - - + + - + android:targetPackage="com.google.android.gms" /> + - - - + + - - - + - - - + - - - + + android:title="@string/pref_more_settings" + app:isPreferenceVisible="false"> - + android:targetPackage="com.google.android.gms" /> + - - + - - + android:title="@string/nlp_backends_title" /> - - + - - + android:title="@string/pref_about_title" /> From cda60817f2f13d7176987c5c74c1fa3cbdbd6b05 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 26 Jul 2020 12:01:03 +0200 Subject: [PATCH 03/51] Major update to lib implementations --- LICENSES/Apache-2.0.txt | 208 +++++++++++ LICENSES/CC-BY-4.0.txt | 324 ++++++++++++++++++ build.gradle | 6 +- .../common/internal/ISignInButtonCreator.aidl | 0 .../common/server/FavaDiagnosticsEntity.aidl | 0 .../common/server/FavaDiagnosticsEntity.java | 0 play-services-base-api/build.gradle | 40 +++ .../src/main/AndroidManifest.xml | 6 + .../common/api/internal/IStatusCallback.aidl | 7 + .../android/gms/common/data/DataHolder.aidl | 0 .../android/gms/common/images/WebImage.aidl | 0 .../auth/api/signin/GoogleSignInAccount.java | 12 + .../android/gms/common/data/DataHolder.java | 0 .../android/gms/common/data/Freezable.java | 0 .../android/gms/common/images/WebImage.java | 0 play-services-base/build.gradle | 1 + .../android/gms/common/api/AccountInfo.java | 1 + .../google/android/gms/common/api/Api.java | 29 +- .../android/gms/common/api/GoogleApi.java | 48 +++ .../gms/common/api/GoogleApiClient.java | 57 +-- .../android/gms/common/api/HasApiKey.java | 12 + .../gms/common/api/internal/ApiKey.java | 12 + ...ApiConnection.java => DummyApiClient.java} | 4 +- .../java/org/microg/gms/common/GmsClient.java | 20 +- .../org/microg/gms/common/GmsConnector.java | 6 +- .../{ApiConnection.java => ApiClient.java} | 2 +- ...{ApiBuilder.java => ApiClientBuilder.java} | 8 +- .../gms/common/api/ApiClientSettings.java | 9 + .../gms/common/api/ConnectionCallbacks.java | 41 +++ .../gms/common/api/GoogleApiClientImpl.java | 46 +-- .../gms/common/api/GoogleApiManager.java | 180 ++++++++++ .../gms/common/api/InstantGoogleApiCall.java | 21 ++ .../api/OnConnectionFailedListener.java | 25 ++ .../gms/common/api/PendingGoogleApiCall.java | 12 + play-services-basement/build.gradle | 2 - .../java/org/microg/gms/common/Constants.java | 2 +- .../org/microg/gms/common/GmsService.java | 1 + play-services-cast-api/build.gradle | 2 + play-services-cast-framework-api/build.gradle | 2 + .../com/google/android/gms/cast/Cast.java | 4 +- .../android/gms/cast/CastRemoteDisplay.java | 4 +- ...Builder.java => CastApiClientBuilder.java} | 13 +- .../org/microg/gms/cast/CastClientImpl.java | 9 +- ...=> CastRemoteDisplayApiClientBuilder.java} | 17 +- play-services-gcm/build.gradle | 5 +- .../google/android/gms/gcm/GcmReceiver.java | 4 +- play-services-iid/build.gradle | 2 + .../gms/iid/InstanceIDListenerService.java | 4 +- play-services-location-api/build.gradle | 2 + play-services-location/build.gradle | 4 +- .../gms/location/ActivityRecognition.java | 4 +- .../location/FusedLocationProviderApi.java | 1 + .../location/FusedLocationProviderClient.java | 42 +++ .../android/gms/location/GeofencingApi.java | 1 + .../gms/location/LocationServices.java | 13 +- .../android/gms/location/SettingsApi.java | 1 + ... ActivityRecognitionApiClientBuilder.java} | 15 +- .../ActivityRecognitionClientImpl.java | 5 +- .../FusedLocationProviderApiImpl.java | 3 +- .../gms/location/GeofencingApiImpl.java | 4 +- .../location/GoogleLocationManagerClient.java | 7 +- .../gms/location/LocationClientImpl.java | 6 +- ... => LocationServicesApiClientBuilder.java} | 18 +- play-services-wearable-api/build.gradle | 2 + .../google/android/gms/wearable/Wearable.java | 4 +- ...der.java => WearableApiClientBuilder.java} | 15 +- .../gms/wearable/WearableClientImpl.java | 4 +- settings.gradle | 21 +- 68 files changed, 1187 insertions(+), 193 deletions(-) create mode 100644 LICENSES/Apache-2.0.txt create mode 100644 LICENSES/CC-BY-4.0.txt rename {play-services-basement => play-services-api}/src/main/aidl/com/google/android/gms/common/internal/ISignInButtonCreator.aidl (100%) rename {play-services-basement => play-services-api}/src/main/aidl/com/google/android/gms/common/server/FavaDiagnosticsEntity.aidl (100%) rename {play-services-basement => play-services-api}/src/main/java/com/google/android/gms/common/server/FavaDiagnosticsEntity.java (100%) create mode 100644 play-services-base-api/build.gradle create mode 100644 play-services-base-api/src/main/AndroidManifest.xml create mode 100644 play-services-base-api/src/main/aidl/com/google/android/gms/common/api/internal/IStatusCallback.aidl rename {play-services-basement => play-services-base-api}/src/main/aidl/com/google/android/gms/common/data/DataHolder.aidl (100%) rename {play-services-basement => play-services-base-api}/src/main/aidl/com/google/android/gms/common/images/WebImage.aidl (100%) create mode 100644 play-services-base-api/src/main/java/com/google/android/gms/auth/api/signin/GoogleSignInAccount.java rename {play-services-basement => play-services-base-api}/src/main/java/com/google/android/gms/common/data/DataHolder.java (100%) rename {play-services-basement => play-services-base-api}/src/main/java/com/google/android/gms/common/data/Freezable.java (100%) rename {play-services-basement => play-services-base-api}/src/main/java/com/google/android/gms/common/images/WebImage.java (100%) create mode 100644 play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApi.java create mode 100644 play-services-base/src/main/java/com/google/android/gms/common/api/HasApiKey.java create mode 100644 play-services-base/src/main/java/com/google/android/gms/common/api/internal/ApiKey.java rename play-services-base/src/main/java/org/microg/gms/common/{DummyApiConnection.java => DummyApiClient.java} (90%) rename play-services-base/src/main/java/org/microg/gms/common/api/{ApiConnection.java => ApiClient.java} (95%) rename play-services-base/src/main/java/org/microg/gms/common/api/{ApiBuilder.java => ApiClientBuilder.java} (64%) create mode 100644 play-services-base/src/main/java/org/microg/gms/common/api/ApiClientSettings.java create mode 100644 play-services-base/src/main/java/org/microg/gms/common/api/ConnectionCallbacks.java create mode 100644 play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiManager.java create mode 100644 play-services-base/src/main/java/org/microg/gms/common/api/InstantGoogleApiCall.java create mode 100644 play-services-base/src/main/java/org/microg/gms/common/api/OnConnectionFailedListener.java create mode 100644 play-services-base/src/main/java/org/microg/gms/common/api/PendingGoogleApiCall.java rename play-services-cast/src/main/java/org/microg/gms/cast/{CastApiBuilder.java => CastApiClientBuilder.java} (60%) rename play-services-cast/src/main/java/org/microg/gms/cast/{CastRemoteDisplayApiBuilder.java => CastRemoteDisplayApiClientBuilder.java} (52%) create mode 100644 play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderClient.java rename play-services-location/src/main/java/org/microg/gms/location/{ActivityRecognitionApiBuilder.java => ActivityRecognitionApiClientBuilder.java} (57%) rename play-services-location/src/main/java/org/microg/gms/location/{LocationServicesApiBuilder.java => LocationServicesApiClientBuilder.java} (56%) rename play-services-wearable/src/main/java/org/microg/gms/wearable/{WearableApiBuilder.java => WearableApiClientBuilder.java} (62%) diff --git a/LICENSES/Apache-2.0.txt b/LICENSES/Apache-2.0.txt new file mode 100644 index 00000000..4ed90b95 --- /dev/null +++ b/LICENSES/Apache-2.0.txt @@ -0,0 +1,208 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, +AND DISTRIBUTION + + 1. Definitions. + + + +"License" shall mean the terms and conditions for use, reproduction, and distribution +as defined by Sections 1 through 9 of this document. + + + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + + + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct +or indirect, to cause the direction or management of such entity, whether +by contract or otherwise, or (ii) ownership of fifty percent (50%) or more +of the outstanding shares, or (iii) beneficial ownership of such entity. + + + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions +granted by this License. + + + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + + + +"Object" form shall mean any form resulting from mechanical transformation +or translation of a Source form, including but not limited to compiled object +code, generated documentation, and conversions to other media types. + + + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice that +is included in or attached to the work (an example is provided in the Appendix +below). + + + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative +Works shall not include works that remain separable from, or merely link (or +bind by name) to the interfaces of, the Work and Derivative Works thereof. + + + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative +Works thereof, that is intentionally submitted to Licensor for inclusion in +the Work by the copyright owner or by an individual or Legal Entity authorized +to submit on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication +sent to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor +for the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + + + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently incorporated +within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this +License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable copyright license to reproduce, prepare +Derivative Works of, publicly display, publicly perform, sublicense, and distribute +the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, +each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) patent +license to make, have made, use, offer to sell, sell, import, and otherwise +transfer the Work, where such license applies only to those patent claims +licensable by such Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work to which such +Contribution(s) was submitted. If You institute patent litigation against +any entity (including a cross-claim or counterclaim in a lawsuit) alleging +that the Work or a Contribution incorporated within the Work constitutes direct +or contributory patent infringement, then any patent licenses granted to You +under this License for that Work shall terminate as of the date such litigation +is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or +Derivative Works thereof in any medium, with or without modifications, and +in Source or Object form, provided that You meet the following conditions: + +(a) You must give any other recipients of the Work or Derivative Works a copy +of this License; and + +(b) You must cause any modified files to carry prominent notices stating that +You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source +form of the Work, excluding those notices that do not pertain to any part +of the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its distribution, +then any Derivative Works that You distribute must include a readable copy +of the attribution notices contained within such NOTICE file, excluding those +notices that do not pertain to any part of the Derivative Works, in at least +one of the following places: within a NOTICE text file distributed as part +of the Derivative Works; within the Source form or documentation, if provided +along with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents +of the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works +that You distribute, alongside or as an addendum to the NOTICE text from the +Work, provided that such additional attribution notices cannot be construed +as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, +or distribution of Your modifications, or for any such Derivative Works as +a whole, provided Your use, reproduction, and distribution of the Work otherwise +complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any +Contribution intentionally submitted for inclusion in the Work by You to the +Licensor shall be under the terms and conditions of this License, without +any additional terms or conditions. Notwithstanding the above, nothing herein +shall supersede or modify the terms of any separate license agreement you +may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, +trademarks, service marks, or product names of the Licensor, except as required +for reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to +in writing, Licensor provides the Work (and each Contributor provides its +Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied, including, without limitation, any warranties +or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR +A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness +of using or redistributing the Work and assume any risks associated with Your +exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether +in tort (including negligence), contract, or otherwise, unless required by +applicable law (such as deliberate and grossly negligent acts) or agreed to +in writing, shall any Contributor be liable to You for damages, including +any direct, indirect, special, incidental, or consequential damages of any +character arising as a result of this License or out of the use or inability +to use the Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all other commercial +damages or losses), even if such Contributor has been advised of the possibility +of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work +or Derivative Works thereof, You may choose to offer, and charge a fee for, +acceptance of support, warranty, indemnity, or other liability obligations +and/or rights consistent with this License. However, in accepting such obligations, +You may act only on Your own behalf and on Your sole responsibility, not on +behalf of any other Contributor, and only if You agree to indemnify, defend, +and hold each Contributor harmless for any liability incurred by, or claims +asserted against, such Contributor by reason of your accepting any such warranty +or additional liability. END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own identifying +information. (Don't include the brackets!) The text should be enclosed in +the appropriate comment syntax for the file format. We also recommend that +a file or class name and description of purpose be included on the same "printed +page" as the copyright notice for easier identification within third-party +archives. + +Copyright [yyyy] [name of copyright owner] + +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 + +http://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. diff --git a/LICENSES/CC-BY-4.0.txt b/LICENSES/CC-BY-4.0.txt new file mode 100644 index 00000000..3f92dfc5 --- /dev/null +++ b/LICENSES/CC-BY-4.0.txt @@ -0,0 +1,324 @@ +Creative Commons Attribution 4.0 International Creative Commons Corporation +("Creative Commons") is not a law firm and does not provide legal services +or legal advice. Distribution of Creative Commons public licenses does not +create a lawyer-client or other relationship. Creative Commons makes its licenses +and related information available on an "as-is" basis. Creative Commons gives +no warranties regarding its licenses, any material licensed under their terms +and conditions, or any related information. Creative Commons disclaims all +liability for damages resulting from their use to the fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and conditions +that creators and other rights holders may use to share original works of +authorship and other material subject to copyright and certain other rights +specified in the public license below. The following considerations are for +informational purposes only, are not exhaustive, and do not form part of our +licenses. + +Considerations for licensors: Our public licenses are intended for use by +those authorized to give the public permission to use material in ways otherwise +restricted by copyright and certain other rights. Our licenses are irrevocable. +Licensors should read and understand the terms and conditions of the license +they choose before applying it. Licensors should also secure all rights necessary +before applying our licenses so that the public can reuse the material as +expected. Licensors should clearly mark any material not subject to the license. +This includes other CC-licensed material, or material used under an exception +or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors + +Considerations for the public: By using one of our public licenses, a licensor +grants the public permission to use the licensed material under specified +terms and conditions. If the licensor's permission is not necessary for any +reason–for example, because of any applicable exception or limitation to copyright–then +that use is not regulated by the license. Our licenses grant only permissions +under copyright and certain other rights that a licensor has authority to +grant. Use of the licensed material may still be restricted for other reasons, +including because others have copyright or other rights in the material. A +licensor may make special requests, such as asking that all changes be marked +or described. Although not required by our licenses, you are encouraged to +respect those requests where reasonable. More considerations for the public +: wiki.creativecommons.org/Considerations_for_licensees Creative Commons Attribution +4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree to +be bound by the terms and conditions of this Creative Commons Attribution +4.0 International Public License ("Public License"). To the extent this Public +License may be interpreted as a contract, You are granted the Licensed Rights +in consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the Licensor +receives from making the Licensed Material available under these terms and +conditions. + +Section 1 – Definitions. + +a. Adapted Material means material subject to Copyright and Similar Rights +that is derived from or based upon the Licensed Material and in which the +Licensed Material is translated, altered, arranged, transformed, or otherwise +modified in a manner requiring permission under the Copyright and Similar +Rights held by the Licensor. For purposes of this Public License, where the +Licensed Material is a musical work, performance, or sound recording, Adapted +Material is always produced where the Licensed Material is synched in timed +relation with a moving image. + +b. Adapter's License means the license You apply to Your Copyright and Similar +Rights in Your contributions to Adapted Material in accordance with the terms +and conditions of this Public License. + +c. Copyright and Similar Rights means copyright and/or similar rights closely +related to copyright including, without limitation, performance, broadcast, +sound recording, and Sui Generis Database Rights, without regard to how the +rights are labeled or categorized. For purposes of this Public License, the +rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. + +d. Effective Technological Measures means those measures that, in the absence +of proper authority, may not be circumvented under laws fulfilling obligations +under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, +and/or similar international agreements. + +e. Exceptions and Limitations means fair use, fair dealing, and/or any other +exception or limitation to Copyright and Similar Rights that applies to Your +use of the Licensed Material. + +f. Licensed Material means the artistic or literary work, database, or other +material to which the Licensor applied this Public License. + +g. Licensed Rights means the rights granted to You subject to the terms and +conditions of this Public License, which are limited to all Copyright and +Similar Rights that apply to Your use of the Licensed Material and that the +Licensor has authority to license. + +h. Licensor means the individual(s) or entity(ies) granting rights under this +Public License. + +i. Share means to provide material to the public by any means or process that +requires permission under the Licensed Rights, such as reproduction, public +display, public performance, distribution, dissemination, communication, or +importation, and to make material available to the public including in ways +that members of the public may access the material from a place and at a time +individually chosen by them. + +j. Sui Generis Database Rights means rights other than copyright resulting +from Directive 96/9/EC of the European Parliament and of the Council of 11 +March 1996 on the legal protection of databases, as amended and/or succeeded, +as well as other essentially equivalent rights anywhere in the world. + +k. You means the individual or entity exercising the Licensed Rights under +this Public License. Your has a corresponding meaning. + +Section 2 – Scope. + + a. License grant. + +1. Subject to the terms and conditions of this Public License, the Licensor +hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, +irrevocable license to exercise the Licensed Rights in the Licensed Material +to: + + A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + +2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions +and Limitations apply to Your use, this Public License does not apply, and +You do not need to comply with its terms and conditions. + + 3. Term. The term of this Public License is specified in Section 6(a). + +4. Media and formats; technical modifications allowed. The Licensor authorizes +You to exercise the Licensed Rights in all media and formats whether now known +or hereafter created, and to make technical modifications necessary to do +so. The Licensor waives and/or agrees not to assert any right or authority +to forbid You from making technical modifications necessary to exercise the +Licensed Rights, including technical modifications necessary to circumvent +Effective Technological Measures. For purposes of this Public License, simply +making modifications authorized by this Section 2(a)(4) never produces Adapted +Material. + + 5. Downstream recipients. + +A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed +Material automatically receives an offer from the Licensor to exercise the +Licensed Rights under the terms and conditions of this Public License. + +B. No downstream restrictions. You may not offer or impose any additional +or different terms or conditions on, or apply any Effective Technological +Measures to, the Licensed Material if doing so restricts exercise of the Licensed +Rights by any recipient of the Licensed Material. + +6. No endorsement. Nothing in this Public License constitutes or may be construed +as permission to assert or imply that You are, or that Your use of the Licensed +Material is, connected with, or sponsored, endorsed, or granted official status +by, the Licensor or others designated to receive attribution as provided in +Section 3(a)(1)(A)(i). + + b. Other rights. + +1. Moral rights, such as the right of integrity, are not licensed under this +Public License, nor are publicity, privacy, and/or other similar personality +rights; however, to the extent possible, the Licensor waives and/or agrees +not to assert any such rights held by the Licensor to the limited extent necessary +to allow You to exercise the Licensed Rights, but not otherwise. + +2. Patent and trademark rights are not licensed under this Public License. + +3. To the extent possible, the Licensor waives any right to collect royalties +from You for the exercise of the Licensed Rights, whether directly or through +a collecting society under any voluntary or waivable statutory or compulsory +licensing scheme. In all other cases the Licensor expressly reserves any right +to collect such royalties. + +Section 3 – License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the following +conditions. + + a. Attribution. + +1. If You Share the Licensed Material (including in modified form), You must: + +A. retain the following if it is supplied by the Licensor with the Licensed +Material: + +i. identification of the creator(s) of the Licensed Material and any others +designated to receive attribution, in any reasonable manner requested by the +Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + +v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; + +B. indicate if You modified the Licensed Material and retain an indication +of any previous modifications; and + +C. indicate the Licensed Material is licensed under this Public License, and +include the text of, or the URI or hyperlink to, this Public License. + +2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner +based on the medium, means, and context in which You Share the Licensed Material. +For example, it may be reasonable to satisfy the conditions by providing a +URI or hyperlink to a resource that includes the required information. + +3. If requested by the Licensor, You must remove any of the information required +by Section 3(a)(1)(A) to the extent reasonably practicable. + +4. If You Share Adapted Material You produce, the Adapter's License You apply +must not prevent recipients of the Adapted Material from complying with this +Public License. + +Section 4 – Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that apply to +Your use of the Licensed Material: + +a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, +reuse, reproduce, and Share all or a substantial portion of the contents of +the database; + +b. if You include all or a substantial portion of the database contents in +a database in which You have Sui Generis Database Rights, then the database +in which You have Sui Generis Database Rights (but not its individual contents) +is Adapted Material; and + +c. You must comply with the conditions in Section 3(a) if You Share all or +a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not replace +Your obligations under this Public License where the Licensed Rights include +other Copyright and Similar Rights. + +Section 5 – Disclaimer of Warranties and Limitation of Liability. + +a. Unless otherwise separately undertaken by the Licensor, to the extent possible, +the Licensor offers the Licensed Material as-is and as-available, and makes +no representations or warranties of any kind concerning the Licensed Material, +whether express, implied, statutory, or other. This includes, without limitation, +warranties of title, merchantability, fitness for a particular purpose, non-infringement, +absence of latent or other defects, accuracy, or the presence or absence of +errors, whether or not known or discoverable. Where disclaimers of warranties +are not allowed in full or in part, this disclaimer may not apply to You. + +b. To the extent possible, in no event will the Licensor be liable to You +on any legal theory (including, without limitation, negligence) or otherwise +for any direct, special, indirect, incidental, consequential, punitive, exemplary, +or other losses, costs, expenses, or damages arising out of this Public License +or use of the Licensed Material, even if the Licensor has been advised of +the possibility of such losses, costs, expenses, or damages. Where a limitation +of liability is not allowed in full or in part, this limitation may not apply +to You. + +c. The disclaimer of warranties and limitation of liability provided above +shall be interpreted in a manner that, to the extent possible, most closely +approximates an absolute disclaimer and waiver of all liability. + +Section 6 – Term and Termination. + +a. This Public License applies for the term of the Copyright and Similar Rights +licensed here. However, if You fail to comply with this Public License, then +Your rights under this Public License terminate automatically. + +b. Where Your right to use the Licensed Material has terminated under Section +6(a), it reinstates: + +1. automatically as of the date the violation is cured, provided it is cured +within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + +c. For the avoidance of doubt, this Section 6(b) does not affect any right +the Licensor may have to seek remedies for Your violations of this Public +License. + +d. For the avoidance of doubt, the Licensor may also offer the Licensed Material +under separate terms or conditions or stop distributing the Licensed Material +at any time; however, doing so will not terminate this Public License. + + e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +Section 7 – Other Terms and Conditions. + +a. The Licensor shall not be bound by any additional or different terms or +conditions communicated by You unless expressly agreed. + +b. Any arrangements, understandings, or agreements regarding the Licensed +Material not stated herein are separate from and independent of the terms +and conditions of this Public License. + +Section 8 – Interpretation. + +a. For the avoidance of doubt, this Public License does not, and shall not +be interpreted to, reduce, limit, restrict, or impose conditions on any use +of the Licensed Material that could lawfully be made without permission under +this Public License. + +b. To the extent possible, if any provision of this Public License is deemed +unenforceable, it shall be automatically reformed to the minimum extent necessary +to make it enforceable. If the provision cannot be reformed, it shall be severed +from this Public License without affecting the enforceability of the remaining +terms and conditions. + +c. No term or condition of this Public License will be waived and no failure +to comply consented to unless expressly agreed to by the Licensor. + +d. Nothing in this Public License constitutes or may be interpreted as a limitation +upon, or waiver of, any privileges and immunities that apply to the Licensor +or You, including from the legal processes of any jurisdiction or authority. + +Creative Commons is not a party to its public licenses. Notwithstanding, Creative +Commons may elect to apply one of its public licenses to material it publishes +and in those instances will be considered the "Licensor." The text of the +Creative Commons public licenses is dedicated to the public domain under the +CC0 Public Domain Dedication. Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as otherwise +permitted by the Creative Commons policies published at creativecommons.org/policies, +Creative Commons does not authorize the use of the trademark "Creative Commons" +or any other trademark or logo of Creative Commons without its prior written +consent including, without limitation, in connection with any unauthorized +modifications to any of its public licenses or any other arrangements, understandings, +or agreements concerning use of licensed material. For the avoidance of doubt, +this paragraph does not form part of the public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/build.gradle b/build.gradle index d9efd03d..64952c74 100644 --- a/build.gradle +++ b/build.gradle @@ -4,8 +4,8 @@ */ buildscript { - ext.nlpVersion = '2.0-alpha1' - ext.remoteDroidGuardVersion = '0.1.1' + ext.nlpVersion = '2.0-alpha2' + ext.remoteDroidGuardVersion = '0.1.2' ext.safeParcelVersion = '1.6.0' ext.wearableVersion = '0.1.1' @@ -53,7 +53,7 @@ def execResult(...args) { return stdout.toString().trim() } -def gmsVersion = "19.4.20" +def gmsVersion = "20.24.14" def gmsVersionCode = Integer.parseInt(gmsVersion.replaceAll('\\.', '')) def gitVersionBase = execResult('git', 'describe', '--tags', '--abbrev=0', '--match=v[0-9]*').substring(1) def gitCommitCount = Integer.parseInt(execResult('git', 'rev-list', '--count', "v$gitVersionBase..HEAD")) diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/ISignInButtonCreator.aidl b/play-services-api/src/main/aidl/com/google/android/gms/common/internal/ISignInButtonCreator.aidl similarity index 100% rename from play-services-basement/src/main/aidl/com/google/android/gms/common/internal/ISignInButtonCreator.aidl rename to play-services-api/src/main/aidl/com/google/android/gms/common/internal/ISignInButtonCreator.aidl diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/server/FavaDiagnosticsEntity.aidl b/play-services-api/src/main/aidl/com/google/android/gms/common/server/FavaDiagnosticsEntity.aidl similarity index 100% rename from play-services-basement/src/main/aidl/com/google/android/gms/common/server/FavaDiagnosticsEntity.aidl rename to play-services-api/src/main/aidl/com/google/android/gms/common/server/FavaDiagnosticsEntity.aidl diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/server/FavaDiagnosticsEntity.java b/play-services-api/src/main/java/com/google/android/gms/common/server/FavaDiagnosticsEntity.java similarity index 100% rename from play-services-basement/src/main/java/com/google/android/gms/common/server/FavaDiagnosticsEntity.java rename to play-services-api/src/main/java/com/google/android/gms/common/server/FavaDiagnosticsEntity.java diff --git a/play-services-base-api/build.gradle b/play-services-base-api/build.gradle new file mode 100644 index 00000000..70d9d624 --- /dev/null +++ b/play-services-base-api/build.gradle @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2015 microG Project Team + * + * 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 + * + * http://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. + */ + +apply plugin: 'com.android.library' + +dependencies { + api project(':play-services-basement') +} + +android { + compileSdkVersion androidCompileSdk + buildToolsVersion "$androidBuildVersionTools" + + aidlPackageWhiteList "com/google/android/gms/common/data/DataHolder.aidl" + aidlPackageWhiteList "com/google/android/gms/common/images/WebImage.aidl" + + defaultConfig { + versionName version + minSdkVersion androidMinSdk + targetSdkVersion androidTargetSdk + } + + compileOptions { + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + } +} diff --git a/play-services-base-api/src/main/AndroidManifest.xml b/play-services-base-api/src/main/AndroidManifest.xml new file mode 100644 index 00000000..7c8eeef3 --- /dev/null +++ b/play-services-base-api/src/main/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + diff --git a/play-services-base-api/src/main/aidl/com/google/android/gms/common/api/internal/IStatusCallback.aidl b/play-services-base-api/src/main/aidl/com/google/android/gms/common/api/internal/IStatusCallback.aidl new file mode 100644 index 00000000..6355a13b --- /dev/null +++ b/play-services-base-api/src/main/aidl/com/google/android/gms/common/api/internal/IStatusCallback.aidl @@ -0,0 +1,7 @@ +package com.google.android.gms.common.api.internal; + +import com.google.android.gms.common.api.Status; + +interface IStatusCallback { + void onResult(in Status status); +} diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/data/DataHolder.aidl b/play-services-base-api/src/main/aidl/com/google/android/gms/common/data/DataHolder.aidl similarity index 100% rename from play-services-basement/src/main/aidl/com/google/android/gms/common/data/DataHolder.aidl rename to play-services-base-api/src/main/aidl/com/google/android/gms/common/data/DataHolder.aidl diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/images/WebImage.aidl b/play-services-base-api/src/main/aidl/com/google/android/gms/common/images/WebImage.aidl similarity index 100% rename from play-services-basement/src/main/aidl/com/google/android/gms/common/images/WebImage.aidl rename to play-services-base-api/src/main/aidl/com/google/android/gms/common/images/WebImage.aidl diff --git a/play-services-base-api/src/main/java/com/google/android/gms/auth/api/signin/GoogleSignInAccount.java b/play-services-base-api/src/main/java/com/google/android/gms/auth/api/signin/GoogleSignInAccount.java new file mode 100644 index 00000000..802db9a3 --- /dev/null +++ b/play-services-base-api/src/main/java/com/google/android/gms/auth/api/signin/GoogleSignInAccount.java @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.auth.api.signin; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class GoogleSignInAccount extends AutoSafeParcelable { + public static final Creator CREATOR = new AutoCreator(GoogleSignInAccount.class); +} diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/data/DataHolder.java b/play-services-base-api/src/main/java/com/google/android/gms/common/data/DataHolder.java similarity index 100% rename from play-services-basement/src/main/java/com/google/android/gms/common/data/DataHolder.java rename to play-services-base-api/src/main/java/com/google/android/gms/common/data/DataHolder.java diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/data/Freezable.java b/play-services-base-api/src/main/java/com/google/android/gms/common/data/Freezable.java similarity index 100% rename from play-services-basement/src/main/java/com/google/android/gms/common/data/Freezable.java rename to play-services-base-api/src/main/java/com/google/android/gms/common/data/Freezable.java diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/images/WebImage.java b/play-services-base-api/src/main/java/com/google/android/gms/common/images/WebImage.java similarity index 100% rename from play-services-basement/src/main/java/com/google/android/gms/common/images/WebImage.java rename to play-services-base-api/src/main/java/com/google/android/gms/common/images/WebImage.java diff --git a/play-services-base/build.gradle b/play-services-base/build.gradle index 7bdaad9f..3d47a737 100644 --- a/play-services-base/build.gradle +++ b/play-services-base/build.gradle @@ -35,6 +35,7 @@ android { dependencies { api project(':play-services-basement') api project(':play-services-tasks') + api project(':play-services-base-api') implementation "androidx.fragment:fragment:$fragmentVersion" } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/AccountInfo.java b/play-services-base/src/main/java/com/google/android/gms/common/api/AccountInfo.java index 94c11015..30d6a169 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/AccountInfo.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/AccountInfo.java @@ -18,6 +18,7 @@ package com.google.android.gms.common.api; import org.microg.safeparcel.AutoSafeParcelable; +@Deprecated public class AccountInfo extends AutoSafeParcelable { public static final Creator CREATOR = new AutoCreator(AccountInfo.class); } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/Api.java b/play-services-base/src/main/java/com/google/android/gms/common/api/Api.java index 610da966..065fff8a 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/Api.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/Api.java @@ -16,8 +16,12 @@ package com.google.android.gms.common.api; +import android.accounts.Account; + +import com.google.android.gms.auth.api.signin.GoogleSignInAccount; + import org.microg.gms.common.PublicApi; -import org.microg.gms.common.api.ApiBuilder; +import org.microg.gms.common.api.ApiClientBuilder; /** * Describes a section of the Google Play Services API that should be made available. Instances of @@ -33,16 +37,15 @@ import org.microg.gms.common.api.ApiBuilder; */ @PublicApi public final class Api { - - private final ApiBuilder builder; + private final ApiClientBuilder builder; @PublicApi(exclude = true) - public Api(ApiBuilder builder) { + public Api(ApiClientBuilder builder) { this.builder = builder; } @PublicApi(exclude = true) - public ApiBuilder getBuilder() { + public ApiClientBuilder getBuilder() { return builder; } @@ -79,6 +82,22 @@ public final class Api { @PublicApi interface Optional extends HasOptions, NotRequiredOptions { } + + /** + * An interface for {@link ApiOptions} that include an account. + */ + @PublicApi + interface HasAccountOptions extends HasOptions, NotRequiredOptions { + Account getAccount(); + } + + /** + * An interface for {@link ApiOptions} that includes a {@link GoogleSignInAccount} + */ + @PublicApi + interface HasGoogleSignInAccountOptions extends HasOptions { + GoogleSignInAccount getGoogleSignInAccount(); + } } } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApi.java b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApi.java new file mode 100644 index 00000000..455ba014 --- /dev/null +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApi.java @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.common.api; + +import android.content.Context; + +import com.google.android.gms.common.api.internal.ApiKey; +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.TaskCompletionSource; + +import org.microg.gms.common.PublicApi; +import org.microg.gms.common.api.ApiClient; +import org.microg.gms.common.api.GoogleApiManager; +import org.microg.gms.common.api.PendingGoogleApiCall; + +@PublicApi +public abstract class GoogleApi implements HasApiKey { + private GoogleApiManager manager; + @PublicApi(exclude = true) + public Api api; + + @PublicApi(exclude = true) + protected GoogleApi(Context context, Api api) { + this.api = api; + this.manager = GoogleApiManager.getInstance(context); + } + + @PublicApi(exclude = true) + protected Task scheduleTask(PendingGoogleApiCall apiCall) { + TaskCompletionSource completionSource = new TaskCompletionSource<>(); + manager.scheduleTask(this, apiCall, completionSource); + return completionSource.getTask(); + } + + @Override + @PublicApi(exclude = true) + public ApiKey getApiKey() { + return null; + } + + @PublicApi(exclude = true) + public O getOptions() { + return null; + } +} diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiClient.java b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiClient.java index 1cd0525f..fb7088e6 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiClient.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiClient.java @@ -29,6 +29,7 @@ import com.google.android.gms.common.ConnectionResult; import org.microg.gms.auth.AuthConstants; import org.microg.gms.common.PublicApi; +import org.microg.gms.common.api.ApiClientSettings; import org.microg.gms.common.api.GoogleApiClientImpl; import java.util.HashMap; @@ -56,6 +57,7 @@ import java.util.concurrent.TimeUnit; * in {@link Activity#onStop()}, regardless of the state. */ @PublicApi +@Deprecated public interface GoogleApiClient { /** * Connects the client to Google Play services. Blocks until the connection either succeeds or @@ -271,7 +273,7 @@ public interface GoogleApiClient { * attempt fails. */ public Builder(Context context, ConnectionCallbacks connectedListener, - OnConnectionFailedListener connectionFailedListener) { + OnConnectionFailedListener connectionFailedListener) { this(context); addConnectionCallbacks(connectedListener); addOnConnectionFailedListener(connectionFailedListener); @@ -358,16 +360,15 @@ public interface GoogleApiClient { * @return The {@link GoogleApiClient} object. */ public GoogleApiClient build() { - return new GoogleApiClientImpl(context, looper, getAccountInfo(), apis, - connectionCallbacks, connectionFailedListeners, clientId); + return new GoogleApiClientImpl(context, looper, getClientSettings(), apis, connectionCallbacks, connectionFailedListeners, clientId); } - private AccountInfo getAccountInfo() { + private ApiClientSettings getClientSettings() { return null; } public Builder enableAutoManage(FragmentActivity fragmentActivity, int cliendId, - OnConnectionFailedListener unresolvedConnectionFailedListener) + OnConnectionFailedListener unresolvedConnectionFailedListener) throws NullPointerException, IllegalArgumentException, IllegalStateException { this.fragmentActivity = fragmentActivity; this.clientId = cliendId; @@ -433,7 +434,8 @@ public interface GoogleApiClient { * service. Most applications implement {@link #onConnected(Bundle)} to start making requests. */ @PublicApi - interface ConnectionCallbacks { + @Deprecated + interface ConnectionCallbacks extends org.microg.gms.common.api.ConnectionCallbacks { /** * A suspension cause informing that the service has been killed. */ @@ -442,34 +444,6 @@ public interface GoogleApiClient { * A suspension cause informing you that a peer device connection was lost. */ int CAUSE_NETWORK_LOST = 2; - - /** - * After calling {@link #connect()}, this method will be invoked asynchronously when the - * connect request has successfully completed. After this callback, the application can - * make requests on other methods provided by the client and expect that no user - * intervention is required to call methods that use account and scopes provided to the - * client constructor. - *

- * Note that the contents of the {@code connectionHint} Bundle are defined by the specific - * services. Please see the documentation of the specific implementation of - * {@link GoogleApiClient} you are using for more information. - * - * @param connectionHint Bundle of data provided to clients by Google Play services. May - * be null if no content is provided by the service. - */ - void onConnected(Bundle connectionHint); - - /** - * Called when the client is temporarily in a disconnected state. This can happen if there - * is a problem with the remote service (e.g. a crash or resource problem causes it to be - * killed by the system). When called, all requests have been canceled and no outstanding - * listeners will be executed. GoogleApiClient will automatically attempt to restore the - * connection. Applications should disable UI components that require the service, and wait - * for a call to {@link #onConnected(Bundle)} to re-enable them. - * - * @param cause The reason for the disconnection. Defined by constants {@code CAUSE_*}. - */ - void onConnectionSuspended(int cause); } /** @@ -478,18 +452,7 @@ public interface GoogleApiClient { * resolution. */ @PublicApi - interface OnConnectionFailedListener { - /** - * Called when there was an error connecting the client to the service. - * - * @param result A {@link ConnectionResult} that can be used for resolving the error, and - * deciding what sort of error occurred. To resolve the error, the resolution - * must be started from an activity with a non-negative {@code requestCode} - * passed to {@link ConnectionResult#startResolutionForResult(Activity, int)}. - * Applications should implement {@link Activity#onActivityResult} in their - * Activity to call {@link #connect()} again if the user has resolved the - * issue (resultCode is {@link Activity#RESULT_OK}). - */ - void onConnectionFailed(ConnectionResult result); + @Deprecated + interface OnConnectionFailedListener extends org.microg.gms.common.api.OnConnectionFailedListener { } } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/HasApiKey.java b/play-services-base/src/main/java/com/google/android/gms/common/api/HasApiKey.java new file mode 100644 index 00000000..e208b4d8 --- /dev/null +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/HasApiKey.java @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.common.api; + +import com.google.android.gms.common.api.internal.ApiKey; + +public interface HasApiKey { + ApiKey getApiKey(); +} diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/internal/ApiKey.java b/play-services-base/src/main/java/com/google/android/gms/common/api/internal/ApiKey.java new file mode 100644 index 00000000..5a42d8fd --- /dev/null +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/internal/ApiKey.java @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.common.api.internal; + +import com.google.android.gms.common.api.Api; + +public class ApiKey { + private Api api; +} diff --git a/play-services-base/src/main/java/org/microg/gms/common/DummyApiConnection.java b/play-services-base/src/main/java/org/microg/gms/common/DummyApiClient.java similarity index 90% rename from play-services-base/src/main/java/org/microg/gms/common/DummyApiConnection.java rename to play-services-base/src/main/java/org/microg/gms/common/DummyApiClient.java index 9476d3e7..132a6148 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/DummyApiConnection.java +++ b/play-services-base/src/main/java/org/microg/gms/common/DummyApiClient.java @@ -16,9 +16,9 @@ package org.microg.gms.common; -import org.microg.gms.common.api.ApiConnection; +import org.microg.gms.common.api.ApiClient; -public class DummyApiConnection implements ApiConnection { +public class DummyApiClient implements ApiClient { private boolean connected = false; @Override diff --git a/play-services-base/src/main/java/org/microg/gms/common/GmsClient.java b/play-services-base/src/main/java/org/microg/gms/common/GmsClient.java index 779f4769..64ac6942 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/GmsClient.java +++ b/play-services-base/src/main/java/org/microg/gms/common/GmsClient.java @@ -27,19 +27,20 @@ import android.os.RemoteException; import android.util.Log; import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.internal.GetServiceRequest; import com.google.android.gms.common.internal.IGmsCallbacks; import com.google.android.gms.common.internal.IGmsServiceBroker; -import org.microg.gms.common.api.ApiConnection; +import org.microg.gms.common.api.ApiClient; +import org.microg.gms.common.api.ConnectionCallbacks; +import org.microg.gms.common.api.OnConnectionFailedListener; -public abstract class GmsClient implements ApiConnection { +public abstract class GmsClient implements ApiClient { private static final String TAG = "GmsClient"; private final Context context; - protected final GoogleApiClient.ConnectionCallbacks callbacks; - protected final GoogleApiClient.OnConnectionFailedListener connectionFailedListener; + protected final ConnectionCallbacks callbacks; + protected final OnConnectionFailedListener connectionFailedListener; protected ConnectionState state = ConnectionState.NOT_CONNECTED; private ServiceConnection serviceConnection; private I serviceInterface; @@ -49,8 +50,7 @@ public abstract class GmsClient implements ApiConnection { protected Account account = null; protected Bundle extras = new Bundle(); - public GmsClient(Context context, GoogleApiClient.ConnectionCallbacks callbacks, - GoogleApiClient.OnConnectionFailedListener connectionFailedListener, String actionString) { + public GmsClient(Context context, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener, String actionString) { this.context = context; this.callbacks = callbacks; this.connectionFailedListener = connectionFailedListener; @@ -89,8 +89,7 @@ public abstract class GmsClient implements ApiConnection { } public void handleConnectionFailed() { - connectionFailedListener.onConnectionFailed(new ConnectionResult(ConnectionResult - .API_UNAVAILABLE, null)); + connectionFailedListener.onConnectionFailed(new ConnectionResult(ConnectionResult.API_UNAVAILABLE, null)); } @Override @@ -147,8 +146,7 @@ public abstract class GmsClient implements ApiConnection { public void onServiceConnected(ComponentName componentName, IBinder iBinder) { try { Log.d(TAG, "ServiceConnection : onServiceConnected(" + componentName + ")"); - onConnectedToBroker(IGmsServiceBroker.Stub.asInterface(iBinder), - new GmsCallbacks()); + onConnectedToBroker(IGmsServiceBroker.Stub.asInterface(iBinder), new GmsCallbacks()); } catch (RemoteException e) { disconnect(); } diff --git a/play-services-base/src/main/java/org/microg/gms/common/GmsConnector.java b/play-services-base/src/main/java/org/microg/gms/common/GmsConnector.java index 9de363f6..8013d70f 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/GmsConnector.java +++ b/play-services-base/src/main/java/org/microg/gms/common/GmsConnector.java @@ -27,10 +27,10 @@ import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.Result; import org.microg.gms.common.api.AbstractPendingResult; -import org.microg.gms.common.api.ApiConnection; +import org.microg.gms.common.api.ApiClient; import org.microg.gms.common.api.GoogleApiClientImpl; -public class GmsConnector { +public class GmsConnector { private static final String TAG = "GmsConnector"; private final GoogleApiClientImpl apiClient; @@ -43,7 +43,7 @@ public class GmsConnector { this.callback = callback; } - public static PendingResult call(GoogleApiClient client, Api api, GmsConnector.Callback callback) { + public static PendingResult call(GoogleApiClient client, Api api, GmsConnector.Callback callback) { return new GmsConnector(client, api, callback).connect(); } diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/ApiConnection.java b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClient.java similarity index 95% rename from play-services-base/src/main/java/org/microg/gms/common/api/ApiConnection.java rename to play-services-base/src/main/java/org/microg/gms/common/api/ApiClient.java index 9ca239b4..602e150e 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/api/ApiConnection.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClient.java @@ -16,7 +16,7 @@ package org.microg.gms.common.api; -public interface ApiConnection { +public interface ApiClient { void connect(); void disconnect(); diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/ApiBuilder.java b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientBuilder.java similarity index 64% rename from play-services-base/src/main/java/org/microg/gms/common/api/ApiBuilder.java rename to play-services-base/src/main/java/org/microg/gms/common/api/ApiClientBuilder.java index 7d1fb020..b5aa386f 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/api/ApiBuilder.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientBuilder.java @@ -19,12 +19,8 @@ package org.microg.gms.common.api; import android.content.Context; import android.os.Looper; -import com.google.android.gms.common.api.AccountInfo; import com.google.android.gms.common.api.Api; -import com.google.android.gms.common.api.GoogleApiClient; -public interface ApiBuilder { - ApiConnection build(Context context, Looper looper, O options, AccountInfo accountInfo, - GoogleApiClient.ConnectionCallbacks callbacks, - GoogleApiClient.OnConnectionFailedListener connectionFailedListener); +public interface ApiClientBuilder { + ApiClient build(O options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener); } diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientSettings.java b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientSettings.java new file mode 100644 index 00000000..d1e314a7 --- /dev/null +++ b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientSettings.java @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.common.api; + +public class ApiClientSettings { +} diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/ConnectionCallbacks.java b/play-services-base/src/main/java/org/microg/gms/common/api/ConnectionCallbacks.java new file mode 100644 index 00000000..738a43d3 --- /dev/null +++ b/play-services-base/src/main/java/org/microg/gms/common/api/ConnectionCallbacks.java @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.common.api; + +import android.os.Bundle; + +import com.google.android.gms.common.api.GoogleApiClient; + +public interface ConnectionCallbacks { + + /** + * After calling {@link #connect()}, this method will be invoked asynchronously when the + * connect request has successfully completed. After this callback, the application can + * make requests on other methods provided by the client and expect that no user + * intervention is required to call methods that use account and scopes provided to the + * client constructor. + *

+ * Note that the contents of the {@code connectionHint} Bundle are defined by the specific + * services. Please see the documentation of the specific implementation of + * {@link GoogleApiClient} you are using for more information. + * + * @param connectionHint Bundle of data provided to clients by Google Play services. May + * be null if no content is provided by the service. + */ + void onConnected(Bundle connectionHint); + + /** + * Called when the client is temporarily in a disconnected state. This can happen if there + * is a problem with the remote service (e.g. a crash or resource problem causes it to be + * killed by the system). When called, all requests have been canceled and no outstanding + * listeners will be executed. GoogleApiClient will automatically attempt to restore the + * connection. Applications should disable UI components that require the service, and wait + * for a call to {@link #onConnected(Bundle)} to re-enable them. + * + * @param cause The reason for the disconnection. Defined by constants {@code CAUSE_*}. + */ + void onConnectionSuspended(int cause); +} diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiClientImpl.java b/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiClientImpl.java index 8c802d4a..11233697 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiClientImpl.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiClientImpl.java @@ -20,11 +20,12 @@ import android.content.Context; import android.os.Bundle; import android.os.Looper; import android.os.Message; + import androidx.fragment.app.FragmentActivity; + import android.util.Log; import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.api.AccountInfo; import com.google.android.gms.common.api.Api; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; @@ -41,10 +42,9 @@ public class GoogleApiClientImpl implements GoogleApiClient { private final Context context; private final Looper looper; - private final AccountInfo accountInfo; + private final ApiClientSettings clientSettings; private final Map apis = new HashMap(); - private final Map apiConnections = new HashMap(); - private final Handler handler; + private final Map apiConnections = new HashMap(); private final Set connectionCallbacks = new HashSet(); private final Set connectionFailedListeners = new HashSet(); private final int clientId; @@ -78,23 +78,20 @@ public class GoogleApiClientImpl implements GoogleApiClient { private int usageCounter = 0; private boolean shouldDisconnect = false; - public GoogleApiClientImpl(Context context, Looper looper, AccountInfo accountInfo, + public GoogleApiClientImpl(Context context, Looper looper, ApiClientSettings clientSettings, Map apis, Set connectionCallbacks, Set connectionFailedListeners, int clientId) { this.context = context; this.looper = looper; - this.handler = new Handler(looper); - this.accountInfo = accountInfo; + this.clientSettings = clientSettings; this.apis.putAll(apis); this.connectionCallbacks.addAll(connectionCallbacks); this.connectionFailedListeners.addAll(connectionFailedListeners); this.clientId = clientId; for (Api api : apis.keySet()) { - apiConnections.put(api, api.getBuilder().build(context, looper, - apis.get(api), accountInfo, baseConnectionCallbacks, - baseConnectionFailedListener)); + apiConnections.put(api, api.getBuilder().build(apis.get(api), context, looper, clientSettings, baseConnectionCallbacks, baseConnectionFailedListener)); } } @@ -111,7 +108,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { return looper; } - public ApiConnection getApiConnection(Api api) { + public ApiClient getApiConnection(Api api) { return apiConnections.get(api); } @@ -141,7 +138,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { Log.d(TAG, "Already connected/connecting, nothing to do"); return; } - for (ApiConnection connection : apiConnections.values()) { + for (ApiClient connection : apiConnections.values()) { if (!connection.isConnected()) { connection.connect(); } @@ -154,7 +151,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { shouldDisconnect = true; } else { Log.d(TAG, "disconnect()"); - for (ApiConnection connection : apiConnections.values()) { + for (ApiClient connection : apiConnections.values()) { if (connection.isConnected()) { connection.disconnect(); } @@ -164,7 +161,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { @Override public synchronized boolean isConnected() { - for (ApiConnection connection : apiConnections.values()) { + for (ApiClient connection : apiConnections.values()) { if (!connection.isConnected()) return false; } return true; @@ -172,7 +169,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { @Override public synchronized boolean isConnecting() { - for (ApiConnection connection : apiConnections.values()) { + for (ApiClient connection : apiConnections.values()) { if (connection.isConnecting()) return true; } return false; @@ -220,23 +217,4 @@ public class GoogleApiClientImpl implements GoogleApiClient { public void unregisterConnectionFailedListener(OnConnectionFailedListener listener) { connectionFailedListeners.remove(listener); } - - private class Handler extends android.os.Handler { - private Handler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - if (msg.what == 0 && msg.obj instanceof Runnable) { - ((Runnable) msg.obj).run(); - } else { - super.handleMessage(msg); - } - } - - public void sendRunnable(Runnable runnable) { - sendMessage(obtainMessage(1, runnable)); - } - } } diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiManager.java b/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiManager.java new file mode 100644 index 00000000..1662ca31 --- /dev/null +++ b/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiManager.java @@ -0,0 +1,180 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.common.api; + +import android.content.Context; +import android.os.Bundle; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.api.Api; +import com.google.android.gms.common.api.GoogleApi; +import com.google.android.gms.tasks.TaskCompletionSource; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GoogleApiManager { + private static GoogleApiManager instance; + private Context context; + private Map clientMap = new HashMap<>(); + private Map>> waitingApiCallMap = new HashMap<>(); + + private GoogleApiManager(Context context) { + this.context = context; + } + + public synchronized static GoogleApiManager getInstance(Context context) { + if (instance == null) instance = new GoogleApiManager(context); + return instance; + } + + private synchronized A clientForApi(GoogleApi api) { + ApiInstance apiInstance = new ApiInstance(api); + if (clientMap.containsKey(apiInstance)) { + return (A) clientMap.get(apiInstance); + } else { + ApiClient client = api.api.getBuilder().build(api.getOptions(), context, context.getMainLooper(), null, new ConnectionCallback(apiInstance), new ConnectionFailedListener(apiInstance)); + clientMap.put(apiInstance, client); + waitingApiCallMap.put(apiInstance, new ArrayList<>()); + return (A) client; + } + } + + public synchronized void scheduleTask(GoogleApi api, PendingGoogleApiCall apiCall, TaskCompletionSource completionSource) { + A client = clientForApi(api); + boolean connecting = client.isConnecting(); + boolean connected = client.isConnected(); + if (connected) { + apiCall.execute(client, completionSource); + } else { + waitingApiCallMap.get(new ApiInstance(api)).add(new WaitingApiCall((PendingGoogleApiCall) apiCall, completionSource)); + if (!connecting) { + client.connect(); + } + } + } + + private synchronized void onInstanceConnected(ApiInstance apiInstance, Bundle connectionHint) { + List> waitingApiCalls = waitingApiCallMap.get(apiInstance); + for (WaitingApiCall waitingApiCall : waitingApiCalls) { + waitingApiCall.execute(clientMap.get(apiInstance)); + } + waitingApiCalls.clear(); + } + + private synchronized void onInstanceSuspended(ApiInstance apiInstance, int cause) { + + } + + private synchronized void onInstanceFailed(ApiInstance apiInstance, ConnectionResult result) { + List> waitingApiCalls = waitingApiCallMap.get(apiInstance); + for (WaitingApiCall waitingApiCall : waitingApiCalls) { + waitingApiCall.failed(new RuntimeException(result.getErrorMessage())); + } + waitingApiCalls.clear(); + } + + private class ConnectionCallback implements ConnectionCallbacks { + private ApiInstance apiInstance; + + public ConnectionCallback(ApiInstance apiInstance) { + this.apiInstance = apiInstance; + } + + @Override + public void onConnected(Bundle connectionHint) { + onInstanceConnected(apiInstance, connectionHint); + } + + @Override + public void onConnectionSuspended(int cause) { + onInstanceSuspended(apiInstance, cause); + } + } + + private class ConnectionFailedListener implements OnConnectionFailedListener { + private ApiInstance apiInstance; + + public ConnectionFailedListener(ApiInstance apiInstance) { + this.apiInstance = apiInstance; + } + + @Override + public void onConnectionFailed(ConnectionResult result) { + onInstanceFailed(apiInstance, result); + } + } + + private static class WaitingApiCall { + private PendingGoogleApiCall apiCall; + private TaskCompletionSource completionSource; + + public WaitingApiCall(PendingGoogleApiCall apiCall, TaskCompletionSource completionSource) { + this.apiCall = apiCall; + this.completionSource = completionSource; + } + + public void execute(ApiClient client) { + apiCall.execute(client, completionSource); + } + + public void failed(Exception e) { + completionSource.setException(e); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + WaitingApiCall that = (WaitingApiCall) o; + + if (apiCall != null ? !apiCall.equals(that.apiCall) : that.apiCall != null) return false; + return completionSource != null ? completionSource.equals(that.completionSource) : that.completionSource == null; + } + + @Override + public int hashCode() { + int result = apiCall != null ? apiCall.hashCode() : 0; + result = 31 * result + (completionSource != null ? completionSource.hashCode() : 0); + return result; + } + } + + private static class ApiInstance { + private Class apiClass; + private Api.ApiOptions apiOptions; + + public ApiInstance(Class apiClass, Api.ApiOptions apiOptions) { + this.apiClass = apiClass; + this.apiOptions = apiOptions; + } + + public ApiInstance(GoogleApi api) { + this(api.getClass(), api.getOptions()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ApiInstance that = (ApiInstance) o; + + if (apiClass != null ? !apiClass.equals(that.apiClass) : that.apiClass != null) return false; + return apiOptions != null ? apiOptions.equals(that.apiOptions) : that.apiOptions == null; + } + + @Override + public int hashCode() { + int result = apiClass != null ? apiClass.hashCode() : 0; + result = 31 * result + (apiOptions != null ? apiOptions.hashCode() : 0); + return result; + } + } +} diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/InstantGoogleApiCall.java b/play-services-base/src/main/java/org/microg/gms/common/api/InstantGoogleApiCall.java new file mode 100644 index 00000000..5e813d8b --- /dev/null +++ b/play-services-base/src/main/java/org/microg/gms/common/api/InstantGoogleApiCall.java @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.common.api; + +import com.google.android.gms.tasks.TaskCompletionSource; + +public interface InstantGoogleApiCall extends PendingGoogleApiCall { + R execute(A client) throws Exception; + + @Override + default void execute(A client, TaskCompletionSource completionSource) { + try { + completionSource.setResult(execute(client)); + } catch (Exception e) { + completionSource.setException(e); + } + } +} diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/OnConnectionFailedListener.java b/play-services-base/src/main/java/org/microg/gms/common/api/OnConnectionFailedListener.java new file mode 100644 index 00000000..cd994235 --- /dev/null +++ b/play-services-base/src/main/java/org/microg/gms/common/api/OnConnectionFailedListener.java @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.common.api; + +import android.app.Activity; + +import com.google.android.gms.common.ConnectionResult; + +public interface OnConnectionFailedListener { + /** + * Called when there was an error connecting the client to the service. + * + * @param result A {@link ConnectionResult} that can be used for resolving the error, and + * deciding what sort of error occurred. To resolve the error, the resolution + * must be started from an activity with a non-negative {@code requestCode} + * passed to {@link ConnectionResult#startResolutionForResult(Activity, int)}. + * Applications should implement {@link Activity#onActivityResult} in their + * Activity to call {@link #connect()} again if the user has resolved the + * issue (resultCode is {@link Activity#RESULT_OK}). + */ + void onConnectionFailed(ConnectionResult result); +} diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/PendingGoogleApiCall.java b/play-services-base/src/main/java/org/microg/gms/common/api/PendingGoogleApiCall.java new file mode 100644 index 00000000..8c92abd7 --- /dev/null +++ b/play-services-base/src/main/java/org/microg/gms/common/api/PendingGoogleApiCall.java @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.common.api; + +import com.google.android.gms.tasks.TaskCompletionSource; + +public interface PendingGoogleApiCall { + void execute(A client, TaskCompletionSource completionSource); +} diff --git a/play-services-basement/build.gradle b/play-services-basement/build.gradle index e88b1909..201ce74e 100644 --- a/play-services-basement/build.gradle +++ b/play-services-basement/build.gradle @@ -30,8 +30,6 @@ android { buildToolsVersion "$androidBuildVersionTools" aidlPackageWhiteList "com/google/android/gms/common/api/Status.aidl" - aidlPackageWhiteList "com/google/android/gms/common/data/DataHolder.aidl" - aidlPackageWhiteList "com/google/android/gms/common/images/WebImage.aidl" aidlPackageWhiteList "com/google/android/gms/common/internal/ICancelToken.aidl" aidlPackageWhiteList "com/google/android/gms/common/server/FavaDiagnosticsEntity.aidl" aidlPackageWhiteList "com/google/android/gms/dynamic/IObjectWrapper.aidl" diff --git a/play-services-basement/src/main/java/org/microg/gms/common/Constants.java b/play-services-basement/src/main/java/org/microg/gms/common/Constants.java index e6680da8..67222fc4 100644 --- a/play-services-basement/src/main/java/org/microg/gms/common/Constants.java +++ b/play-services-basement/src/main/java/org/microg/gms/common/Constants.java @@ -17,7 +17,7 @@ package org.microg.gms.common; public class Constants { - public static final int MAX_REFERENCE_VERSION = 19420 * 1000; + public static final int MAX_REFERENCE_VERSION = 202414 * 1000; public static final String GMS_PACKAGE_NAME = "com.google.android.gms"; public static final String GSF_PACKAGE_NAME = "com.google.android.gsf"; public static final String GMS_PACKAGE_SIGNATURE_SHA1 = "38918a453d07199354f8b19af05ec6562ced5788"; diff --git a/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java b/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java index 19dcf1e3..73f32940 100644 --- a/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java +++ b/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java @@ -98,6 +98,7 @@ public enum GmsService { GASS(116, "com.google.android.gms.gass.START"), WORK_ACCOUNT(120), AD_CACHE(123, "com.google.android.gms.ads.service.CACHE"), + NEARBY_EXPOSURE(236, "com.google.android.gms.nearby.exposurenotification.START") ; public int SERVICE_ID; diff --git a/play-services-cast-api/build.gradle b/play-services-cast-api/build.gradle index b3d5f509..bdc679a1 100644 --- a/play-services-cast-api/build.gradle +++ b/play-services-cast-api/build.gradle @@ -37,4 +37,6 @@ android { dependencies { api project(':play-services-basement') + + api project(':play-services-base-api') } diff --git a/play-services-cast-framework-api/build.gradle b/play-services-cast-framework-api/build.gradle index db8f59e4..9db7c812 100644 --- a/play-services-cast-framework-api/build.gradle +++ b/play-services-cast-framework-api/build.gradle @@ -34,5 +34,7 @@ android { dependencies { api project(':play-services-basement') + + api project(':play-services-base-api') api project(':play-services-cast-api') } diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/Cast.java b/play-services-cast/src/main/java/com/google/android/gms/cast/Cast.java index b223b584..33f7be44 100644 --- a/play-services-cast/src/main/java/com/google/android/gms/cast/Cast.java +++ b/play-services-cast/src/main/java/com/google/android/gms/cast/Cast.java @@ -24,7 +24,7 @@ import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.Result; import com.google.android.gms.common.api.Status; -import org.microg.gms.cast.CastApiBuilder; +import org.microg.gms.cast.CastApiClientBuilder; import org.microg.gms.cast.CastApiImpl; import org.microg.gms.common.PublicApi; @@ -89,7 +89,7 @@ public final class Cast { /** * Token to pass to {@link GoogleApiClient.Builder#addApi(Api)} to enable the Cast features. */ - public static final Api API = new Api(new CastApiBuilder()); + public static final Api API = new Api(new CastApiClientBuilder()); /** * An implementation of the CastApi interface. The interface is used to interact with a cast device. diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/CastRemoteDisplay.java b/play-services-cast/src/main/java/com/google/android/gms/cast/CastRemoteDisplay.java index ddb5d53c..30c20e73 100644 --- a/play-services-cast/src/main/java/com/google/android/gms/cast/CastRemoteDisplay.java +++ b/play-services-cast/src/main/java/com/google/android/gms/cast/CastRemoteDisplay.java @@ -23,7 +23,7 @@ import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.Result; import com.google.android.gms.common.api.Status; -import org.microg.gms.cast.CastRemoteDisplayApiBuilder; +import org.microg.gms.cast.CastRemoteDisplayApiClientBuilder; import org.microg.gms.cast.CastRemoteDisplayApiImpl; import org.microg.gms.common.PublicApi; @@ -32,7 +32,7 @@ public final class CastRemoteDisplay { /** * Token to pass to {@link GoogleApiClient.Builder#addApi(Api)} to enable the CastRemoteDisplay features. */ - public static final Api API = new Api(new CastRemoteDisplayApiBuilder()); + public static final Api API = new Api(new CastRemoteDisplayApiClientBuilder()); /** * An implementation of the CastRemoteDisplayAPI interface. The interface is used to interact with a cast device. diff --git a/play-services-cast/src/main/java/org/microg/gms/cast/CastApiBuilder.java b/play-services-cast/src/main/java/org/microg/gms/cast/CastApiClientBuilder.java similarity index 60% rename from play-services-cast/src/main/java/org/microg/gms/cast/CastApiBuilder.java rename to play-services-cast/src/main/java/org/microg/gms/cast/CastApiClientBuilder.java index cc40793f..aba48971 100644 --- a/play-services-cast/src/main/java/org/microg/gms/cast/CastApiBuilder.java +++ b/play-services-cast/src/main/java/org/microg/gms/cast/CastApiClientBuilder.java @@ -20,15 +20,16 @@ import android.content.Context; import android.os.Looper; import com.google.android.gms.cast.Cast; -import com.google.android.gms.common.api.AccountInfo; -import com.google.android.gms.common.api.GoogleApiClient; -import org.microg.gms.common.api.ApiBuilder; -import org.microg.gms.common.api.ApiConnection; +import org.microg.gms.common.api.ApiClientBuilder; +import org.microg.gms.common.api.ApiClientSettings; +import org.microg.gms.common.api.ApiClient; +import org.microg.gms.common.api.ConnectionCallbacks; +import org.microg.gms.common.api.OnConnectionFailedListener; -public class CastApiBuilder implements ApiBuilder{ +public class CastApiClientBuilder implements ApiClientBuilder { @Override - public ApiConnection build(Context context, Looper looper, Cast.CastOptions options, AccountInfo accountInfo, GoogleApiClient.ConnectionCallbacks callbacks, GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { + public ApiClient build(Cast.CastOptions options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { return new CastClientImpl(context, options, callbacks, connectionFailedListener); } } diff --git a/play-services-cast/src/main/java/org/microg/gms/cast/CastClientImpl.java b/play-services-cast/src/main/java/org/microg/gms/cast/CastClientImpl.java index 1f80aa1f..8b6bd502 100644 --- a/play-services-cast/src/main/java/org/microg/gms/cast/CastClientImpl.java +++ b/play-services-cast/src/main/java/org/microg/gms/cast/CastClientImpl.java @@ -19,11 +19,12 @@ package org.microg.gms.cast; import android.content.Context; import com.google.android.gms.cast.Cast; -import com.google.android.gms.common.api.GoogleApiClient; -import org.microg.gms.common.DummyApiConnection; +import org.microg.gms.common.DummyApiClient; +import org.microg.gms.common.api.ConnectionCallbacks; +import org.microg.gms.common.api.OnConnectionFailedListener; -public class CastClientImpl extends DummyApiConnection { - public CastClientImpl(Context context, Cast.CastOptions options, GoogleApiClient.ConnectionCallbacks callbacks, GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { +public class CastClientImpl extends DummyApiClient { + public CastClientImpl(Context context, Cast.CastOptions options, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { } } diff --git a/play-services-cast/src/main/java/org/microg/gms/cast/CastRemoteDisplayApiBuilder.java b/play-services-cast/src/main/java/org/microg/gms/cast/CastRemoteDisplayApiClientBuilder.java similarity index 52% rename from play-services-cast/src/main/java/org/microg/gms/cast/CastRemoteDisplayApiBuilder.java rename to play-services-cast/src/main/java/org/microg/gms/cast/CastRemoteDisplayApiClientBuilder.java index 048afd15..588d25c3 100644 --- a/play-services-cast/src/main/java/org/microg/gms/cast/CastRemoteDisplayApiBuilder.java +++ b/play-services-cast/src/main/java/org/microg/gms/cast/CastRemoteDisplayApiClientBuilder.java @@ -20,16 +20,17 @@ import android.content.Context; import android.os.Looper; import com.google.android.gms.cast.CastRemoteDisplay; -import com.google.android.gms.common.api.AccountInfo; -import com.google.android.gms.common.api.GoogleApiClient; -import org.microg.gms.common.DummyApiConnection; -import org.microg.gms.common.api.ApiBuilder; -import org.microg.gms.common.api.ApiConnection; +import org.microg.gms.common.DummyApiClient; +import org.microg.gms.common.api.ApiClientBuilder; +import org.microg.gms.common.api.ApiClientSettings; +import org.microg.gms.common.api.ApiClient; +import org.microg.gms.common.api.ConnectionCallbacks; +import org.microg.gms.common.api.OnConnectionFailedListener; -public class CastRemoteDisplayApiBuilder implements ApiBuilder { +public class CastRemoteDisplayApiClientBuilder implements ApiClientBuilder { @Override - public ApiConnection build(Context context, Looper looper, CastRemoteDisplay.CastRemoteDisplayOptions options, AccountInfo accountInfo, GoogleApiClient.ConnectionCallbacks callbacks, GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { - return new DummyApiConnection(); + public ApiClient build(CastRemoteDisplay.CastRemoteDisplayOptions options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { + return new DummyApiClient(); } } diff --git a/play-services-gcm/build.gradle b/play-services-gcm/build.gradle index fc2881e0..26dc7663 100644 --- a/play-services-gcm/build.gradle +++ b/play-services-gcm/build.gradle @@ -43,5 +43,6 @@ android { dependencies { api project(':play-services-iid') - // compile project(':play-services-measurement') -} \ No newline at end of file + + implementation 'androidx.legacy:legacy-support-core-utils:1.0.0' // TODO +} diff --git a/play-services-gcm/src/main/java/com/google/android/gms/gcm/GcmReceiver.java b/play-services-gcm/src/main/java/com/google/android/gms/gcm/GcmReceiver.java index d160f42b..e9bba44b 100644 --- a/play-services-gcm/src/main/java/com/google/android/gms/gcm/GcmReceiver.java +++ b/play-services-gcm/src/main/java/com/google/android/gms/gcm/GcmReceiver.java @@ -24,9 +24,9 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.Build; -import android.support.v4.content.WakefulBroadcastReceiver; import android.util.Base64; import android.util.Log; +import androidx.legacy.content.WakefulBroadcastReceiver; import static org.microg.gms.gcm.GcmConstants.ACTION_C2DM_REGISTRATION; import static org.microg.gms.gcm.GcmConstants.ACTION_INSTANCE_ID; @@ -124,4 +124,4 @@ public class GcmReceiver extends WakefulBroadcastReceiver { setResultCode(code); } } -} \ No newline at end of file +} diff --git a/play-services-iid/build.gradle b/play-services-iid/build.gradle index c8960415..5edc4151 100644 --- a/play-services-iid/build.gradle +++ b/play-services-iid/build.gradle @@ -44,4 +44,6 @@ android { dependencies { api project(':play-services-base') api project(':play-services-iid-api') + + implementation 'androidx.legacy:legacy-support-core-utils:1.0.0' // TODO } diff --git a/play-services-iid/src/main/java/com/google/android/gms/iid/InstanceIDListenerService.java b/play-services-iid/src/main/java/com/google/android/gms/iid/InstanceIDListenerService.java index a15baa0f..c7bf61c7 100644 --- a/play-services-iid/src/main/java/com/google/android/gms/iid/InstanceIDListenerService.java +++ b/play-services-iid/src/main/java/com/google/android/gms/iid/InstanceIDListenerService.java @@ -25,7 +25,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; -import android.support.v4.content.WakefulBroadcastReceiver; +import androidx.legacy.content.WakefulBroadcastReceiver; import static org.microg.gms.gcm.GcmConstants.ACTION_C2DM_REGISTRATION; import static org.microg.gms.gcm.GcmConstants.ACTION_INSTANCE_ID; @@ -135,4 +135,4 @@ public class InstanceIDListenerService extends Service { } } -} \ No newline at end of file +} diff --git a/play-services-location-api/build.gradle b/play-services-location-api/build.gradle index 7d1eb81f..fb66e4c7 100644 --- a/play-services-location-api/build.gradle +++ b/play-services-location-api/build.gradle @@ -34,4 +34,6 @@ android { dependencies { api project(':play-services-basement') + + api project(':play-services-base-api') } diff --git a/play-services-location/build.gradle b/play-services-location/build.gradle index a19126df..57f5027b 100644 --- a/play-services-location/build.gradle +++ b/play-services-location/build.gradle @@ -44,4 +44,6 @@ android { dependencies { api project(':play-services-base') api project(':play-services-location-api') -} \ No newline at end of file + + implementation 'androidx.annotation:annotation:1.1.0' +} diff --git a/play-services-location/src/main/java/com/google/android/gms/location/ActivityRecognition.java b/play-services-location/src/main/java/com/google/android/gms/location/ActivityRecognition.java index ef9d76c3..f8f11656 100644 --- a/play-services-location/src/main/java/com/google/android/gms/location/ActivityRecognition.java +++ b/play-services-location/src/main/java/com/google/android/gms/location/ActivityRecognition.java @@ -19,7 +19,7 @@ package com.google.android.gms.location; import com.google.android.gms.common.api.Api; import com.google.android.gms.common.api.GoogleApiClient.Builder; -import org.microg.gms.location.ActivityRecognitionApiBuilder; +import org.microg.gms.location.ActivityRecognitionApiClientBuilder; import org.microg.gms.location.ActivityRecognitionApiImpl; /** @@ -31,7 +31,7 @@ public class ActivityRecognition { /** * Token to pass to {@link Builder#addApi(Api)} to enable ContextServices. */ - public static final Api API = new Api(new ActivityRecognitionApiBuilder()); + public static final Api API = new Api(new ActivityRecognitionApiClientBuilder()); /** * Entry point to the activity recognition APIs. diff --git a/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderApi.java b/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderApi.java index 768111b5..077bae35 100644 --- a/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderApi.java +++ b/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderApi.java @@ -26,6 +26,7 @@ import com.google.android.gms.common.api.Status; import org.microg.gms.location.LocationConstants; +@Deprecated public interface FusedLocationProviderApi { @Deprecated String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION"; diff --git a/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderClient.java b/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderClient.java new file mode 100644 index 00000000..a391c720 --- /dev/null +++ b/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderClient.java @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.location; + +import android.content.Context; +import android.location.Location; + +import com.google.android.gms.common.api.Api; +import com.google.android.gms.common.api.GoogleApi; +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.TaskCompletionSource; + +import org.microg.gms.common.PublicApi; +import org.microg.gms.common.api.InstantGoogleApiCall; +import org.microg.gms.common.api.PendingGoogleApiCall; +import org.microg.gms.location.LocationClientImpl; + +@PublicApi +public class FusedLocationProviderClient extends GoogleApi { + @PublicApi(exclude = true) + public FusedLocationProviderClient(Context context) { + super(context, LocationServices.API); + } + + public Task flushLocations() { + return scheduleTask(new PendingGoogleApiCall() { + @Override + public void execute(LocationClientImpl client, TaskCompletionSource completionSource) { + completionSource.setResult(null); + } + }); + } + + public Task getLastLocation() { + return scheduleTask((InstantGoogleApiCall) LocationClientImpl::getLastLocation); + } + + +} diff --git a/play-services-location/src/main/java/com/google/android/gms/location/GeofencingApi.java b/play-services-location/src/main/java/com/google/android/gms/location/GeofencingApi.java index 784c5c3e..9efc66ce 100644 --- a/play-services-location/src/main/java/com/google/android/gms/location/GeofencingApi.java +++ b/play-services-location/src/main/java/com/google/android/gms/location/GeofencingApi.java @@ -36,6 +36,7 @@ import java.util.List; * .build() * */ +@Deprecated public interface GeofencingApi { PendingResult addGeofences(GoogleApiClient client, GeofencingRequest geofencingRequest, PendingIntent pendingIntent); diff --git a/play-services-location/src/main/java/com/google/android/gms/location/LocationServices.java b/play-services-location/src/main/java/com/google/android/gms/location/LocationServices.java index 839550f4..f1f10a62 100644 --- a/play-services-location/src/main/java/com/google/android/gms/location/LocationServices.java +++ b/play-services-location/src/main/java/com/google/android/gms/location/LocationServices.java @@ -16,12 +16,14 @@ package com.google.android.gms.location; +import android.content.Context; + import com.google.android.gms.common.api.Api; import com.google.android.gms.common.api.GoogleApiClient.Builder; import org.microg.gms.location.FusedLocationProviderApiImpl; import org.microg.gms.location.GeofencingApiImpl; -import org.microg.gms.location.LocationServicesApiBuilder; +import org.microg.gms.location.LocationServicesApiClientBuilder; import org.microg.gms.location.SettingsApiImpl; /** @@ -31,20 +33,27 @@ public class LocationServices { /** * Token to pass to {@link Builder#addApi(Api)} to enable LocationServices. */ - public static final Api API = new Api(new LocationServicesApiBuilder()); + public static final Api API = new Api(new LocationServicesApiClientBuilder()); /** * Entry point to the fused location APIs. */ + @Deprecated public static final FusedLocationProviderApi FusedLocationApi = new FusedLocationProviderApiImpl(); /** * Entry point to the geofencing APIs. */ + @Deprecated public static final GeofencingApi GeofencingApi = new GeofencingApiImpl(); /** * Entry point to the location settings-enabler dialog APIs. */ + @Deprecated public static final SettingsApi SettingsApi = new SettingsApiImpl(); + + public static FusedLocationProviderClient getFusedLocationProviderClient(Context context) { + return new FusedLocationProviderClient(context); + } } diff --git a/play-services-location/src/main/java/com/google/android/gms/location/SettingsApi.java b/play-services-location/src/main/java/com/google/android/gms/location/SettingsApi.java index 708d7d02..b6529f7a 100644 --- a/play-services-location/src/main/java/com/google/android/gms/location/SettingsApi.java +++ b/play-services-location/src/main/java/com/google/android/gms/location/SettingsApi.java @@ -25,6 +25,7 @@ import com.google.android.gms.common.api.PendingResult; * This API makes it easy for an app to ensure that the device's system settings are properly * configured for the app's location needs. */ +@Deprecated public interface SettingsApi { /** * Checks if the relevant system settings are enabled on the device to carry out the desired diff --git a/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiBuilder.java b/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiClientBuilder.java similarity index 57% rename from play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiBuilder.java rename to play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiClientBuilder.java index f36ed0c0..1d22bd14 100644 --- a/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiBuilder.java +++ b/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiClientBuilder.java @@ -19,16 +19,17 @@ package org.microg.gms.location; import android.content.Context; import android.os.Looper; -import com.google.android.gms.common.api.AccountInfo; -import com.google.android.gms.common.api.Api; -import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.Api.ApiOptions.NoOptions; -import org.microg.gms.common.api.ApiBuilder; -import org.microg.gms.common.api.ApiConnection; +import org.microg.gms.common.api.ApiClientBuilder; +import org.microg.gms.common.api.ApiClientSettings; +import org.microg.gms.common.api.ApiClient; +import org.microg.gms.common.api.ConnectionCallbacks; +import org.microg.gms.common.api.OnConnectionFailedListener; -public class ActivityRecognitionApiBuilder implements ApiBuilder { +public class ActivityRecognitionApiClientBuilder implements ApiClientBuilder { @Override - public ApiConnection build(Context context, Looper looper, Api.ApiOptions.NoOptions options, AccountInfo accountInfo, GoogleApiClient.ConnectionCallbacks callbacks, GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { + public ApiClient build(NoOptions options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { return new ActivityRecognitionClientImpl(context, callbacks, connectionFailedListener); } } diff --git a/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionClientImpl.java b/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionClientImpl.java index cf065fc9..f48aa489 100644 --- a/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionClientImpl.java +++ b/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionClientImpl.java @@ -20,10 +20,11 @@ import android.app.PendingIntent; import android.content.Context; import android.os.RemoteException; -import com.google.android.gms.common.api.GoogleApiClient; +import org.microg.gms.common.api.ConnectionCallbacks; +import org.microg.gms.common.api.OnConnectionFailedListener; public class ActivityRecognitionClientImpl extends GoogleLocationManagerClient { - public ActivityRecognitionClientImpl(Context context, GoogleApiClient.ConnectionCallbacks callbacks, GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { + public ActivityRecognitionClientImpl(Context context, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { super(context, callbacks, connectionFailedListener); } diff --git a/play-services-location/src/main/java/org/microg/gms/location/FusedLocationProviderApiImpl.java b/play-services-location/src/main/java/org/microg/gms/location/FusedLocationProviderApiImpl.java index 0069974c..df10c6a8 100644 --- a/play-services-location/src/main/java/org/microg/gms/location/FusedLocationProviderApiImpl.java +++ b/play-services-location/src/main/java/org/microg/gms/location/FusedLocationProviderApiImpl.java @@ -24,7 +24,6 @@ import android.util.Log; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; -import com.google.android.gms.common.api.Result; import com.google.android.gms.common.api.Status; import com.google.android.gms.location.FusedLocationProviderApi; import com.google.android.gms.location.LocationListener; @@ -32,8 +31,8 @@ import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import org.microg.gms.common.GmsConnector; -import org.microg.gms.common.api.ApiConnection; +@SuppressWarnings("deprecation") public class FusedLocationProviderApiImpl implements FusedLocationProviderApi { private static final String TAG = "GmsFusedApiImpl"; diff --git a/play-services-location/src/main/java/org/microg/gms/location/GeofencingApiImpl.java b/play-services-location/src/main/java/org/microg/gms/location/GeofencingApiImpl.java index aed9276d..15e52833 100644 --- a/play-services-location/src/main/java/org/microg/gms/location/GeofencingApiImpl.java +++ b/play-services-location/src/main/java/org/microg/gms/location/GeofencingApiImpl.java @@ -18,8 +18,8 @@ package org.microg.gms.location; import android.app.PendingIntent; import android.os.RemoteException; -import android.support.annotation.NonNull; -import android.util.Log; + +import androidx.annotation.NonNull; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; diff --git a/play-services-location/src/main/java/org/microg/gms/location/GoogleLocationManagerClient.java b/play-services-location/src/main/java/org/microg/gms/location/GoogleLocationManagerClient.java index 55d0fae9..deb26d47 100644 --- a/play-services-location/src/main/java/org/microg/gms/location/GoogleLocationManagerClient.java +++ b/play-services-location/src/main/java/org/microg/gms/location/GoogleLocationManagerClient.java @@ -21,17 +21,18 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; -import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.internal.IGmsServiceBroker; import com.google.android.gms.location.internal.IGoogleLocationManagerService; import org.microg.gms.common.Constants; import org.microg.gms.common.GmsClient; import org.microg.gms.common.GmsService; +import org.microg.gms.common.api.ConnectionCallbacks; +import org.microg.gms.common.api.OnConnectionFailedListener; public abstract class GoogleLocationManagerClient extends GmsClient { - public GoogleLocationManagerClient(Context context, GoogleApiClient.ConnectionCallbacks - callbacks, GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { + public GoogleLocationManagerClient(Context context, ConnectionCallbacks + callbacks, OnConnectionFailedListener connectionFailedListener) { super(context, callbacks, connectionFailedListener, GmsService.LOCATION_MANAGER.ACTION); } diff --git a/play-services-location/src/main/java/org/microg/gms/location/LocationClientImpl.java b/play-services-location/src/main/java/org/microg/gms/location/LocationClientImpl.java index bc161d13..b2464774 100644 --- a/play-services-location/src/main/java/org/microg/gms/location/LocationClientImpl.java +++ b/play-services-location/src/main/java/org/microg/gms/location/LocationClientImpl.java @@ -33,7 +33,9 @@ import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.internal.IGeofencerCallbacks; import com.google.android.gms.location.internal.ParcelableGeofence; +import org.microg.gms.common.api.ConnectionCallbacks; import org.microg.gms.common.api.GoogleApiClientImpl; +import org.microg.gms.common.api.OnConnectionFailedListener; import java.util.HashMap; import java.util.List; @@ -45,8 +47,8 @@ public class LocationClientImpl extends GoogleLocationManagerClient { private Map listenerMap = new HashMap(); - public LocationClientImpl(Context context, GoogleApiClient.ConnectionCallbacks callbacks, - GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { + public LocationClientImpl(Context context, ConnectionCallbacks callbacks, + OnConnectionFailedListener connectionFailedListener) { super(context, callbacks, connectionFailedListener); Log.d(TAG, ""); } diff --git a/play-services-location/src/main/java/org/microg/gms/location/LocationServicesApiBuilder.java b/play-services-location/src/main/java/org/microg/gms/location/LocationServicesApiClientBuilder.java similarity index 56% rename from play-services-location/src/main/java/org/microg/gms/location/LocationServicesApiBuilder.java rename to play-services-location/src/main/java/org/microg/gms/location/LocationServicesApiClientBuilder.java index 2e053a81..504bcc46 100644 --- a/play-services-location/src/main/java/org/microg/gms/location/LocationServicesApiBuilder.java +++ b/play-services-location/src/main/java/org/microg/gms/location/LocationServicesApiClientBuilder.java @@ -19,19 +19,17 @@ package org.microg.gms.location; import android.content.Context; import android.os.Looper; -import com.google.android.gms.common.api.AccountInfo; -import com.google.android.gms.common.api.Api; -import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.Api.ApiOptions.NoOptions; -import org.microg.gms.common.api.ApiBuilder; -import org.microg.gms.common.api.ApiConnection; +import org.microg.gms.common.api.ApiClientBuilder; +import org.microg.gms.common.api.ApiClientSettings; +import org.microg.gms.common.api.ApiClient; +import org.microg.gms.common.api.ConnectionCallbacks; +import org.microg.gms.common.api.OnConnectionFailedListener; -public class LocationServicesApiBuilder implements ApiBuilder { +public class LocationServicesApiClientBuilder implements ApiClientBuilder { @Override - public ApiConnection build(Context context, Looper looper, - Api.ApiOptions.NoOptions options, - AccountInfo accountInfo, GoogleApiClient.ConnectionCallbacks callbacks, - GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { + public ApiClient build(NoOptions options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { return new LocationClientImpl(context, callbacks, connectionFailedListener); } } diff --git a/play-services-wearable-api/build.gradle b/play-services-wearable-api/build.gradle index 7d1eb81f..fb66e4c7 100644 --- a/play-services-wearable-api/build.gradle +++ b/play-services-wearable-api/build.gradle @@ -34,4 +34,6 @@ android { dependencies { api project(':play-services-basement') + + api project(':play-services-base-api') } diff --git a/play-services-wearable/src/main/java/com/google/android/gms/wearable/Wearable.java b/play-services-wearable/src/main/java/com/google/android/gms/wearable/Wearable.java index 88899989..e1fcd8ec 100644 --- a/play-services-wearable/src/main/java/com/google/android/gms/wearable/Wearable.java +++ b/play-services-wearable/src/main/java/com/google/android/gms/wearable/Wearable.java @@ -23,7 +23,7 @@ import org.microg.gms.common.PublicApi; import org.microg.gms.wearable.DataApiImpl; import org.microg.gms.wearable.MessageApiImpl; import org.microg.gms.wearable.NodeApiImpl; -import org.microg.gms.wearable.WearableApiBuilder; +import org.microg.gms.wearable.WearableApiClientBuilder; /** * An API for the Android Wear platform. @@ -33,7 +33,7 @@ public class Wearable { /** * Token to pass to {@link GoogleApiClient.Builder#addApi(Api)} to enable the Wearable features. */ - public static final Api API = new Api(new WearableApiBuilder()); + public static final Api API = new Api(new WearableApiClientBuilder()); public static final DataApi DataApi = new DataApiImpl(); public static final MessageApi MessageApi = new MessageApiImpl(); diff --git a/play-services-wearable/src/main/java/org/microg/gms/wearable/WearableApiBuilder.java b/play-services-wearable/src/main/java/org/microg/gms/wearable/WearableApiClientBuilder.java similarity index 62% rename from play-services-wearable/src/main/java/org/microg/gms/wearable/WearableApiBuilder.java rename to play-services-wearable/src/main/java/org/microg/gms/wearable/WearableApiClientBuilder.java index 3c20481b..ebfdc302 100644 --- a/play-services-wearable/src/main/java/org/microg/gms/wearable/WearableApiBuilder.java +++ b/play-services-wearable/src/main/java/org/microg/gms/wearable/WearableApiClientBuilder.java @@ -19,20 +19,19 @@ package org.microg.gms.wearable; import android.content.Context; import android.os.Looper; -import com.google.android.gms.common.api.AccountInfo; -import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.wearable.Wearable; -import org.microg.gms.common.api.ApiBuilder; -import org.microg.gms.common.api.ApiConnection; +import org.microg.gms.common.api.ApiClientBuilder; +import org.microg.gms.common.api.ApiClientSettings; +import org.microg.gms.common.api.ApiClient; +import org.microg.gms.common.api.ConnectionCallbacks; +import org.microg.gms.common.api.OnConnectionFailedListener; -public class WearableApiBuilder implements ApiBuilder { +public class WearableApiClientBuilder implements ApiClientBuilder { private static final String TAG = "GmsWearableApi"; @Override - public ApiConnection build(Context context, Looper looper, Wearable.WearableOptions options, - AccountInfo accountInfo, GoogleApiClient.ConnectionCallbacks callbacks, - GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { + public ApiClient build(Wearable.WearableOptions options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { return new WearableClientImpl(context, options, callbacks, connectionFailedListener); } } diff --git a/play-services-wearable/src/main/java/org/microg/gms/wearable/WearableClientImpl.java b/play-services-wearable/src/main/java/org/microg/gms/wearable/WearableClientImpl.java index 5a667f58..24eee806 100644 --- a/play-services-wearable/src/main/java/org/microg/gms/wearable/WearableClientImpl.java +++ b/play-services-wearable/src/main/java/org/microg/gms/wearable/WearableClientImpl.java @@ -26,12 +26,14 @@ import com.google.android.gms.wearable.internal.IWearableService; import org.microg.gms.common.GmsClient; import org.microg.gms.common.GmsService; +import org.microg.gms.common.api.ConnectionCallbacks; import org.microg.gms.common.api.GoogleApiClientImpl; +import org.microg.gms.common.api.OnConnectionFailedListener; public class WearableClientImpl extends GmsClient { private static final String TAG = "GmsWearClient"; - public WearableClientImpl(Context context, Wearable.WearableOptions options, GoogleApiClient.ConnectionCallbacks callbacks, GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { + public WearableClientImpl(Context context, Wearable.WearableOptions options, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { super(context, callbacks, connectionFailedListener, GmsService.WEARABLE.ACTION); serviceId = GmsService.WEARABLE.SERVICE_ID; if (options != null && options.firstPartyMode) diff --git a/settings.gradle b/settings.gradle index 72474e43..09762221 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,24 +2,33 @@ include ':wearable-lib' include ':play-services-basement' -include ':play-services-api' +include ':play-services-tasks' + +include ':play-services-base-api' include ':play-services-cast-api' include ':play-services-cast-framework-api' include ':play-services-iid-api' include ':play-services-location-api' +//include ':play-services-nearby-api' include ':play-services-wearable-api' -include ':play-services-base' -include ':play-services-tasks' -include ':play-services-wearable' +include ':play-services-api' include ':play-services-base-core' include ':play-services-location-core' include ':play-services-maps-core-mapbox' -include ':play-services-maps-core-vtm' include ':play-services-maps-core-vtm:vtm-microg-theme' +include ':play-services-maps-core-vtm' +include ':play-services-core:microg-ui-tools' // Legacy include ':play-services-core' -include ':play-services-core:microg-ui-tools' +include ':play-services-base' +include ':play-services-cast' +include ':play-services-gcm' +include ':play-services-iid' +include ':play-services-location' +//include ':play-services-nearby' +include ':play-services-wearable' +include ':play-services' From 1187a91325fe86602e51ccc2c6d521119f8d9508 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 26 Jul 2020 12:05:28 +0200 Subject: [PATCH 04/51] Remove some unnecessary classes from legacy ui tools --- .../tools/ui/DimmableIconPreference.java | 81 ------------------- .../microg/tools/ui/TintIconPreference.java | 45 ----------- 2 files changed, 126 deletions(-) delete mode 100644 play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/DimmableIconPreference.java delete mode 100644 play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/TintIconPreference.java diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/DimmableIconPreference.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/DimmableIconPreference.java deleted file mode 100644 index 791cbd02..00000000 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/DimmableIconPreference.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * 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 - * - * http://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. - */ - -package org.microg.tools.ui; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.preference.Preference; -import androidx.preference.PreferenceViewHolder; - -/** - * A preference item that can dim the icon when it's disabled, either directly or because its parent - * is disabled. - */ -public class DimmableIconPreference extends Preference { - private static final int ICON_ALPHA_ENABLED = 255; - private static final int ICON_ALPHA_DISABLED = 102; - - private final CharSequence mContentDescription; - - public DimmableIconPreference(Context context) { - this(context, (AttributeSet) null); - } - - public DimmableIconPreference(Context context, AttributeSet attrs) { - super(context, attrs); - mContentDescription = null; - } - - public DimmableIconPreference(Context context, CharSequence contentDescription) { - super(context); - mContentDescription = contentDescription; - } - - protected boolean shouldDimIcon() { - return !isEnabled(); - } - - private void dimIcon(boolean dimmed) { - Drawable icon = getIcon(); - if (icon != null) { - icon.mutate().setAlpha(dimmed ? ICON_ALPHA_DISABLED : ICON_ALPHA_ENABLED); - setIcon(icon); - } - } - - @Override - public void onBindViewHolder(PreferenceViewHolder view) { - super.onBindViewHolder(view); - if (!TextUtils.isEmpty(mContentDescription)) { - final TextView titleView = (TextView) view.findViewById(android.R.id.title); - titleView.setContentDescription(mContentDescription); - } - ViewGroup.LayoutParams layoutParams = view.findViewById(R.id.icon_frame).getLayoutParams(); - if (layoutParams instanceof LinearLayout.LayoutParams) { - if (((LinearLayout.LayoutParams) layoutParams).leftMargin < 0) { - ((LinearLayout.LayoutParams) layoutParams).leftMargin = 0; - } - } - dimIcon(shouldDimIcon()); - } -} diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/TintIconPreference.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/TintIconPreference.java deleted file mode 100644 index 05486b9c..00000000 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/TintIconPreference.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.microg.tools.ui; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.util.TypedValue; - -import androidx.core.graphics.drawable.DrawableCompat; -import androidx.preference.PreferenceViewHolder; - -import static android.os.Build.VERSION.SDK_INT; -import static android.os.Build.VERSION_CODES.LOLLIPOP; - -public class TintIconPreference extends DimmableIconPreference { - - public TintIconPreference(Context context) { - this(context, (AttributeSet) null); - } - - public TintIconPreference(Context context, AttributeSet attrs) { - super(context, attrs); - } - - private static int getThemeAccentColor(Context context) { - int colorAttr; - if (SDK_INT >= LOLLIPOP) { - colorAttr = android.R.attr.colorAccent; - } else { - //Get colorAccent defined for AppCompat - colorAttr = context.getResources().getIdentifier("colorAccent", "attr", context.getPackageName()); - } - TypedValue outValue = new TypedValue(); - context.getTheme().resolveAttribute(colorAttr, outValue, true); - return outValue.data; - } - - @Override - public void onBindViewHolder(PreferenceViewHolder view) { - super.onBindViewHolder(view); - Drawable icon = getIcon(); - if (icon != null) { - DrawableCompat.setTint(icon, getThemeAccentColor(getContext())); - } - } -} From ed68a9482eecf280811bdb420b8afb787fc66429 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 26 Jul 2020 13:39:51 +0200 Subject: [PATCH 05/51] Add initial basic provisioning service --- play-services-core/build.gradle | 3 +- .../src/main/AndroidManifest.xml | 12 +++++ .../org/microg/gms/checkin/CheckinPrefs.java | 8 ++++ .../java/org/microg/gms/gcm/GcmPrefs.java | 10 ++++ .../microg/gms/provision/ProvisionService.kt | 46 +++++++++++++++++++ .../gms/ui/DeviceRegistrationFragment.kt | 5 +- .../microg/gms/ui/PushNotificationFragment.kt | 7 +-- .../src/main/res/values/strings.xml | 2 + 8 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/provision/ProvisionService.kt diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle index 8ee555cb..bc3d697a 100644 --- a/play-services-core/build.gradle +++ b/play-services-core/build.gradle @@ -61,6 +61,7 @@ dependencies { implementation "androidx.navigation:navigation-fragment-ktx:$navigationVersion" implementation "androidx.navigation:navigation-ui-ktx:$navigationVersion" + implementation "androidx.lifecycle:lifecycle-service:$lifecycleVersion" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" } @@ -75,8 +76,6 @@ android { minSdkVersion androidMinSdk targetSdkVersion androidTargetSdk -// buildConfigField "boolean", "USE_MAPBOX", "${useMapbox()}" - multiDexEnabled true ndk { diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml index 6b58afd7..74fbd245 100644 --- a/play-services-core/src/main/AndroidManifest.xml +++ b/play-services-core/src/main/AndroidManifest.xml @@ -64,6 +64,11 @@ android:name="org.microg.gms.EXTENDED_ACCESS" android:label="@string/perm_extended_access_label" android:protectionLevel="dangerous" /> + @@ -112,6 +117,13 @@ android:name="fake-signature" android:value="@string/fake_signature" /> + + + + diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java index d18914b6..f090c97e 100644 --- a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java @@ -6,6 +6,7 @@ package org.microg.gms.checkin; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; @@ -44,4 +45,11 @@ public class CheckinPrefs implements SharedPreferences.OnSharedPreferenceChangeL public boolean isEnabled() { return checkinEnabled; } + + public static void setEnabled(Context context, boolean newStatus) { + PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(PREF_ENABLE_CHECKIN, newStatus).commit(); + if (newStatus) { + context.sendOrderedBroadcast(new Intent(context, TriggerReceiver.class), null); + } + } } diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java b/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java index 30a95703..e4051f47 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java @@ -17,6 +17,7 @@ package org.microg.gms.gcm; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -197,6 +198,15 @@ public class GcmPrefs implements SharedPreferences.OnSharedPreferenceChangeListe return isEnabled() && info != null && getHeartbeatMsFor(info) >= 0; } + public static void setEnabled(Context context, boolean newStatus) { + PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(GcmPrefs.PREF_ENABLE_GCM, newStatus).commit(); + if (!newStatus) { + McsService.stop(context); + } else { + context.sendBroadcast(new Intent(TriggerReceiver.FORCE_TRY_RECONNECT, null, context, TriggerReceiver.class)); + } + } + public boolean isGcmLogEnabled() { return gcmLogEnabled; } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/provision/ProvisionService.kt b/play-services-core/src/main/kotlin/org/microg/gms/provision/ProvisionService.kt new file mode 100644 index 00000000..9cfd43c1 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/provision/ProvisionService.kt @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.provision + +import android.app.Service +import android.content.Intent +import android.os.Bundle +import android.util.Log +import androidx.lifecycle.LifecycleService +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.delay +import org.microg.gms.checkin.CheckinPrefs +import org.microg.gms.gcm.GcmPrefs +import org.microg.gms.snet.SafetyNetPrefs + +class ProvisionService : LifecycleService() { + private fun Bundle.getBooleanOrNull(key: String): Boolean? { + return if (containsKey(key)) getBoolean(key) else null + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + super.onStartCommand(intent, flags, startId) + lifecycleScope.launchWhenStarted { + intent?.extras?.let { + val s = it.keySet().map { key -> "$key = ${it[key]}" }.joinToString(", ") + Log.d(TAG, "Provisioning: $s") + } + + intent?.extras?.getBooleanOrNull("checkin_enabled")?.let { CheckinPrefs.setEnabled(this@ProvisionService, it) } + intent?.extras?.getBooleanOrNull("gcm_enabled")?.let { GcmPrefs.setEnabled(this@ProvisionService, it) } + intent?.extras?.getBooleanOrNull("safetynet_enabled")?.let { SafetyNetPrefs.get(this@ProvisionService).isEnabled = it } + // What else? + + delay(2 * 1000) // Wait 2 seconds to give provisioning some extra time + stopSelfResult(startId) + } + return Service.START_NOT_STICKY + } + + companion object { + private const val TAG = "GmsProvision" + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt index 68f30f72..721774f0 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt @@ -26,10 +26,7 @@ class DeviceRegistrationFragment : Fragment(R.layout.device_registration_fragmen binding = DeviceRegistrationFragmentBinding.inflate(inflater, container, false) binding.switchBarCallback = object : PreferenceSwitchBarCallback { override fun onChecked(newStatus: Boolean) { - PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(PREF_ENABLE_CHECKIN, newStatus).commit() - if (newStatus) { - requireContext().sendOrderedBroadcast(Intent(requireContext(), TriggerReceiver::class.java), null) - } + CheckinPrefs.setEnabled(context, newStatus) binding.checkinEnabled = newStatus } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt index fcdc6965..ad699e22 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt @@ -25,12 +25,7 @@ class PushNotificationFragment : Fragment(R.layout.push_notification_fragment) { binding = PushNotificationFragmentBinding.inflate(inflater, container, false) binding.switchBarCallback = object : PreferenceSwitchBarCallback { override fun onChecked(newStatus: Boolean) { - PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(GcmPrefs.PREF_ENABLE_GCM, newStatus).apply() - if (!newStatus) { - McsService.stop(context) - } else { - requireContext().sendBroadcast(Intent(TriggerReceiver.FORCE_TRY_RECONNECT, null, context, TriggerReceiver::class.java)) - } + GcmPrefs.setEnabled(context, newStatus) binding.gcmEnabled = newStatus } } diff --git a/play-services-core/src/main/res/values/strings.xml b/play-services-core/src/main/res/values/strings.xml index cfc7fd85..faafbdc0 100644 --- a/play-services-core/src/main/res/values/strings.xml +++ b/play-services-core/src/main/res/values/strings.xml @@ -52,6 +52,8 @@ This can take a couple of minutes." send C2DM messages to other apps exchange messages and receive sync notifications from Google servers Extended access to Google services + provision microG services + Allows the app to configure microG services without user interaction Google device registration Google Cloud Messaging From 94de371cb936bb5f8547fcf117586bc9611e102a Mon Sep 17 00:00:00 2001 From: Alexandru Chircu Date: Wed, 1 Jan 2020 14:32:56 +0200 Subject: [PATCH 06/51] Implement API for AppInvite and Firebase Dynamic Links --- firebase-dynamic-links-api/build.gradle | 49 ++++++++++++++++ firebase-dynamic-links-api/gradle.properties | 34 +++++++++++ .../src/main/AndroidManifest.xml | 18 ++++++ .../internal/DynamicLinkData.aidl | 3 + .../internal/IDynamicLinksCallbacks.aidl | 12 ++++ .../internal/IDynamicLinksService.aidl | 12 ++++ .../internal/ShortDynamicLink.aidl | 3 + .../dynamiclinks/internal/Warning.aidl | 3 + .../internal/DynamicLinkData.java | 57 +++++++++++++++++++ .../internal/ShortDynamicLink.java | 50 ++++++++++++++++ .../dynamiclinks/internal/Warning.java | 38 +++++++++++++ play-services-appinvite-api/build.gradle | 49 ++++++++++++++++ play-services-appinvite-api/gradle.properties | 34 +++++++++++ .../src/main/AndroidManifest.xml | 18 ++++++ .../internal/IAppInviteCallbacks.aidl | 11 ++++ .../appinvite/internal/IAppInviteService.aidl | 14 +++++ .../org/microg/gms/common/GmsService.java | 4 +- settings.gradle | 3 + 18 files changed, 411 insertions(+), 1 deletion(-) create mode 100644 firebase-dynamic-links-api/build.gradle create mode 100644 firebase-dynamic-links-api/gradle.properties create mode 100644 firebase-dynamic-links-api/src/main/AndroidManifest.xml create mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/DynamicLinkData.aidl create mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksCallbacks.aidl create mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksService.aidl create mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.aidl create mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/Warning.aidl create mode 100644 firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/DynamicLinkData.java create mode 100644 firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.java create mode 100644 firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/Warning.java create mode 100644 play-services-appinvite-api/build.gradle create mode 100644 play-services-appinvite-api/gradle.properties create mode 100644 play-services-appinvite-api/src/main/AndroidManifest.xml create mode 100644 play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteCallbacks.aidl create mode 100644 play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteService.aidl diff --git a/firebase-dynamic-links-api/build.gradle b/firebase-dynamic-links-api/build.gradle new file mode 100644 index 00000000..32edbc9b --- /dev/null +++ b/firebase-dynamic-links-api/build.gradle @@ -0,0 +1,49 @@ +/* + * Copyright 2019 e Foundation + * + * 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 + * + * http://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. + */ + +apply plugin: 'com.android.library' + +String getMyVersionName() { + def stdout = new ByteArrayOutputStream() + if (rootProject.file("gradlew").exists()) + exec { commandLine 'git', 'describe', '--tags', '--always', '--dirty'; standardOutput = stdout } + else // automatic build system, don't tag dirty + exec { commandLine 'git', 'describe', '--tags', '--always'; standardOutput = stdout } + return stdout.toString().trim().substring(1) +} + +group = 'org.microg' +version = getMyVersionName() + +android { + compileSdkVersion androidCompileSdk() + buildToolsVersion "$androidBuildVersionTools" + + defaultConfig { + versionName getMyVersionName() + minSdkVersion androidMinSdk() + targetSdkVersion androidTargetSdk() + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + api project(':play-services-basement') +} diff --git a/firebase-dynamic-links-api/gradle.properties b/firebase-dynamic-links-api/gradle.properties new file mode 100644 index 00000000..c601b6d6 --- /dev/null +++ b/firebase-dynamic-links-api/gradle.properties @@ -0,0 +1,34 @@ +# +# Copyright 2019 e Foundation +# +# 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 +# +# http://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. +# + +POM_NAME=Firebase Dynamic Links API +POM_DESCRIPTION=Interfaces and objects for IPC between Firebase Library and microG + +POM_PACKAGING=aar + +POM_URL=https://github.com/microg/android_external_GmsApi + +POM_SCM_URL=https://github.com/microg/android_external_GmsApi +POM_SCM_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git +POM_SCM_DEV_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git + +POM_LICENCE_NAME=The Apache Software License, Version 2.0 +POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt +POM_LICENCE_DIST=repo + +POM_DEVELOPER_ID=alexandruchircu +POM_DEVELOPER_NAME=Alexandru Chircu + diff --git a/firebase-dynamic-links-api/src/main/AndroidManifest.xml b/firebase-dynamic-links-api/src/main/AndroidManifest.xml new file mode 100644 index 00000000..ae17555c --- /dev/null +++ b/firebase-dynamic-links-api/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/DynamicLinkData.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/DynamicLinkData.aidl new file mode 100644 index 00000000..5862178a --- /dev/null +++ b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/DynamicLinkData.aidl @@ -0,0 +1,3 @@ +package com.google.firebase.dynamiclinks.internal; + +parcelable DynamicLinkData; \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksCallbacks.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksCallbacks.aidl new file mode 100644 index 00000000..9f9915ff --- /dev/null +++ b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksCallbacks.aidl @@ -0,0 +1,12 @@ +package com.google.firebase.dynamiclinks.internal; + + +import com.google.firebase.dynamiclinks.internal.DynamicLinkData; +import com.google.firebase.dynamiclinks.internal.ShortDynamicLink; + +import com.google.android.gms.common.api.Status; + +interface IDynamicLinksCallbacks { + void onStatusDynamicLinkData(in Status status, in DynamicLinkData dldata) = 0; + void onStatusShortDynamicLink(in Status status, in ShortDynamicLink sdlink) = 1; +} diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksService.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksService.aidl new file mode 100644 index 00000000..57f083f5 --- /dev/null +++ b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksService.aidl @@ -0,0 +1,12 @@ +package com.google.firebase.dynamiclinks.internal; + + +import com.google.firebase.dynamiclinks.internal.IDynamicLinksCallbacks; + +import android.os.Bundle; + + +interface IDynamicLinksService { + void getInitialLink(IDynamicLinksCallbacks callback, String var2) = 0; + void func2(IDynamicLinksCallbacks callback, in Bundle var2) = 1; +} diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.aidl new file mode 100644 index 00000000..f4852a03 --- /dev/null +++ b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.aidl @@ -0,0 +1,3 @@ +package com.google.firebase.dynamiclinks.internal; + +parcelable ShortDynamicLink; \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/Warning.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/Warning.aidl new file mode 100644 index 00000000..4331c92a --- /dev/null +++ b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/Warning.aidl @@ -0,0 +1,3 @@ +package com.google.firebase.dynamiclinks.internal; + +parcelable Warning; \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/DynamicLinkData.java b/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/DynamicLinkData.java new file mode 100644 index 00000000..02270cd1 --- /dev/null +++ b/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/DynamicLinkData.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2019 e Foundation + * + * 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 + * + * http://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. + */ + +package com.google.firebase.dynamiclinks.internal; + + +import org.microg.safeparcel.AutoSafeParcelable; +import org.microg.safeparcel.SafeParceled; + +import android.os.Bundle; +import android.net.Uri; + + +public class DynamicLinkData extends AutoSafeParcelable { + @SafeParceled(1) + public final String dynamicLink; + + @SafeParceled(2) + public final String deepLink; + + @SafeParceled(3) + public final int minVersion; + + @SafeParceled(4) + public final long clickTimestamp; + + @SafeParceled(5) + public final Bundle extensionBundle; + + @SafeParceled(6) + public final Uri redirectUrl; + + public DynamicLinkData() { + dynamicLink = new String(); + deepLink = new String(); + minVersion = 0; + clickTimestamp = 0; + extensionBundle = new Bundle(); + redirectUrl = Uri.EMPTY; + } + + + public static final Creator CREATOR = new AutoCreator(DynamicLinkData.class); +} \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.java b/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.java new file mode 100644 index 00000000..893e4098 --- /dev/null +++ b/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2019 e Foundation + * + * 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 + * + * http://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. + */ + +package com.google.firebase.dynamiclinks.internal; + + +import com.google.firebase.dynamiclinks.internal.Warning; + +import org.microg.safeparcel.AutoSafeParcelable; +import org.microg.safeparcel.SafeParceled; + +import android.net.Uri; +import java.util.List; +import java.util.ArrayList; + + +public class ShortDynamicLink extends AutoSafeParcelable { + @SafeParceled(1) + public final Uri shortLink; + + @SafeParceled(2) + public final Uri previewLink; + + @SafeParceled(3) + public final List warnings; + + + public ShortDynamicLink() { + shortLink = Uri.EMPTY; + previewLink = Uri.EMPTY; + + warnings = new ArrayList<>(); + } + + + public static final Creator CREATOR = new AutoCreator(ShortDynamicLink.class); +} \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/Warning.java b/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/Warning.java new file mode 100644 index 00000000..950f3de7 --- /dev/null +++ b/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/Warning.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2019 e Foundation + * + * 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 + * + * http://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. + */ + +package com.google.firebase.dynamiclinks.internal; + + +import org.microg.safeparcel.AutoSafeParcelable; +import org.microg.safeparcel.SafeParceled; + + +public class Warning extends AutoSafeParcelable { + @SafeParceled(1) + private int versionCode = 1; + + @SafeParceled(2) + public final String message; + + + public Warning() { + message = null; + } + + + public static final Creator CREATOR = new AutoCreator(Warning.class); +} \ No newline at end of file diff --git a/play-services-appinvite-api/build.gradle b/play-services-appinvite-api/build.gradle new file mode 100644 index 00000000..32edbc9b --- /dev/null +++ b/play-services-appinvite-api/build.gradle @@ -0,0 +1,49 @@ +/* + * Copyright 2019 e Foundation + * + * 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 + * + * http://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. + */ + +apply plugin: 'com.android.library' + +String getMyVersionName() { + def stdout = new ByteArrayOutputStream() + if (rootProject.file("gradlew").exists()) + exec { commandLine 'git', 'describe', '--tags', '--always', '--dirty'; standardOutput = stdout } + else // automatic build system, don't tag dirty + exec { commandLine 'git', 'describe', '--tags', '--always'; standardOutput = stdout } + return stdout.toString().trim().substring(1) +} + +group = 'org.microg' +version = getMyVersionName() + +android { + compileSdkVersion androidCompileSdk() + buildToolsVersion "$androidBuildVersionTools" + + defaultConfig { + versionName getMyVersionName() + minSdkVersion androidMinSdk() + targetSdkVersion androidTargetSdk() + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + api project(':play-services-basement') +} diff --git a/play-services-appinvite-api/gradle.properties b/play-services-appinvite-api/gradle.properties new file mode 100644 index 00000000..7215aee4 --- /dev/null +++ b/play-services-appinvite-api/gradle.properties @@ -0,0 +1,34 @@ +# +# Copyright 2019 e Foundation +# +# 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 +# +# http://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. +# + +POM_NAME=Play Services Internal AppInvite API +POM_DESCRIPTION=Interfaces and objects for IPC between Play Services Library and Play Services Core + +POM_PACKAGING=aar + +POM_URL=https://github.com/microg/android_external_GmsApi + +POM_SCM_URL=https://github.com/microg/android_external_GmsApi +POM_SCM_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git +POM_SCM_DEV_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git + +POM_LICENCE_NAME=The Apache Software License, Version 2.0 +POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt +POM_LICENCE_DIST=repo + +POM_DEVELOPER_ID=alexandruchircu +POM_DEVELOPER_NAME=Alexandru Chircu + diff --git a/play-services-appinvite-api/src/main/AndroidManifest.xml b/play-services-appinvite-api/src/main/AndroidManifest.xml new file mode 100644 index 00000000..da7741f9 --- /dev/null +++ b/play-services-appinvite-api/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + diff --git a/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteCallbacks.aidl b/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteCallbacks.aidl new file mode 100644 index 00000000..66c64d7e --- /dev/null +++ b/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteCallbacks.aidl @@ -0,0 +1,11 @@ +package com.google.android.gms.appinvite.internal; + + +import com.google.android.gms.common.api.Status; +import android.content.Intent; + + +interface IAppInviteCallbacks { + void onStatus(in Status status) = 0; + void onStatusIntent(in Status status, in Intent intent) = 1; +} diff --git a/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteService.aidl b/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteService.aidl new file mode 100644 index 00000000..630edd43 --- /dev/null +++ b/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteService.aidl @@ -0,0 +1,14 @@ +package com.google.android.gms.appinvite.internal; + + +import com.google.android.gms.appinvite.internal.IAppInviteCallbacks; + +import com.google.android.gms.dynamic.IObjectWrapper; +import com.google.android.gms.common.api.Status; + + +interface IAppInviteService { + void updateInvitationOnInstall(IAppInviteCallbacks callback, String invitationId) = 0; + void convertInvitation(IAppInviteCallbacks callback, String invitationId) = 1; + void getInvitation(IAppInviteCallbacks callback) = 2; +} diff --git a/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java b/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java index 73f32940..fd6141ce 100644 --- a/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java +++ b/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java @@ -88,6 +88,7 @@ public enum GmsService { PLUS_INTERNAL(70), SOURCE_DEVICE(75, "com.google.android.gms.smartdevice.d2d.SourceDeviceService.START"), TARGET_DEVICE(76, "com.google.android.gms.smartdevice.d2d.TargetDeviceService.START"), + APP_INVITE(77, "com.google.android.gms.appinvite.service.START"), TAP_AND_PAY(79, "com.google.android.gms.tapandpay.service.BIND"), ACCOUNTS(81, "com.google.android.gms.smartdevice.setup.accounts.AccountsService.START"), TRUST_AGENT(85, "com.google.android.gms.trustagent.StateApi.START"), @@ -98,7 +99,8 @@ public enum GmsService { GASS(116, "com.google.android.gms.gass.START"), WORK_ACCOUNT(120), AD_CACHE(123, "com.google.android.gms.ads.service.CACHE"), - NEARBY_EXPOSURE(236, "com.google.android.gms.nearby.exposurenotification.START") + DYNAMIC_LINKS(131, "com.google.firebase.dynamiclinks.service.START"), + NEARBY_EXPOSURE(236, "com.google.android.gms.nearby.exposurenotification.START"), ; public int SERVICE_ID; diff --git a/settings.gradle b/settings.gradle index 09762221..95774e5a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,6 +4,7 @@ include ':play-services-basement' include ':play-services-tasks' +include ':play-services-appinvite-api' include ':play-services-base-api' include ':play-services-cast-api' include ':play-services-cast-framework-api' @@ -14,6 +15,8 @@ include ':play-services-wearable-api' include ':play-services-api' +include ':firebase-dynamic-links-api' + include ':play-services-base-core' include ':play-services-location-core' include ':play-services-maps-core-mapbox' From 7bc61ab97fe8c4bbfc8ab8f2a11440692582f22c Mon Sep 17 00:00:00 2001 From: Alexandru Chircu Date: Wed, 1 Jan 2020 14:50:56 +0200 Subject: [PATCH 07/51] Implement AppInvite and Firebase Dynamic Links --- play-services-api/build.gradle | 1 + play-services-core/build.gradle | 1 + .../src/main/AndroidManifest.xml | 12 ++++ .../gms/appinvite/AppInviteService.java | 49 +++++++++++++ .../gms/appinvite/AppInviteServiceImpl.java | 68 +++++++++++++++++++ .../dynamiclinks/DynamicLinksService.java | 49 +++++++++++++ .../dynamiclinks/DynamicLinksServiceImpl.java | 64 +++++++++++++++++ 7 files changed, 244 insertions(+) create mode 100644 play-services-core/src/main/java/org/microg/gms/appinvite/AppInviteService.java create mode 100644 play-services-core/src/main/java/org/microg/gms/appinvite/AppInviteServiceImpl.java create mode 100644 play-services-core/src/main/java/org/microg/gms/firebase/dynamiclinks/DynamicLinksService.java create mode 100644 play-services-core/src/main/java/org/microg/gms/firebase/dynamiclinks/DynamicLinksServiceImpl.java diff --git a/play-services-api/build.gradle b/play-services-api/build.gradle index 44c2d884..259c6337 100644 --- a/play-services-api/build.gradle +++ b/play-services-api/build.gradle @@ -34,6 +34,7 @@ android { dependencies { api project(':play-services-basement') + api project(':play-services-appinvite-api') api project(':play-services-cast-api') api project(':play-services-cast-framework-api') api project(':play-services-iid-api') diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle index bc3d697a..2c446d07 100644 --- a/play-services-core/build.gradle +++ b/play-services-core/build.gradle @@ -37,6 +37,7 @@ dependencies { api "org.slf4j:slf4j-api:1.7.25" api "uk.uuid.slf4j:slf4j-android:1.7.25-1" + implementation project(':firebase-dynamic-links-api') implementation project(':play-services-base-core') implementation project(':play-services-location-core') implementation project(':play-services-core:microg-ui-tools') // deprecated diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml index 74fbd245..ef0b723c 100644 --- a/play-services-core/src/main/AndroidManifest.xml +++ b/play-services-core/src/main/AndroidManifest.xml @@ -622,6 +622,18 @@ + + + + + + + + + + + + diff --git a/play-services-core/src/main/java/org/microg/gms/appinvite/AppInviteService.java b/play-services-core/src/main/java/org/microg/gms/appinvite/AppInviteService.java new file mode 100644 index 00000000..8270f78a --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/appinvite/AppInviteService.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2019 e Foundation + * + * 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 + * + * http://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. + */ + +package org.microg.gms.appinvite; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; +import android.os.RemoteException; + +import com.google.android.gms.common.api.CommonStatusCodes; +import com.google.android.gms.common.internal.GetServiceRequest; +import com.google.android.gms.common.internal.IGmsCallbacks; + +import org.microg.gms.BaseService; +import org.microg.gms.common.GmsService; +import org.microg.gms.common.PackageUtils; + +import org.microg.gms.appinvite.AppInviteServiceImpl; + +public class AppInviteService extends BaseService { + private static final String TAG = "GmsAppInviteService"; + + public AppInviteService() { + super("GmsAppInviteSvc", GmsService.APP_INVITE); + } + + @Override + public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException { + PackageUtils.getAndCheckCallingPackage(this, request.packageName); + Log.d(TAG, "callb: " + callback + " ; req: " + request + " ; serv: " + service); + + callback.onPostInitComplete(0, new AppInviteServiceImpl(this, request.packageName, request.extras), null); + } +} diff --git a/play-services-core/src/main/java/org/microg/gms/appinvite/AppInviteServiceImpl.java b/play-services-core/src/main/java/org/microg/gms/appinvite/AppInviteServiceImpl.java new file mode 100644 index 00000000..e3bfe6d3 --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/appinvite/AppInviteServiceImpl.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2019 e Foundation + * + * 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 + * + * http://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. + */ + +package org.microg.gms.appinvite; + +import android.os.Parcel; +import android.os.RemoteException; +import android.os.Bundle; +import android.app.Activity; +import android.util.Log; +import android.content.Context; +import android.content.Intent; + +import com.google.android.gms.common.api.Status; + +import com.google.android.gms.dynamic.IObjectWrapper; +import com.google.android.gms.dynamic.ObjectWrapper; + +import com.google.android.gms.appinvite.internal.IAppInviteService; +import com.google.android.gms.appinvite.internal.IAppInviteCallbacks; + + +public class AppInviteServiceImpl extends IAppInviteService.Stub { + private static final String TAG = "GmsAppInviteServImpl"; + + public AppInviteServiceImpl(Context context, String packageName, Bundle extras) { + } + + + @Override + public void updateInvitationOnInstall(IAppInviteCallbacks callback, String invitationId) throws RemoteException { + callback.onStatus(Status.SUCCESS); + } + + @Override + public void convertInvitation(IAppInviteCallbacks callback, String invitationId) throws RemoteException { + callback.onStatus(Status.SUCCESS); + } + + @Override + public void getInvitation(IAppInviteCallbacks callback) throws RemoteException { + callback.onStatusIntent(new Status(Activity.RESULT_CANCELED), null); + } + + + @Override + public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { + if (super.onTransact(code, data, reply, flags)) { + return true; + } + + Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags); + return false; + } +} diff --git a/play-services-core/src/main/java/org/microg/gms/firebase/dynamiclinks/DynamicLinksService.java b/play-services-core/src/main/java/org/microg/gms/firebase/dynamiclinks/DynamicLinksService.java new file mode 100644 index 00000000..064d7ead --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/firebase/dynamiclinks/DynamicLinksService.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2019 e Foundation + * + * 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 + * + * http://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. + */ + +package org.microg.gms.firebase.dynamiclinks; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; +import android.os.RemoteException; + +import com.google.android.gms.common.api.CommonStatusCodes; +import com.google.android.gms.common.internal.GetServiceRequest; +import com.google.android.gms.common.internal.IGmsCallbacks; + +import org.microg.gms.BaseService; +import org.microg.gms.common.GmsService; +import org.microg.gms.common.PackageUtils; + +import org.microg.gms.firebase.dynamiclinks.DynamicLinksServiceImpl; + +public class DynamicLinksService extends BaseService { + private static final String TAG = "GmsDynamicLinksService"; + + public DynamicLinksService() { + super("GmsDynamicLinksSvc", GmsService.DYNAMIC_LINKS); + } + + @Override + public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException { + PackageUtils.getAndCheckCallingPackage(this, request.packageName); + Log.d(TAG, "callb: " + callback + " ; req: " + request + " ; serv: " + service); + + callback.onPostInitComplete(0, new DynamicLinksServiceImpl(this, request.packageName, request.extras), null); + } +} diff --git a/play-services-core/src/main/java/org/microg/gms/firebase/dynamiclinks/DynamicLinksServiceImpl.java b/play-services-core/src/main/java/org/microg/gms/firebase/dynamiclinks/DynamicLinksServiceImpl.java new file mode 100644 index 00000000..a9f970b5 --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/firebase/dynamiclinks/DynamicLinksServiceImpl.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 e Foundation + * + * 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 + * + * http://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. + */ + +package org.microg.gms.firebase.dynamiclinks; + +import android.os.Parcel; +import android.os.RemoteException; +import android.os.Bundle; +import android.util.Log; +import android.content.Context; +import android.content.Intent; + +import com.google.android.gms.common.api.Status; +import com.google.android.gms.common.api.CommonStatusCodes; + +import com.google.firebase.dynamiclinks.internal.IDynamicLinksService; +import com.google.firebase.dynamiclinks.internal.IDynamicLinksCallbacks; +import com.google.firebase.dynamiclinks.internal.DynamicLinkData; +import com.google.firebase.dynamiclinks.internal.ShortDynamicLink; + + +public class DynamicLinksServiceImpl extends IDynamicLinksService.Stub { + private static final String TAG = "GmsDynamicLinksServImpl"; + + public DynamicLinksServiceImpl(Context context, String packageName, Bundle extras) { + } + + + @Override + public void getInitialLink(IDynamicLinksCallbacks callback, String var2) throws RemoteException { + callback.onStatusDynamicLinkData(Status.SUCCESS, new DynamicLinkData()); + } + + + @Override + public void func2(IDynamicLinksCallbacks callback, Bundle var2) throws RemoteException { + Log.d(TAG, "func2: " + callback + ", " + var2); + callback.onStatusShortDynamicLink(Status.SUCCESS, new ShortDynamicLink()); + } + + + @Override + public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { + if (super.onTransact(code, data, reply, flags)) { + return true; + } + + Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags); + return false; + } +} From f199f902b14f8435e2103c45f99aa8be01f8b070 Mon Sep 17 00:00:00 2001 From: delthas Date: Sun, 19 Jul 2020 18:01:45 +0200 Subject: [PATCH 08/51] Fix GCM heartbeat interval for roaming connections with manual interval When using GCM on a roaming connection, the heartbeat interval is set to: `networkRoaming * 6000`. It should instead be `networkRoaming * 60000` because we're converting from a number of minutes (stored in the properties) to a number of milliseconds, like it's done for regular mobile and wifi connections. --- .../src/main/java/org/microg/gms/gcm/GcmPrefs.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java b/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java index e4051f47..4bfe71d5 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java @@ -115,7 +115,7 @@ public class GcmPrefs implements SharedPreferences.OnSharedPreferenceChangeListe public int getHeartbeatMsFor(String pref, boolean rawRoaming) { if (PREF_NETWORK_ROAMING.equals(pref) && (rawRoaming || networkRoaming != 0)) { - return networkRoaming * 6000; + return networkRoaming * 60000; } else if (PREF_NETWORK_MOBILE.equals(pref)) { if (networkMobile != 0) return networkMobile * 60000; else return learntMobile; From 74a1b1799c67c4be5c973beb42118927749cbf41 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 26 Jul 2020 21:24:37 +0200 Subject: [PATCH 09/51] Make strings translatable --- .../gms/ui/DeviceRegistrationFragment.kt | 4 ---- .../DeviceRegistrationPreferencesFragment.kt | 4 ++-- .../microg/gms/ui/PushNotificationFragment.kt | 4 ---- .../ui/PushNotificationPreferencesFragment.kt | 4 ++-- .../src/main/res/values-de/strings.xml | 4 ++-- .../src/main/res/values-fr/strings.xml | 4 ++-- .../src/main/res/values-pl/strings.xml | 2 -- .../src/main/res/values-pt-rBR/strings.xml | 6 +++--- .../src/main/res/values-ru/strings.xml | 2 -- .../src/main/res/values-sr/strings.xml | 4 +--- .../src/main/res/values-uk/strings.xml | 2 -- .../src/main/res/values-zh-rTW/strings.xml | 2 -- .../src/main/res/values/strings.xml | 18 ++++++++++++++++-- .../xml/preferences_device_registration.xml | 2 +- .../main/res/xml/preferences_gcm_advanced.xml | 4 ++-- .../res/xml/preferences_push_notifications.xml | 6 +++--- ...preferences_push_notifications_all_apps.xml | 10 +++++----- .../xml/preferences_push_notifications_app.xml | 10 +++++----- 18 files changed, 44 insertions(+), 48 deletions(-) diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt index 721774f0..5cece629 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt @@ -5,19 +5,15 @@ package org.microg.gms.ui -import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope -import androidx.preference.PreferenceManager import com.google.android.gms.R import com.google.android.gms.databinding.DeviceRegistrationFragmentBinding import org.microg.gms.checkin.CheckinPrefs -import org.microg.gms.checkin.CheckinPrefs.PREF_ENABLE_CHECKIN -import org.microg.gms.checkin.TriggerReceiver class DeviceRegistrationFragment : Fragment(R.layout.device_registration_fragment) { private lateinit var binding: DeviceRegistrationFragmentBinding diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt index 9bc63cfe..b1f53234 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt @@ -45,9 +45,9 @@ class DeviceRegistrationPreferencesFragment : PreferenceFragmentCompat() { statusCategory.isVisible = CheckinPrefs.get(context).isEnabled val checkinInfo = LastCheckinInfo.read(requireContext()) status.summary = if (checkinInfo.lastCheckin > 0) { - "Last registration: " + DateUtils.getRelativeTimeSpanString(checkinInfo.lastCheckin, System.currentTimeMillis(), 0) + getString(R.string.checkin_last_registration, DateUtils.getRelativeTimeSpanString(checkinInfo.lastCheckin, System.currentTimeMillis(), 0)) } else { - "Not registered" + getString(R.string.checkin_not_registered) } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt index ad699e22..6345c62b 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt @@ -4,19 +4,15 @@ */ package org.microg.gms.ui -import android.content.Intent import android.os.Bundle import android.view.* import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController -import androidx.preference.* import com.google.android.gms.R import com.google.android.gms.databinding.PushNotificationFragmentBinding import org.microg.gms.checkin.CheckinPrefs import org.microg.gms.gcm.GcmPrefs -import org.microg.gms.gcm.McsService -import org.microg.gms.gcm.TriggerReceiver class PushNotificationFragment : Fragment(R.layout.push_notification_fragment) { lateinit var binding: PushNotificationFragmentBinding diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt index f855ea54..9021ffb5 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt @@ -68,9 +68,9 @@ class PushNotificationPreferencesFragment : PreferenceFragmentCompat() { handler.postDelayed(updateRunnable, UPDATE_INTERVAL) pushStatusCategory.isVisible = GcmPrefs.get(context).isEnabled pushStatus.summary = if (McsService.isConnected()) { - "Connected since: " + DateUtils.getRelativeTimeSpanString(McsService.getStartTimestamp(), System.currentTimeMillis(), 0) + getString(R.string.gcm_network_state_connected, DateUtils.getRelativeTimeSpanString(McsService.getStartTimestamp(), System.currentTimeMillis(), 0)) } else { - "Disconnected" + getString(R.string.gcm_network_state_disconnected) } } diff --git a/play-services-core/src/main/res/values-de/strings.xml b/play-services-core/src/main/res/values-de/strings.xml index c8d74623..07e8db87 100644 --- a/play-services-core/src/main/res/values-de/strings.xml +++ b/play-services-core/src/main/res/values-de/strings.xml @@ -146,8 +146,8 @@ Dies kann einige Minuten dauern." Einige Apps registrieren sich nicht automatisch erneut und haben keine Möglichkeit dies manuell anzustoßen. Diese Apps funktionieren eventuell nach dem abmelden nicht mehr richtig.\nFortsetzen? Du hast einer App die Erlaubnis der Registrierung entzogen, die bereits registriert ist.\nWillst du diese App jetzt auch abmelden damit sie zukünftig keine Push-Nachrichten erhält? Nachrichten: %1$d (%2$d bytes) - Aktueller Zustand: Nicht verbunden - Aktueller Zustand: Verbunden seit %1$s + Nicht verbunden + Verbunden seit %1$s Google SafetyNet ist ein System um Geräte zu zertifizieren und so sicherzustellen, dass sie ausreichend geschützt und kompatibel mit Android sind. Einige Anwendungen benutzen SafetyNet aus Sicherheitsgründen oder um einen Kopierschutz zu erzwingen.\n\nmicroG GmsCore enthält eine freie Implementierung von SafetyNet, jedoch verlangen die Google-Server, dass die Anfragen durch das proprietäre DroidGuard signiert sind. Eine unschädliche gemachte Version von DroidGuard ist als separate "DroidGuard Helper" app verfügbar. diff --git a/play-services-core/src/main/res/values-fr/strings.xml b/play-services-core/src/main/res/values-fr/strings.xml index 3a9d5cf9..6b5471ca 100644 --- a/play-services-core/src/main/res/values-fr/strings.xml +++ b/play-services-core/src/main/res/values-fr/strings.xml @@ -149,8 +149,8 @@ Ceci peut prendre plusieurs minutes." Certaines applications ne se réenregistrent pas et/ou ne fournisse pas de moyens de le faire manuellement. Ces applications peuvent ne plus fonctionner correctement après le désenregistrement.\nContinuer ? Vous avez empêché une application déjà enregistrée de s’enregistrer pour recevoir des notifications push.\nVoulez-vous la désenregistrer maintenant pour qu’elle ne reçoive plus de notifications push à l’avenir ? Messages : %1$d (%2$d octets) - Status actuel : Déconnecté - Status actuel : Connecté depuis %1$s + Déconnecté + Connecté depuis %1$s Google SafetyNet est un système de certification du terminal, assurant que celui-ci est correctement sécurisé et compatible avec Android CTS. Certaines applications utilisent SafetyNet pour des raisons de sécurité ou comme prérequis anti-altérations.\n\nmicroG GmsCore contient une implantation libre de SafetyNet, mais les serveurs officiels requièrent que les requêtes SafetyNet soient signées par le système propriétaire DroidGuard. Une version mise en « bac-à-sable » de DroidGuard est disponible dans une application séparée « DroidGuard Helper ». diff --git a/play-services-core/src/main/res/values-pl/strings.xml b/play-services-core/src/main/res/values-pl/strings.xml index 05bbeb1f..b9f8a0cc 100644 --- a/play-services-core/src/main/res/values-pl/strings.xml +++ b/play-services-core/src/main/res/values-pl/strings.xml @@ -149,8 +149,6 @@ To zajmie kilka minut. Niektóre aplikacje nie rejestrują się automatycznie ponownie lub nie posiadają opcji do zrobienia tego ręcznie. Takie aplikacje po wyrejestrowaniu mogą nie działać prawidłowo.\nCzy chcesz kontynuować? Odmówiłeś już zarejestrowanej aplikacji zarejestrować się w usłudze powiadomień ‘push’.\nCzy chcesz ją wyrejestrować, aby nie otrzymywała powiadomień ‘push’ w przyszłości? Wiadomości: %1$d (%2$d bajtów) - Obecny stan: rozłączony - Obecny stan: połączony od %1$s Google SafetyNet jest systemem certyfikacji urządzenia, który upewnia się czy urządzenie jest poprawnie zabezpieczone i kompatybilne z Android CTS. Niektóre aplikacje używają SafetyNet ze względów bezpieczeństwa lub jako przeciwśrodek do modyfikacji.\n\nUsługa microG GmsCore zawiera wolną implementację SafetyNet, ale oficjalny serwer wymaga by SafetyNet był podpisany przez własnościowy system DroidGuard. Specjalna wersja DroidGuard-a jest dostępna do pobrania jako oddzielna aplikacja “DroidGuard Helper” w repozytorium miroG w F-Droid. diff --git a/play-services-core/src/main/res/values-pt-rBR/strings.xml b/play-services-core/src/main/res/values-pt-rBR/strings.xml index 31f62feb..fa0b522a 100644 --- a/play-services-core/src/main/res/values-pt-rBR/strings.xml +++ b/play-services-core/src/main/res/values-pt-rBR/strings.xml @@ -131,7 +131,7 @@ Isso pode demorar alguns minutos." Algumas aplicações não registam automaticamente e/ou não fornecem uma opção para fazê-lo manualmente. Esses aplicativos podem não funcionar corretamente após o cancelamento do registro.\nContinuar? Você negou um app para se registrar para notificações push que já está registrado.\nDeseja cancelar o registo agora para que não receba mensagens de envio no futuro? Mensagens: %1$d (%2$d bytes) - Estado atual: desconectado - Estado atual: Conectado desde %1$s + Desconectado + Conectado desde %1$s - + diff --git a/play-services-core/src/main/res/values-ru/strings.xml b/play-services-core/src/main/res/values-ru/strings.xml index 9cfaecbb..85ce68d5 100644 --- a/play-services-core/src/main/res/values-ru/strings.xml +++ b/play-services-core/src/main/res/values-ru/strings.xml @@ -159,8 +159,6 @@ "Некоторые приложение автоматически не перепривязываются и/или не предоставляют возможности сделать это вручную. Такие приложения могут работать некорректно после отвязки.\nПродолжить?" Вы запретили push-уведомления для приложения, которое уже привязано.\nВы хотите отвязать его сейчас чтобы больше не получать от него push-уведомлений? Уведомлений: %1$d (%2$d bytes) - Текущий статус: Отключен - Текущий статус: Подключен %1$s Google SafetyNet это система сертификации устройства, гарантирующая, что устройство корректно защищено и совместимо с Android CTS. Некоторые приложения используют SafetyNet из соображений безопасности или в качестве предварительной системы защиты от взлома.\n\nmicroG GmsCore содержит свободную реализацию SafetyNet, но официальный сервер требует, чтобы запросы были подписаны с помощью проприетарной системы DroidGuard. Изолированная версия DroidGuard доступна как отдельное приложение "DroidGuard Helper". diff --git a/play-services-core/src/main/res/values-sr/strings.xml b/play-services-core/src/main/res/values-sr/strings.xml index ddec2e46..3a026a49 100644 --- a/play-services-core/src/main/res/values-sr/strings.xml +++ b/play-services-core/src/main/res/values-sr/strings.xml @@ -131,7 +131,5 @@ Неке се апликације не пријављују поново аутоматски и/или не пружају могућност да се то уради ручно. Ове апликације можда неће радити исправно након одјављивања.\nДа наставим? Нисте дозволили апликацији да се пријави на гурана обавештења а која је већ пријављена.\nЖелите ли да је одјавите сада тако да убудуће не прима гурана обавештења? Порука: %1$d (%2$d бајта) - Тренутно стање: неповезан - Тренутно стање: повезан %1$s - + diff --git a/play-services-core/src/main/res/values-uk/strings.xml b/play-services-core/src/main/res/values-uk/strings.xml index 15887c72..1db30562 100644 --- a/play-services-core/src/main/res/values-uk/strings.xml +++ b/play-services-core/src/main/res/values-uk/strings.xml @@ -156,8 +156,6 @@ Деякі додатки автоматично не прив\'язуються або/та не дозволяють зробити це вручну. Такі додатки можуть робити некоректно після відв\'язування.\nПродовжити? Ви заборонили додатку push-повідомлення, який вже був прив\'язаний.\nВи бажаєте відв\'язати його зараз, аби більше не отримувати від нього push-повідомлень? Повідомлень: %1$d (%2$d байт) - Поточний стан: Відключено - Поточний стан: Під\'єднано від %1$s Google SafetyNet це система сертифікації пристрою, яка гарантує, що пристрій коректно захищено та сумісне із Android CTS. Деякі додатки використовують SafetyNet для безпеки або в якості попередньої системи захисту від злому.\n\nmicroG GmsCore містить вільну реалізацію SafetyNet, але офіційний сервер вимагає, аби запити були підписані за допомогою закритої програмної системи DroidGuard. Ізольована версія DroidGuard доступна для встановлення як окремий додаток \"DroidGuard Helper\". diff --git a/play-services-core/src/main/res/values-zh-rTW/strings.xml b/play-services-core/src/main/res/values-zh-rTW/strings.xml index 6f5b5ac6..5f297719 100644 --- a/play-services-core/src/main/res/values-zh-rTW/strings.xml +++ b/play-services-core/src/main/res/values-zh-rTW/strings.xml @@ -137,8 +137,6 @@ 您拒絕了一個已經註冊的程式去註冊接收推送通知。 您是否想取消註冊讓它未來不再收到推送通知? 已接收訊息:%1$d個(%2$d位元組〉 - 現在狀態:未連接 - 現在狀態:自%1$s連接至今 Google SafetyNet是一個確認手機被確實保護和相容於Android CTS的驗證系統。一些程式基於安全因素使用SafetyNet,一些則是以必須通過的形式來防止篡改。 diff --git a/play-services-core/src/main/res/values/strings.xml b/play-services-core/src/main/res/values/strings.xml index faafbdc0..db8e3515 100644 --- a/play-services-core/src/main/res/values/strings.xml +++ b/play-services-core/src/main/res/values/strings.xml @@ -68,6 +68,7 @@ This can take a couple of minutes." Advanced None + See all Google Play Games %1$s would like to use Play Games @@ -137,6 +138,10 @@ This can take a couple of minutes." Registers your device to Google services and creates a unique device identifier. microG strips identifying bits other than your Google account name from registration data. + Not registered + Last registration: %1$s + + Status More Account @@ -165,8 +170,17 @@ This can take a couple of minutes." Some apps do not automatically re-register and/or do not provide an option to do so manually. These apps might not work correctly after unregistering.\nContinue? You denied an app to register for push notifications that is already registered.\nDo you want to unregister it now so it does not receive push messages in the future? Messages: %1$d (%2$d bytes) - Current State: Disconnected - Current State: Connected since %1$s + Disconnected + Connected since %1$s + + Allow registration + Allow the app to register for push notifications. + Start app on push message + Start the app while in background to receive the incoming push messages. + Apps using push notifications + Registered apps + Unregistered apps + Networks to use for push notifications Google SafetyNet is a device certification system, ensuring that the device is properly secured and compatible with Android CTS. Some applications use SafetyNet for security reasons or as a prerequisite for tamper-protection.\n\nmicroG GmsCore contains a free implementation of SafetyNet, but the official server requires SafetyNet requests to be signed using the proprietary DroidGuard system. A sandboxed version of DroidGuard is available as a separate “DroidGuard Helper” app. diff --git a/play-services-core/src/main/res/xml/preferences_device_registration.xml b/play-services-core/src/main/res/xml/preferences_device_registration.xml index 886ec0b7..92c2023f 100644 --- a/play-services-core/src/main/res/xml/preferences_device_registration.xml +++ b/play-services-core/src/main/res/xml/preferences_device_registration.xml @@ -12,7 +12,7 @@ diff --git a/play-services-core/src/main/res/xml/preferences_gcm_advanced.xml b/play-services-core/src/main/res/xml/preferences_gcm_advanced.xml index 449e2d60..bc14d3dd 100644 --- a/play-services-core/src/main/res/xml/preferences_gcm_advanced.xml +++ b/play-services-core/src/main/res/xml/preferences_gcm_advanced.xml @@ -25,7 +25,7 @@ + android:title="@string/prefcat_push_networks_title"> - \ No newline at end of file + diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications.xml b/play-services-core/src/main/res/xml/preferences_push_notifications.xml index 06c8fb8a..e9384ea5 100644 --- a/play-services-core/src/main/res/xml/preferences_push_notifications.xml +++ b/play-services-core/src/main/res/xml/preferences_push_notifications.xml @@ -10,17 +10,17 @@ android:title="Push notifications"> + android:title="@string/prefcat_push_apps_title"> + android:title="@string/list_item_see_all" /> + android:title="@string/prefcat_push_apps_title"> diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml b/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml index fad13b22..907fd211 100644 --- a/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml +++ b/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml @@ -14,15 +14,15 @@ android:defaultValue="true" android:key="pref_push_app_allow_register" android:persistent="false" - android:summary="Allow the app to register for push notifications." - android:title="Allow registration" /> + android:summary="@string/pref_push_app_allow_register_summary" + android:title="@string/pref_push_app_allow_register_title" /> + android:summary="@string/pref_push_app_wake_for_delivery_summary" + android:title="@string/pref_push_app_wake_for_delivery_title" /> @@ -31,7 +31,7 @@ android:layout="@layout/preference_category_no_label"> + android:title="@string/gcm_unregister_app" /> From 322e806548568fe763f2da88e28d5b99c4a47041 Mon Sep 17 00:00:00 2001 From: Pdevo Date: Sun, 26 Jul 2020 22:30:36 +0200 Subject: [PATCH 10/51] Added IT lang files (#1096) --- .../src/main/res/values-it/strings.xml | 44 +++++ .../src/main/res/values-it/permissions.xml | 42 ++++ .../src/main/res/values-it/plurals.xml | 35 ++++ .../src/main/res/values-it/strings.xml | 183 ++++++++++++++++++ 4 files changed, 304 insertions(+) create mode 100644 play-services-core/microg-ui-tools/src/main/res/values-it/strings.xml create mode 100644 play-services-core/src/main/res/values-it/permissions.xml create mode 100644 play-services-core/src/main/res/values-it/plurals.xml create mode 100644 play-services-core/src/main/res/values-it/strings.xml diff --git a/play-services-core/microg-ui-tools/src/main/res/values-it/strings.xml b/play-services-core/microg-ui-tools/src/main/res/values-it/strings.xml new file mode 100644 index 00000000..52e85d46 --- /dev/null +++ b/play-services-core/microg-ui-tools/src/main/res/values-it/strings.xml @@ -0,0 +1,44 @@ + + + + + Strumenti interfaccia utente di microG + Licenza Apache 2.0, team di microG + + Versione %1$s + %1$s %2$s + Tutti i diritti sono riservati. + + Configurazione + + Auto-controllo + Verifica se il sistema è correttamente configurato per utilizzare microG. + + Autorizzazione concessa + Autorizzazione a %1$s: + Tocca qui per concedere l\'autorizzazione a %1$s. Negare l\'autorizzazione può comportare il funzionamento anomalo di altre applicazioni. + + microG UI Demo + Sommario + Versione v0.1.0 + Librerie incluse + + v4 Support Library + v7 appcompat Support Library + v7 preference Support Library + Licenza Apache 2.0, The Android Open Source Project + diff --git a/play-services-core/src/main/res/values-it/permissions.xml b/play-services-core/src/main/res/values-it/permissions.xml new file mode 100644 index 00000000..b2c5d580 --- /dev/null +++ b/play-services-core/src/main/res/values-it/permissions.xml @@ -0,0 +1,42 @@ + + + + + Tutti i servizi Google + Permette alle applicazioni di accedere a tutti i servizi Google mediante l\'account Google. + + Servizi Android + Permette alle applicazioni di accedere ai servizi Android mediante l\'account Google. + Google AdSense + Permette alle applicazioni di accedere a Google AdSense mediante l\'account Google. + Google AdWords + Permette alle applicazioni di accedere a Google AdWords mediante l\'account Google. + Google App Engine + Permette alle applicazioni di accedere a Google App Engine mediante l\'account Google. + Google Blogger + Permette alle applicazioni di accedere a Google Blogger mediante l\'account Google. + Calendario Google + Permette alle applicazioni di accedere al calendario di Google mediante l\'account Google. + Contatti Google + Permette alle applicazioni di accedere ai Contatti Google mediante l\'account Google. + Dodgeball + Permette alle applicazioni di accedere a Dodgeball mediante l\'account Google. + Google Finance + Permette alle applicazioni di accedere a Google Finance mediante l\'account Google. + Google Base + Permette alle applicazioni di accedere a Google base mediante l\'account Google. + diff --git a/play-services-core/src/main/res/values-it/plurals.xml b/play-services-core/src/main/res/values-it/plurals.xml new file mode 100644 index 00000000..413e2a0a --- /dev/null +++ b/play-services-core/src/main/res/values-it/plurals.xml @@ -0,0 +1,35 @@ + + + + + + %1$d fornitore configurato. + %1$d fornitori configurati. + + + %1$d applicazione registrata + %1$d applicazioni registrate + + + Un permesso necessario al corretto funzionamento di microG non è stato concesso. + Più permessi necessari al corretto funzionamento di microG non sono stati concessi. + + + Richiedi il permesso mancante + Richiedi i permessi mancanti + + diff --git a/play-services-core/src/main/res/values-it/strings.xml b/play-services-core/src/main/res/values-it/strings.xml new file mode 100644 index 00000000..bd10550d --- /dev/null +++ b/play-services-core/src/main/res/values-it/strings.xml @@ -0,0 +1,183 @@ + + + + Servizi microG + Impostazioni di microG + Configurazione di microG + + Giusto un secondo… + Google + Continuando autorizzi questa applicazione e Google ad usare le tue informazioni in accordo con i rispettivi termini di servizio e politiche di riservatezza. + %1$s vorrebbe: + %1$s vorrebbe utilizzare: + Gestione dell\'account Google + Ci dispiace… + "Un\'applicazione sul tuo dispositivo sta tentando di accedere all\'account Google. + +Se ciò era intenzionale, utilizzate il pulsante Accedi per collegarti alla pagina di autenticazione di Google, in caso contrario utilizza il pulsante Cancella per tornare all\'applicazione che ha aperto questa finestra di dialogo." + Accedere + "Il tuo dispositivo sta stabilendo la connessione con i server di Google per autenticarti. + +Questa operazione può richiedere alcuni secondi." + "Non disponi di una connessione ad internet. + +Potrebbe trattarsi di un disservizio temporaneo oppure non essere il tuo dispositivo Android fornito di connessione dati. Riprova quando connessi ad una rete cellulare o ad una rete Wi-Fi." + "C\è stato un problema di comunicazione con i server di Google. + +Try again later." + "Il tuo dispositivo sta comunicando con i server di Google per salvare le informazioni sull\'account. + +Questa operazione può richiedere alcuni minuti." + Permetti + Nega + Autenticazione necessaria + %1$s necessita della tua autorizzazione ad accedere all\'account Google. + + Ascolta la trasmissione di stati interni + Ascolta messaggi C2DM + Invia messaggi C2DM ad altre applicazioni + Scambia messaggi e riceve notifiche di sincronizzazione dai server Google + Accesso esteso ai servizi Google + + Registrazione del dispositivo + Messaggistica cloud + SafetyNet + + Disabilitato + Abilitato + Automatico + Manuale + + Impostazioni avanzate + Nessuno + + Google Play Games + %1$s vorrebbe usare Play Games + Per usare Play Games è necessario installare l\'applicazione di Play Games. L\'applicazione può continuare ad essere usata senza Play Games, ma è possibile che funzioni in modo anomalo. + + Seleziona un luogo + Non è ancora possibile selezionare un luogo. + Seleziona questo luogo + Luoghi vicini + (%1$.7f, %2$.7f) + + microG: Il permesso di %1$s è mancante + + Reti mobili + Wi-Fi + Roaming + Altre reti + + + + Supporto alla falsificazione della firma + Pacchetti installati + Sistema + + Il sistema supporta la falsificazione della firma: + La tua ROM non dispone del supporto nativo per la falsificazione della firma. Puoi comunque utilizzare Xposed o altri sistemi per garantire la falsificazione della firma. Consulta la documentazione su quali ROM supportino la falsificazione della firma e su come utlizzare microG sulle ROM che non la supportano. + Il sistema garantisce la falsificazione della firma: + Questo è un indice sintomatico del fatto che la ROM attuale supporta la falsificazione della firma, ma richiede azioni ulteriori per attivarla. Consulta la documentazione su quali operazioni siano necessarie. + Il sistema falsifica la firma: + Consulta la documentazione su quali operazioni siano necessarie. + + Play Services (GmsCore) + Play Store (Phonesky) + Services Framework (GSF) + %1$s installato: + Installa l\'applicazione %1$s oppure un\'altra compatibile. Consulta la documentazione su quali applicazioni siano compatibili. + %1$s ha la firma corretta: + O l\'applicazione %1$s non è compatibile, oppure la falsificazione della firma non è attiva per essa. Consulta la documentazione su quali applicazioni e ROM siano compatibili. + + Ottimizzazioni della batteria ignorate: + Tocca qui per disabilitare le ottimizzazioni della batteria. Non selezionare questa opzione potrebbe comportare il malfunzionamento delle applicazioni. + + + + Informazioni + Componenti + Configurazione + Servizi Google + Servizi di Localizzazione + Modalità operativa + Servizi + Sperimentale + + Ottimizzazioni della batteria abilitate + Hai abilitato il servizio di messaggistica cloud di Google, tuttavia le ottimizzazioni della batteria sono abilitate per microG. Al fine di garantire la ricezione delle notisfiche push, dovresti slezionare l\'opzione per ignorare le ottimizzazioni della batteria. + Ignora ottimizzazioni + Permesso mancante + + Preferenze dell\'account + Informazioni personali e riservatezza + Accesso e sicurezza + + Dai fiducia a Google per i permessi alle applicazioni + Quando disabilitato, viene interpellato l\'utente prima che ogni richiesta di autorizzazione da parte delle applicazioni venga inviata a Google. Alcune applicazioni potrebbero fallire nell\'utilizzare l\'account Google se questa opzione è disabilitata. + Autorizza le applicazioni a visualizzare gli account + Quando abilitata tutte le applicazioni su questo dispositivo saranno in grado di visualizzare gli indirizzi di posta elettronica dell\'account Google senza autorizzazione preventiva. + + Registra il tuo dispositivo ai servizi Google e crea un identificativo univoco. microG estrapola bit di identidicazione piuttosto che il nome dell\'account Google dai dati di registrazione. + + Impostazioni avanzate + + Account + Aggiungi un account Google + Il servizio di messaggistica cloud di Google è un fornitore di notifiche push utilizzato da molte applicazioni di terze parti. Per poterlo utlizzare devi abilitare la registrazione del dispositivo. + Intervallo di aggiornamento del servizio di messaggistica cloud di Google + L\'intervallo temporale, espresso in secondi, utilizzato dal sistema per contattare i serve di Google. Aumentare questo intervallo ridurrà il consumo di batteria, tuttavia potrebbe causare ritardi nella ricezione delle notifiche push.\nDeprecato, verrà rimpiazzato in versioni future. + Applicazioni che utilizzano il servizio di messaggistica cloud di Google + Lista delle applicazioni attualmente registrate al servizio di messaggistica cloud di Google: + Conferma le nuove applicazioni + Interroga l\'utente prima di registrare una nuova applicazione per le notifiche push. + Intervallo di ping: %1$s + + A proposito di microG + Informazioni sulla versione e sulle librerie utilizzate + + Errore durante la de-registrazione + Non più installata + De-registrazione + Non registrata + Nessun messaggio ricevuto fino ad ora + Ultimo messaggio: %1$s + Registrata + Registrata da: %1$s + De-registrazione %1$s? + Alcune applicazioni non rinnovano automaticamente la registrazione e/o non forniscono un\'opzione per farlo manualmente. Queste applicazioni potrebbero non funzionare correttamente a seguito della de-registrazione.\nContinuare? + Hai negato ad una applicazione già registrata di registrarsi alle notifiche push.\nDesideri de-registrarla così che non riceva più notifiche push in futuro? + Messaggi: %1$d (%2$d bytes) + Stato corrente: Disconnesso + Stato corrente: Connesso da %1$s + + SafetyNet di Google è un sistema di certificazione dispositivo che ne garantisce la sicurezza e la compatibilità con Android CTS. Alcune applicazioni utlizzano SafetyNet per ragioni di sicurezza o come prerequisito per la protezione da manomissione.\n\nmicroG contiene una implementazione libera di SafetyNet, tuttavia i server ufficiali richiedono che le richieste SafetyNet siano firmate utilizzando il sistema proprietario DroidGuard. Una versione contenitore di DroidGuard è disponibile come applicazione “DroidGuard Helper”. + + Provare l\'attestazione SafetyNet + + Usa i server ufficiali + Richiede un sistema senza privilegi di superutente e microG DroidGuard Helper installato + Server ufficiale + Usa i server di terzi parti + I server di terze parti potrebbero essere in grado di rispondere alle richieste di SafetyNet senza la firma di DroidGuard + Server di terze parti + URL del server personalizzato + URL completo del server personalizzato rispondente alle richieste di attestazione SafetyNet + Usa certificato auto-firmato + Anziché richiedere un server, firma localmente le risposte SafetyNet utlizzando un certificato auto-firmato. La maggior parte delle applicazioni rifiuteranno l\'uso di risposte auto-firmate. + Certificato auto-firmato + + From 964555691ed6dc71790d4a1b8a3753580039b7b7 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 26 Jul 2020 22:38:34 +0200 Subject: [PATCH 11/51] Adjust IT translations for recent changes --- play-services-core/src/main/res/values-it/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/play-services-core/src/main/res/values-it/strings.xml b/play-services-core/src/main/res/values-it/strings.xml index bd10550d..52676d09 100644 --- a/play-services-core/src/main/res/values-it/strings.xml +++ b/play-services-core/src/main/res/values-it/strings.xml @@ -161,8 +161,8 @@ Questa operazione può richiedere alcuni minuti." Alcune applicazioni non rinnovano automaticamente la registrazione e/o non forniscono un\'opzione per farlo manualmente. Queste applicazioni potrebbero non funzionare correttamente a seguito della de-registrazione.\nContinuare? Hai negato ad una applicazione già registrata di registrarsi alle notifiche push.\nDesideri de-registrarla così che non riceva più notifiche push in futuro? Messaggi: %1$d (%2$d bytes) - Stato corrente: Disconnesso - Stato corrente: Connesso da %1$s + Disconnesso + Connesso da %1$s SafetyNet di Google è un sistema di certificazione dispositivo che ne garantisce la sicurezza e la compatibilità con Android CTS. Alcune applicazioni utlizzano SafetyNet per ragioni di sicurezza o come prerequisito per la protezione da manomissione.\n\nmicroG contiene una implementazione libera di SafetyNet, tuttavia i server ufficiali richiedono che le richieste SafetyNet siano firmate utilizzando il sistema proprietario DroidGuard. Una versione contenitore di DroidGuard è disponibile come applicazione “DroidGuard Helper”. From a69bf58c8f0b1ca0e7bf302f9534c851f6298604 Mon Sep 17 00:00:00 2001 From: X1nto Date: Mon, 27 Jul 2020 13:52:57 +0400 Subject: [PATCH 12/51] some refreshing idk --- play-services-core/proguard-rules.pro | 59 --------------------------- 1 file changed, 59 deletions(-) delete mode 120000 play-services-core/proguard-rules.pro diff --git a/play-services-core/proguard-rules.pro b/play-services-core/proguard-rules.pro deleted file mode 120000 index 851afada..00000000 --- a/play-services-core/proguard-rules.pro +++ /dev/null @@ -1,59 +0,0 @@ -# We're referencing stuff that is unknown to the system -#-libraryjar ../unifiednlp-compat/build/classes/java/main --dontwarn java.awt.** --dontwarn javax.annotation.** - -# External libs --dontwarn okio.** --dontwarn com.squareup.okhttp.** --dontwarn org.oscim.tiling.source.OkHttpEngine --dontwarn org.oscim.tiling.source.OkHttpEngine$OkHttpFactory --dontwarn com.caverock.androidsvg.** --dontwarn org.slf4j.** --dontwarn org.codehaus.jackson.** --dontwarn com.android.location.provider.** - -# Disable ProGuard Notes, they won't help here --dontnote - -# Keep dynamically loaded GMS classes --keep public class com.google.android.gms.common.security.ProviderInstallerImpl { public *; } --keep public class com.google.android.gms.cast.framework.internal.CastDynamiteModuleImpl { public *; } - -# Keep AutoSafeParcelables --keep public class * extends org.microg.safeparcel.AutoSafeParcelable { - @org.microg.safeparcel.SafeParceled *; -} - -# Keep form data --keepclassmembers class * { - @org.microg.gms.common.HttpFormClient$* *; -} - -# Keep our stuff --keep class org.microg** { *; } --keep class com.google.android.gms** { *; } --keep class com.mgoogle** { *; } --keepdirectories org/microg** --keepdirectories com/google/android/gms** --keepdirectories com/mgoogle** - -# Keep asInterface method cause it's accessed from SafeParcel --keepattributes InnerClasses --keepclassmembers interface * extends android.os.IInterface { - public static class *; -} --keep public class * extends android.os.Binder { public static *; } - -# Keep library info --keep class **.BuildConfig { *; } - -# Keep protobuf class builders --keep public class com.squareup.wire.Message --keep public class * extends com.squareup.wire.Message --keep public class * extends com.squareup.wire.Message$Builder { public (...); } - -# Proguard configuration for Jackson 1.x --keepclassmembers class * { - @org.codehaus.jackson.annotate.* *; -} From 9ebbb5c75489f68990be8ef529ce7d333085b4d8 Mon Sep 17 00:00:00 2001 From: X1nto Date: Mon, 27 Jul 2020 13:54:21 +0400 Subject: [PATCH 13/51] added a proguard file --- play-services-core/proguard-rules.pro | 59 +++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 play-services-core/proguard-rules.pro diff --git a/play-services-core/proguard-rules.pro b/play-services-core/proguard-rules.pro new file mode 100644 index 00000000..851afada --- /dev/null +++ b/play-services-core/proguard-rules.pro @@ -0,0 +1,59 @@ +# We're referencing stuff that is unknown to the system +#-libraryjar ../unifiednlp-compat/build/classes/java/main +-dontwarn java.awt.** +-dontwarn javax.annotation.** + +# External libs +-dontwarn okio.** +-dontwarn com.squareup.okhttp.** +-dontwarn org.oscim.tiling.source.OkHttpEngine +-dontwarn org.oscim.tiling.source.OkHttpEngine$OkHttpFactory +-dontwarn com.caverock.androidsvg.** +-dontwarn org.slf4j.** +-dontwarn org.codehaus.jackson.** +-dontwarn com.android.location.provider.** + +# Disable ProGuard Notes, they won't help here +-dontnote + +# Keep dynamically loaded GMS classes +-keep public class com.google.android.gms.common.security.ProviderInstallerImpl { public *; } +-keep public class com.google.android.gms.cast.framework.internal.CastDynamiteModuleImpl { public *; } + +# Keep AutoSafeParcelables +-keep public class * extends org.microg.safeparcel.AutoSafeParcelable { + @org.microg.safeparcel.SafeParceled *; +} + +# Keep form data +-keepclassmembers class * { + @org.microg.gms.common.HttpFormClient$* *; +} + +# Keep our stuff +-keep class org.microg** { *; } +-keep class com.google.android.gms** { *; } +-keep class com.mgoogle** { *; } +-keepdirectories org/microg** +-keepdirectories com/google/android/gms** +-keepdirectories com/mgoogle** + +# Keep asInterface method cause it's accessed from SafeParcel +-keepattributes InnerClasses +-keepclassmembers interface * extends android.os.IInterface { + public static class *; +} +-keep public class * extends android.os.Binder { public static *; } + +# Keep library info +-keep class **.BuildConfig { *; } + +# Keep protobuf class builders +-keep public class com.squareup.wire.Message +-keep public class * extends com.squareup.wire.Message +-keep public class * extends com.squareup.wire.Message$Builder { public (...); } + +# Proguard configuration for Jackson 1.x +-keepclassmembers class * { + @org.codehaus.jackson.annotate.* *; +} From 26e01fcff7fcd0152d63dfe4f559342124ed8742 Mon Sep 17 00:00:00 2001 From: X1nto Date: Mon, 27 Jul 2020 14:25:03 +0400 Subject: [PATCH 14/51] cleanup --- firebase-dynamic-links-api/build.gradle | 49 ---------------- firebase-dynamic-links-api/gradle.properties | 34 ----------- .../src/main/AndroidManifest.xml | 18 ------ .../internal/DynamicLinkData.aidl | 3 - .../internal/IDynamicLinksCallbacks.aidl | 12 ---- .../internal/IDynamicLinksService.aidl | 12 ---- .../internal/ShortDynamicLink.aidl | 3 - .../dynamiclinks/internal/Warning.aidl | 3 - .../internal/DynamicLinkData.java | 57 ------------------- .../internal/ShortDynamicLink.java | 50 ---------------- .../dynamiclinks/internal/Warning.java | 38 ------------- play-services-api/build.gradle | 1 - play-services-appinvite-api/build.gradle | 49 ---------------- play-services-appinvite-api/gradle.properties | 34 ----------- .../src/main/AndroidManifest.xml | 18 ------ .../internal/IAppInviteCallbacks.aidl | 11 ---- .../appinvite/internal/IAppInviteService.aidl | 14 ----- .../gms/location/ActivityRecognition.java | 40 ------------- .../location/FusedLocationProviderClient.java | 42 -------------- .../ActivityRecognitionApiClientBuilder.java | 35 ------------ .../ActivityRecognitionClientImpl.java | 38 ------------- .../google/android/gms/wearable/Wearable.java | 55 ------------------ settings.gradle | 1 + 23 files changed, 1 insertion(+), 616 deletions(-) delete mode 100644 firebase-dynamic-links-api/build.gradle delete mode 100644 firebase-dynamic-links-api/gradle.properties delete mode 100644 firebase-dynamic-links-api/src/main/AndroidManifest.xml delete mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/DynamicLinkData.aidl delete mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksCallbacks.aidl delete mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksService.aidl delete mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.aidl delete mode 100644 firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/Warning.aidl delete mode 100644 firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/DynamicLinkData.java delete mode 100644 firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.java delete mode 100644 firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/Warning.java delete mode 100644 play-services-appinvite-api/build.gradle delete mode 100644 play-services-appinvite-api/gradle.properties delete mode 100644 play-services-appinvite-api/src/main/AndroidManifest.xml delete mode 100644 play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteCallbacks.aidl delete mode 100644 play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteService.aidl delete mode 100644 play-services-location/src/main/java/com/google/android/gms/location/ActivityRecognition.java delete mode 100644 play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderClient.java delete mode 100644 play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiClientBuilder.java delete mode 100644 play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionClientImpl.java delete mode 100644 play-services-wearable/src/main/java/com/google/android/gms/wearable/Wearable.java diff --git a/firebase-dynamic-links-api/build.gradle b/firebase-dynamic-links-api/build.gradle deleted file mode 100644 index 32edbc9b..00000000 --- a/firebase-dynamic-links-api/build.gradle +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2019 e Foundation - * - * 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 - * - * http://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. - */ - -apply plugin: 'com.android.library' - -String getMyVersionName() { - def stdout = new ByteArrayOutputStream() - if (rootProject.file("gradlew").exists()) - exec { commandLine 'git', 'describe', '--tags', '--always', '--dirty'; standardOutput = stdout } - else // automatic build system, don't tag dirty - exec { commandLine 'git', 'describe', '--tags', '--always'; standardOutput = stdout } - return stdout.toString().trim().substring(1) -} - -group = 'org.microg' -version = getMyVersionName() - -android { - compileSdkVersion androidCompileSdk() - buildToolsVersion "$androidBuildVersionTools" - - defaultConfig { - versionName getMyVersionName() - minSdkVersion androidMinSdk() - targetSdkVersion androidTargetSdk() - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } -} - -dependencies { - api project(':play-services-basement') -} diff --git a/firebase-dynamic-links-api/gradle.properties b/firebase-dynamic-links-api/gradle.properties deleted file mode 100644 index c601b6d6..00000000 --- a/firebase-dynamic-links-api/gradle.properties +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright 2019 e Foundation -# -# 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 -# -# http://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. -# - -POM_NAME=Firebase Dynamic Links API -POM_DESCRIPTION=Interfaces and objects for IPC between Firebase Library and microG - -POM_PACKAGING=aar - -POM_URL=https://github.com/microg/android_external_GmsApi - -POM_SCM_URL=https://github.com/microg/android_external_GmsApi -POM_SCM_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git -POM_SCM_DEV_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git - -POM_LICENCE_NAME=The Apache Software License, Version 2.0 -POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt -POM_LICENCE_DIST=repo - -POM_DEVELOPER_ID=alexandruchircu -POM_DEVELOPER_NAME=Alexandru Chircu - diff --git a/firebase-dynamic-links-api/src/main/AndroidManifest.xml b/firebase-dynamic-links-api/src/main/AndroidManifest.xml deleted file mode 100644 index ae17555c..00000000 --- a/firebase-dynamic-links-api/src/main/AndroidManifest.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/DynamicLinkData.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/DynamicLinkData.aidl deleted file mode 100644 index 5862178a..00000000 --- a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/DynamicLinkData.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package com.google.firebase.dynamiclinks.internal; - -parcelable DynamicLinkData; \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksCallbacks.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksCallbacks.aidl deleted file mode 100644 index 9f9915ff..00000000 --- a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksCallbacks.aidl +++ /dev/null @@ -1,12 +0,0 @@ -package com.google.firebase.dynamiclinks.internal; - - -import com.google.firebase.dynamiclinks.internal.DynamicLinkData; -import com.google.firebase.dynamiclinks.internal.ShortDynamicLink; - -import com.google.android.gms.common.api.Status; - -interface IDynamicLinksCallbacks { - void onStatusDynamicLinkData(in Status status, in DynamicLinkData dldata) = 0; - void onStatusShortDynamicLink(in Status status, in ShortDynamicLink sdlink) = 1; -} diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksService.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksService.aidl deleted file mode 100644 index 57f083f5..00000000 --- a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/IDynamicLinksService.aidl +++ /dev/null @@ -1,12 +0,0 @@ -package com.google.firebase.dynamiclinks.internal; - - -import com.google.firebase.dynamiclinks.internal.IDynamicLinksCallbacks; - -import android.os.Bundle; - - -interface IDynamicLinksService { - void getInitialLink(IDynamicLinksCallbacks callback, String var2) = 0; - void func2(IDynamicLinksCallbacks callback, in Bundle var2) = 1; -} diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.aidl deleted file mode 100644 index f4852a03..00000000 --- a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package com.google.firebase.dynamiclinks.internal; - -parcelable ShortDynamicLink; \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/Warning.aidl b/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/Warning.aidl deleted file mode 100644 index 4331c92a..00000000 --- a/firebase-dynamic-links-api/src/main/aidl/com/google/firebase/dynamiclinks/internal/Warning.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package com.google.firebase.dynamiclinks.internal; - -parcelable Warning; \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/DynamicLinkData.java b/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/DynamicLinkData.java deleted file mode 100644 index 02270cd1..00000000 --- a/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/DynamicLinkData.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2019 e Foundation - * - * 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 - * - * http://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. - */ - -package com.google.firebase.dynamiclinks.internal; - - -import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; - -import android.os.Bundle; -import android.net.Uri; - - -public class DynamicLinkData extends AutoSafeParcelable { - @SafeParceled(1) - public final String dynamicLink; - - @SafeParceled(2) - public final String deepLink; - - @SafeParceled(3) - public final int minVersion; - - @SafeParceled(4) - public final long clickTimestamp; - - @SafeParceled(5) - public final Bundle extensionBundle; - - @SafeParceled(6) - public final Uri redirectUrl; - - public DynamicLinkData() { - dynamicLink = new String(); - deepLink = new String(); - minVersion = 0; - clickTimestamp = 0; - extensionBundle = new Bundle(); - redirectUrl = Uri.EMPTY; - } - - - public static final Creator CREATOR = new AutoCreator(DynamicLinkData.class); -} \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.java b/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.java deleted file mode 100644 index 893e4098..00000000 --- a/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/ShortDynamicLink.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2019 e Foundation - * - * 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 - * - * http://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. - */ - -package com.google.firebase.dynamiclinks.internal; - - -import com.google.firebase.dynamiclinks.internal.Warning; - -import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; - -import android.net.Uri; -import java.util.List; -import java.util.ArrayList; - - -public class ShortDynamicLink extends AutoSafeParcelable { - @SafeParceled(1) - public final Uri shortLink; - - @SafeParceled(2) - public final Uri previewLink; - - @SafeParceled(3) - public final List warnings; - - - public ShortDynamicLink() { - shortLink = Uri.EMPTY; - previewLink = Uri.EMPTY; - - warnings = new ArrayList<>(); - } - - - public static final Creator CREATOR = new AutoCreator(ShortDynamicLink.class); -} \ No newline at end of file diff --git a/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/Warning.java b/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/Warning.java deleted file mode 100644 index 950f3de7..00000000 --- a/firebase-dynamic-links-api/src/main/java/com/google/firebase/dynamiclinks/internal/Warning.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2019 e Foundation - * - * 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 - * - * http://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. - */ - -package com.google.firebase.dynamiclinks.internal; - - -import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; - - -public class Warning extends AutoSafeParcelable { - @SafeParceled(1) - private int versionCode = 1; - - @SafeParceled(2) - public final String message; - - - public Warning() { - message = null; - } - - - public static final Creator CREATOR = new AutoCreator(Warning.class); -} \ No newline at end of file diff --git a/play-services-api/build.gradle b/play-services-api/build.gradle index d3064fa5..5e627850 100644 --- a/play-services-api/build.gradle +++ b/play-services-api/build.gradle @@ -34,7 +34,6 @@ android { dependencies { api project(':play-services-basement') - api project(':play-services-appinvite-api') api project(':play-services-cast-api') api project(':play-services-cast-framework-api') api project(':play-services-iid-api') diff --git a/play-services-appinvite-api/build.gradle b/play-services-appinvite-api/build.gradle deleted file mode 100644 index 32edbc9b..00000000 --- a/play-services-appinvite-api/build.gradle +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2019 e Foundation - * - * 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 - * - * http://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. - */ - -apply plugin: 'com.android.library' - -String getMyVersionName() { - def stdout = new ByteArrayOutputStream() - if (rootProject.file("gradlew").exists()) - exec { commandLine 'git', 'describe', '--tags', '--always', '--dirty'; standardOutput = stdout } - else // automatic build system, don't tag dirty - exec { commandLine 'git', 'describe', '--tags', '--always'; standardOutput = stdout } - return stdout.toString().trim().substring(1) -} - -group = 'org.microg' -version = getMyVersionName() - -android { - compileSdkVersion androidCompileSdk() - buildToolsVersion "$androidBuildVersionTools" - - defaultConfig { - versionName getMyVersionName() - minSdkVersion androidMinSdk() - targetSdkVersion androidTargetSdk() - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } -} - -dependencies { - api project(':play-services-basement') -} diff --git a/play-services-appinvite-api/gradle.properties b/play-services-appinvite-api/gradle.properties deleted file mode 100644 index 7215aee4..00000000 --- a/play-services-appinvite-api/gradle.properties +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright 2019 e Foundation -# -# 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 -# -# http://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. -# - -POM_NAME=Play Services Internal AppInvite API -POM_DESCRIPTION=Interfaces and objects for IPC between Play Services Library and Play Services Core - -POM_PACKAGING=aar - -POM_URL=https://github.com/microg/android_external_GmsApi - -POM_SCM_URL=https://github.com/microg/android_external_GmsApi -POM_SCM_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git -POM_SCM_DEV_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git - -POM_LICENCE_NAME=The Apache Software License, Version 2.0 -POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt -POM_LICENCE_DIST=repo - -POM_DEVELOPER_ID=alexandruchircu -POM_DEVELOPER_NAME=Alexandru Chircu - diff --git a/play-services-appinvite-api/src/main/AndroidManifest.xml b/play-services-appinvite-api/src/main/AndroidManifest.xml deleted file mode 100644 index da7741f9..00000000 --- a/play-services-appinvite-api/src/main/AndroidManifest.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - diff --git a/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteCallbacks.aidl b/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteCallbacks.aidl deleted file mode 100644 index 66c64d7e..00000000 --- a/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteCallbacks.aidl +++ /dev/null @@ -1,11 +0,0 @@ -package com.google.android.gms.appinvite.internal; - - -import com.google.android.gms.common.api.Status; -import android.content.Intent; - - -interface IAppInviteCallbacks { - void onStatus(in Status status) = 0; - void onStatusIntent(in Status status, in Intent intent) = 1; -} diff --git a/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteService.aidl b/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteService.aidl deleted file mode 100644 index 630edd43..00000000 --- a/play-services-appinvite-api/src/main/aidl/com/google/android/gms/appinvite/internal/IAppInviteService.aidl +++ /dev/null @@ -1,14 +0,0 @@ -package com.google.android.gms.appinvite.internal; - - -import com.google.android.gms.appinvite.internal.IAppInviteCallbacks; - -import com.google.android.gms.dynamic.IObjectWrapper; -import com.google.android.gms.common.api.Status; - - -interface IAppInviteService { - void updateInvitationOnInstall(IAppInviteCallbacks callback, String invitationId) = 0; - void convertInvitation(IAppInviteCallbacks callback, String invitationId) = 1; - void getInvitation(IAppInviteCallbacks callback) = 2; -} diff --git a/play-services-location/src/main/java/com/google/android/gms/location/ActivityRecognition.java b/play-services-location/src/main/java/com/google/android/gms/location/ActivityRecognition.java deleted file mode 100644 index f8f11656..00000000 --- a/play-services-location/src/main/java/com/google/android/gms/location/ActivityRecognition.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2017 microG Project Team - * - * 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 - * - * http://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. - */ - -package com.google.android.gms.location; - -import com.google.android.gms.common.api.Api; -import com.google.android.gms.common.api.GoogleApiClient.Builder; - -import org.microg.gms.location.ActivityRecognitionApiClientBuilder; -import org.microg.gms.location.ActivityRecognitionApiImpl; - -/** - * The main entry point for activity recognition integration. - */ -public class ActivityRecognition { - public static final String CLIENT_NAME = "activity_recognition"; - - /** - * Token to pass to {@link Builder#addApi(Api)} to enable ContextServices. - */ - public static final Api API = new Api(new ActivityRecognitionApiClientBuilder()); - - /** - * Entry point to the activity recognition APIs. - */ - public static final ActivityRecognitionApi ActivityRecognitionApi = new ActivityRecognitionApiImpl(); -} diff --git a/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderClient.java b/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderClient.java deleted file mode 100644 index a391c720..00000000 --- a/play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderClient.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.location; - -import android.content.Context; -import android.location.Location; - -import com.google.android.gms.common.api.Api; -import com.google.android.gms.common.api.GoogleApi; -import com.google.android.gms.tasks.Task; -import com.google.android.gms.tasks.TaskCompletionSource; - -import org.microg.gms.common.PublicApi; -import org.microg.gms.common.api.InstantGoogleApiCall; -import org.microg.gms.common.api.PendingGoogleApiCall; -import org.microg.gms.location.LocationClientImpl; - -@PublicApi -public class FusedLocationProviderClient extends GoogleApi { - @PublicApi(exclude = true) - public FusedLocationProviderClient(Context context) { - super(context, LocationServices.API); - } - - public Task flushLocations() { - return scheduleTask(new PendingGoogleApiCall() { - @Override - public void execute(LocationClientImpl client, TaskCompletionSource completionSource) { - completionSource.setResult(null); - } - }); - } - - public Task getLastLocation() { - return scheduleTask((InstantGoogleApiCall) LocationClientImpl::getLastLocation); - } - - -} diff --git a/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiClientBuilder.java b/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiClientBuilder.java deleted file mode 100644 index 1d22bd14..00000000 --- a/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiClientBuilder.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 microG Project Team - * - * 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 - * - * http://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. - */ - -package org.microg.gms.location; - -import android.content.Context; -import android.os.Looper; - -import com.google.android.gms.common.api.Api.ApiOptions.NoOptions; - -import org.microg.gms.common.api.ApiClientBuilder; -import org.microg.gms.common.api.ApiClientSettings; -import org.microg.gms.common.api.ApiClient; -import org.microg.gms.common.api.ConnectionCallbacks; -import org.microg.gms.common.api.OnConnectionFailedListener; - -public class ActivityRecognitionApiClientBuilder implements ApiClientBuilder { - @Override - public ApiClient build(NoOptions options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { - return new ActivityRecognitionClientImpl(context, callbacks, connectionFailedListener); - } -} diff --git a/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionClientImpl.java b/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionClientImpl.java deleted file mode 100644 index f48aa489..00000000 --- a/play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionClientImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2017 microG Project Team - * - * 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 - * - * http://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. - */ - -package org.microg.gms.location; - -import android.app.PendingIntent; -import android.content.Context; -import android.os.RemoteException; - -import org.microg.gms.common.api.ConnectionCallbacks; -import org.microg.gms.common.api.OnConnectionFailedListener; - -public class ActivityRecognitionClientImpl extends GoogleLocationManagerClient { - public ActivityRecognitionClientImpl(Context context, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) { - super(context, callbacks, connectionFailedListener); - } - - public void requestActivityUpdates(long detectionIntervalMillis, PendingIntent callbackIntent) throws RemoteException { - getServiceInterface().requestActivityUpdates(detectionIntervalMillis, true, callbackIntent); - } - - public void removeActivityUpdates(PendingIntent callbackIntent) throws RemoteException { - getServiceInterface().removeActivityUpdates(callbackIntent); - } -} diff --git a/play-services-wearable/src/main/java/com/google/android/gms/wearable/Wearable.java b/play-services-wearable/src/main/java/com/google/android/gms/wearable/Wearable.java deleted file mode 100644 index e1fcd8ec..00000000 --- a/play-services-wearable/src/main/java/com/google/android/gms/wearable/Wearable.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * 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 - * - * http://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. - */ - -package com.google.android.gms.wearable; - -import com.google.android.gms.common.api.Api; -import com.google.android.gms.common.api.GoogleApiClient; - -import org.microg.gms.common.PublicApi; -import org.microg.gms.wearable.DataApiImpl; -import org.microg.gms.wearable.MessageApiImpl; -import org.microg.gms.wearable.NodeApiImpl; -import org.microg.gms.wearable.WearableApiClientBuilder; - -/** - * An API for the Android Wear platform. - */ -@PublicApi -public class Wearable { - /** - * Token to pass to {@link GoogleApiClient.Builder#addApi(Api)} to enable the Wearable features. - */ - public static final Api API = new Api(new WearableApiClientBuilder()); - - public static final DataApi DataApi = new DataApiImpl(); - public static final MessageApi MessageApi = new MessageApiImpl(); - public static final NodeApi NodeApi = new NodeApiImpl(); - - public static class WearableOptions implements Api.ApiOptions.Optional { - /** - * Special option for microG to allow implementation of a FOSS first party Android Wear app - */ - @PublicApi(exclude = true) - public boolean firstPartyMode = false; - - public static class Builder { - public WearableOptions build() { - return new WearableOptions(); - } - } - } -} diff --git a/settings.gradle b/settings.gradle index 1d4a1b0d..83dc6675 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,6 +6,7 @@ include ':play-services-cast-framework-api' include ':play-services-iid-api' include ':play-services-base' +include ':play-services-base-api' include ':play-services-tasks' include ':play-services-base-core' From 3aa3c94b0c6185092d678075de2cfa947b9b96c3 Mon Sep 17 00:00:00 2001 From: X1nto Date: Mon, 27 Jul 2020 14:26:43 +0400 Subject: [PATCH 15/51] included a cast folder --- settings.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/settings.gradle b/settings.gradle index 83dc6675..013723e2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,7 @@ include ':play-services-basement' include ':play-services-api' +include ':play-services-cast' include ':play-services-cast-api' include ':play-services-cast-framework-api' include ':play-services-iid-api' From 2e84a5665d0f21f913db060275885e76efa04241 Mon Sep 17 00:00:00 2001 From: X1nto Date: Mon, 27 Jul 2020 14:39:30 +0400 Subject: [PATCH 16/51] added missing resources --- .../src/main/res/drawable-hdpi/ic_gamepad.png | Bin 0 -> 2696 bytes .../src/main/res/drawable-hdpi/ic_magnify.png | Bin 0 -> 575 bytes .../src/main/res/drawable-mdpi/ic_gamepad.png | Bin 0 -> 1751 bytes .../src/main/res/drawable-mdpi/ic_magnify.png | Bin 0 -> 337 bytes .../main/res/drawable-xhdpi/ic_gamepad.png | Bin 0 -> 3654 bytes .../main/res/drawable-xhdpi/ic_magnify.png | Bin 0 -> 581 bytes ...ry_auth_gls_ic_google_minitab_selected.png | Bin 0 -> 3053 bytes ...roprietary_auth_gls_ic_google_selected.png | Bin 0 -> 3922 bytes .../main/res/drawable-xxhdpi/ic_gamepad.png | Bin 0 -> 5805 bytes .../main/res/drawable-xxhdpi/ic_magnify.png | Bin 0 -> 930 bytes .../main/res/drawable-xxxhdpi/ic_magnify.png | Bin 0 -> 1147 bytes .../src/main/res/drawable/dots_horizontal.xml | 14 ++ .../src/main/res/drawable/ic_certificate.xml | 14 ++ .../main/res/drawable/ic_plusone_medium.xml | 17 +++ .../main/res/drawable/ic_plusone_small.xml | 17 +++ .../main/res/drawable/ic_plusone_standard.xml | 17 +++ .../src/main/res/drawable/ic_plusone_tall.xml | 17 +++ .../src/main/res/layout/ask_gcm.xml | 0 .../src/main/res/layout/ask_permission.xml | 2 +- .../res/layout/ask_permission_list_entry.xml | 0 .../layout/device_registration_fragment.xml | 0 .../src/main/res/layout/games_info.xml | 107 ++++++++++++++ .../src/main/res/layout/list_no_item.xml | 0 .../src/main/res/layout/login_assistant.xml | 0 .../res/layout/login_assistant_loading.xml | 0 .../src/main/res/layout/pick_place.xml | 133 ++++++++++++++++++ .../layout/preference_category_no_label.xml | 0 .../res/layout/preference_progress_bar.xml | 0 .../main/res/layout/preference_switch_bar.xml | 0 .../layout/push_notification_app_fragment.xml | 0 .../res/layout/push_notification_fragment.xml | 0 .../main/res/layout/safety_net_fragment.xml | 0 .../res/layout/settings_root_activity.xml | 0 .../src/main/res/menu/pick_place.xml | 28 ++++ .../mipmap-anydpi-v26/ic_microg_settings.xml | 6 + .../res/mipmap-hdpi/ic_core_service_app.png | Bin 0 -> 2453 bytes .../res/mipmap-hdpi/ic_microg_background.png | Bin 0 -> 476 bytes .../res/mipmap-hdpi/ic_microg_foreground.png | Bin 0 -> 7329 bytes .../res/mipmap-hdpi/ic_microg_settings.png | Bin 0 -> 4450 bytes .../src/main/res/navigation/nav_settings.xml | 0 .../src/main/res/xml/contact_syncadapter.xml | 21 +++ .../main/res/xml/preferences_safetynet.xml | 35 +++++ .../res/xml/preferences_snet_advanced.xml | 43 ++++++ 43 files changed, 470 insertions(+), 1 deletion(-) create mode 100755 play-services-core/src/main/res/drawable-hdpi/ic_gamepad.png create mode 100755 play-services-core/src/main/res/drawable-hdpi/ic_magnify.png create mode 100755 play-services-core/src/main/res/drawable-mdpi/ic_gamepad.png create mode 100755 play-services-core/src/main/res/drawable-mdpi/ic_magnify.png create mode 100755 play-services-core/src/main/res/drawable-xhdpi/ic_gamepad.png create mode 100755 play-services-core/src/main/res/drawable-xhdpi/ic_magnify.png create mode 100755 play-services-core/src/main/res/drawable-xhdpi/proprietary_auth_gls_ic_google_minitab_selected.png create mode 100755 play-services-core/src/main/res/drawable-xhdpi/proprietary_auth_gls_ic_google_selected.png create mode 100755 play-services-core/src/main/res/drawable-xxhdpi/ic_gamepad.png create mode 100755 play-services-core/src/main/res/drawable-xxhdpi/ic_magnify.png create mode 100755 play-services-core/src/main/res/drawable-xxxhdpi/ic_magnify.png create mode 100755 play-services-core/src/main/res/drawable/dots_horizontal.xml create mode 100755 play-services-core/src/main/res/drawable/ic_certificate.xml create mode 100755 play-services-core/src/main/res/drawable/ic_plusone_medium.xml create mode 100755 play-services-core/src/main/res/drawable/ic_plusone_small.xml create mode 100755 play-services-core/src/main/res/drawable/ic_plusone_standard.xml create mode 100755 play-services-core/src/main/res/drawable/ic_plusone_tall.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/ask_gcm.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/ask_permission.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/ask_permission_list_entry.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/device_registration_fragment.xml create mode 100755 play-services-core/src/main/res/layout/games_info.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/list_no_item.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/login_assistant.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/login_assistant_loading.xml create mode 100755 play-services-core/src/main/res/layout/pick_place.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/preference_category_no_label.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/preference_progress_bar.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/preference_switch_bar.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/push_notification_app_fragment.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/push_notification_fragment.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/safety_net_fragment.xml mode change 100644 => 100755 play-services-core/src/main/res/layout/settings_root_activity.xml create mode 100755 play-services-core/src/main/res/menu/pick_place.xml create mode 100755 play-services-core/src/main/res/mipmap-anydpi-v26/ic_microg_settings.xml create mode 100755 play-services-core/src/main/res/mipmap-hdpi/ic_core_service_app.png create mode 100755 play-services-core/src/main/res/mipmap-hdpi/ic_microg_background.png create mode 100755 play-services-core/src/main/res/mipmap-hdpi/ic_microg_foreground.png create mode 100755 play-services-core/src/main/res/mipmap-hdpi/ic_microg_settings.png mode change 100644 => 100755 play-services-core/src/main/res/navigation/nav_settings.xml create mode 100755 play-services-core/src/main/res/xml/contact_syncadapter.xml create mode 100755 play-services-core/src/main/res/xml/preferences_safetynet.xml create mode 100755 play-services-core/src/main/res/xml/preferences_snet_advanced.xml diff --git a/play-services-core/src/main/res/drawable-hdpi/ic_gamepad.png b/play-services-core/src/main/res/drawable-hdpi/ic_gamepad.png new file mode 100755 index 0000000000000000000000000000000000000000..43167f99119349c22e73ddf1f0adf2347f22e7cf GIT binary patch literal 2696 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 literal 0 HcmV?d00001 diff --git a/play-services-core/src/main/res/drawable-mdpi/ic_magnify.png b/play-services-core/src/main/res/drawable-mdpi/ic_magnify.png new file mode 100755 index 0000000000000000000000000000000000000000..fedd0c623f5698d635ed5e6234a7a6fe1f5777d5 GIT binary patch literal 337 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjY)RhkE(}6TtKSPDj(q%x-9Zwg>5Rc<;rx@}zIf%H}s}yibcP=+DRGW8r z^#R>4JkqvpALW8F(z6@SZkFs(e6^{2s@2(+)PHA;ZXSKpAHiUJfYE({pml=T6$|ET zdyY$;NMa5%+Q}elz*tncw6q~KM|bVdFRf|61cbt-Td`@_?h3LJmnyiF@bIGOrMXVb zQoPUPV)bGlfA+CHpZ@WLvH7bP)$DJMc%P5?T_+zE_(F3QJL`!B?`?0e&DLIU-uGSy z{{aiL7a!wGt_qgr>Ke(5J-T_|hq==wkNeh>R92qNNlg2Cy!`(YZ@c)5-ygG`lV9OA U_x_2kKz}lLy85}Sb4q9e0DP-{=l}o! literal 0 HcmV?d00001 diff --git a/play-services-core/src/main/res/drawable-xhdpi/ic_gamepad.png b/play-services-core/src/main/res/drawable-xhdpi/ic_gamepad.png new file mode 100755 index 0000000000000000000000000000000000000000..a7b21f88c531a0b184adfd712b107dff5caac827 GIT binary patch literal 3654 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 U!pN|)|CkRj(lghs#X6Gy2Xu?W5C8xG literal 0 HcmV?d00001 diff --git a/play-services-core/src/main/res/drawable-xhdpi/ic_magnify.png b/play-services-core/src/main/res/drawable-xhdpi/ic_magnify.png new file mode 100755 index 0000000000000000000000000000000000000000..5713a86f6329d9ca5d92cc10c6016f5f38852f6f GIT binary patch literal 581 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 literal 0 HcmV?d00001 diff --git a/play-services-core/src/main/res/drawable-xhdpi/proprietary_auth_gls_ic_google_selected.png b/play-services-core/src/main/res/drawable-xhdpi/proprietary_auth_gls_ic_google_selected.png new file mode 100755 index 0000000000000000000000000000000000000000..e23dc238a27be3243d15b34a3fd2a93cc7fca61b GIT binary patch literal 3922 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 literal 0 HcmV?d00001 diff --git a/play-services-core/src/main/res/drawable-xxhdpi/ic_gamepad.png b/play-services-core/src/main/res/drawable-xxhdpi/ic_gamepad.png new file mode 100755 index 0000000000000000000000000000000000000000..556abb12859446937fff3eacad79a3a9b59623d0 GIT binary patch literal 5805 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 literal 0 HcmV?d00001 diff --git a/play-services-core/src/main/res/drawable-xxhdpi/ic_magnify.png b/play-services-core/src/main/res/drawable-xxhdpi/ic_magnify.png new file mode 100755 index 0000000000000000000000000000000000000000..d9f75bc794e76f1e7057b35124cefe6c2fa9c5c8 GIT binary patch literal 930 zcmV;T16}-yP)mb5SFhNPR4CL}$ObYHF6EskADbz{t~4^dg< z45oOj_JAiqf6AEs(e-;N9=Ac?4w9N#NNC~(Fq|{?aP<2)7JNI1YoLyOwmJo#0_R$M z0w#(Rm#3Ud0AMZVKRaJ=uKAc;Yrb7{D|ja1u_|=i65UC0k6XD`+`zJ>(0yRYQO=<# zem9nVJ83U;1ZY|copYRf&XTuDYeVcGVAfJ(1IJqdT3eZhCI77J-Y=!RZpt#gVvIR< zSzr`@C1YKMkyg;8W&D-v0u%B~W{Q%7w1UPho>mq?GlA2u`Fvi)jv6TJ}I<$;mcUfGDJV&k*rxkQy8BaRyC<CLJnElPT9j5+D0q+HP3ck|u&1=M_dNRrfxuRAt?#VSj3^?lF@@C@h!E?4?a zibNIph1n_{Q+dMm)sPf5lJ^_MCa{EMg&axfxg=j-xgJSsNcySPk;O+zZ;dgHn0Pfw z?pr`9k3B| zCtd7Eteq~Bf}Bp;Bn3G(B1tvhbp!%|Kp+qZ1OgX}|BrB-B9PU+=Kufz07*qoM6N<$ Eg1Z%=^Z)<= literal 0 HcmV?d00001 diff --git a/play-services-core/src/main/res/drawable-xxxhdpi/ic_magnify.png b/play-services-core/src/main/res/drawable-xxxhdpi/ic_magnify.png new file mode 100755 index 0000000000000000000000000000000000000000..28456073e7813c560554351ef45fc5102c8dd877 GIT binary patch literal 1147 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoY)RhkE(}8pX7+2iB`GtXjh0W8&F{I+w+d20BB90Qr=5JKe+PJ}8r6A*= zymO-qcao!%#v9%rp)u7iKR8V47_GRHL;giJv>jql^ z=T}UUnY7M*akstKCy!m9o?9qcYQ;`}eIoaXLy^FNY6f##{<};D{11#9cp0i0_%3e? zW5{LL#c0E7z;xjIwNLy9jFZoJ-8;(7cJ1BI-*WfQBv0C$nX#{yciC~d>Mz^RN7M^P zNWWcEC6e5ilFs+HY}xao)TxGjeIDm5#2!p|Qo;DQfBEyWM7LdWm9ym)Djy~M5kGm4 zsr1XT+8Y*$I`!8gX2(U88T_4`QqBBj%ktWr5otV^#nznNzvE7slv(1jTQ2iYzs>O3 zRaZHqbY{eCfeWS&7i2r`s{1dMV*nI{6^r)b;sZTTRdM{ zT}v)FpOk0D(7RczxB8OQW~tQ{G57BMFW|ml`C`FlrL~{k+LGIJ-$pB**}X(++p8}@ z7LiOF{#Kmzp8e^9(m&@psttMG)gI0^v&CjlKXg*)K&|)h^2}hlsGK-1b#I1powtg; zdO1+u+G*eRUs`6f<;ETnziA9fPBlS#-VE*2zTE~1%6M|05jxPgbg%ENDeco%Z8@OB z_$K0(ycf`(PtH*Z(-_Qj-uf@`t<1PNO>Bm0L;kdHf*^bLd2oMG+jMdV`z5Q*v$_+l zs@hX)&CXcJo$&FzzEQ5ZmT!9bi++{gOJ7HWhxc18`QBfz2+adfJ@(W$1o4&Zc{TgzZyZyYIbkmj9T=zcR z$vFOThlR5T_k|VHOLaa?3Y>cUV_mdKI;Vst00}bj_y7O^ literal 0 HcmV?d00001 diff --git a/play-services-core/src/main/res/drawable/dots_horizontal.xml b/play-services-core/src/main/res/drawable/dots_horizontal.xml new file mode 100755 index 00000000..4110aed7 --- /dev/null +++ b/play-services-core/src/main/res/drawable/dots_horizontal.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/play-services-core/src/main/res/drawable/ic_certificate.xml b/play-services-core/src/main/res/drawable/ic_certificate.xml new file mode 100755 index 00000000..780e4db4 --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_certificate.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/play-services-core/src/main/res/drawable/ic_plusone_medium.xml b/play-services-core/src/main/res/drawable/ic_plusone_medium.xml new file mode 100755 index 00000000..f7433017 --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_plusone_medium.xml @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/play-services-core/src/main/res/drawable/ic_plusone_small.xml b/play-services-core/src/main/res/drawable/ic_plusone_small.xml new file mode 100755 index 00000000..f7433017 --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_plusone_small.xml @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/play-services-core/src/main/res/drawable/ic_plusone_standard.xml b/play-services-core/src/main/res/drawable/ic_plusone_standard.xml new file mode 100755 index 00000000..f7433017 --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_plusone_standard.xml @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/play-services-core/src/main/res/drawable/ic_plusone_tall.xml b/play-services-core/src/main/res/drawable/ic_plusone_tall.xml new file mode 100755 index 00000000..f7433017 --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_plusone_tall.xml @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/play-services-core/src/main/res/layout/ask_gcm.xml b/play-services-core/src/main/res/layout/ask_gcm.xml old mode 100644 new mode 100755 diff --git a/play-services-core/src/main/res/layout/ask_permission.xml b/play-services-core/src/main/res/layout/ask_permission.xml old mode 100644 new mode 100755 index 44801f8a..6ef04c35 --- a/play-services-core/src/main/res/layout/ask_permission.xml +++ b/play-services-core/src/main/res/layout/ask_permission.xml @@ -75,7 +75,7 @@ android:padding="10dp"> diff --git a/play-services-core/src/main/res/layout/ask_permission_list_entry.xml b/play-services-core/src/main/res/layout/ask_permission_list_entry.xml old mode 100644 new mode 100755 diff --git a/play-services-core/src/main/res/layout/device_registration_fragment.xml b/play-services-core/src/main/res/layout/device_registration_fragment.xml old mode 100644 new mode 100755 diff --git a/play-services-core/src/main/res/layout/games_info.xml b/play-services-core/src/main/res/layout/games_info.xml new file mode 100755 index 00000000..972dc179 --- /dev/null +++ b/play-services-core/src/main/res/layout/games_info.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +