/* * Copyright (C) 2018 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.gcm; import static org.microg.gms.gcm.GcmConstants.ERROR_SERVICE_NOT_AVAILABLE; import static org.microg.gms.gcm.GcmConstants.EXTRA_ERROR; import static org.microg.gms.gcm.GcmConstants.EXTRA_REGISTRATION_ID; import static org.microg.gms.gcm.GcmConstants.EXTRA_RETRY_AFTER; import static org.microg.gms.gcm.GcmConstants.EXTRA_UNREGISTERED; import android.content.Context; import android.os.Bundle; import android.util.Log; import org.microg.gms.checkin.LastCheckinInfo; import org.microg.gms.common.HttpFormClient; import org.microg.gms.common.PackageUtils; import java.io.IOException; public class PushRegisterManager { private static final String TAG = "GmsGcmRegisterMgr"; public static RegisterResponse unregister(Context context, String packageName, String pkgSignature, String sender, String info) { GcmDatabase database = new GcmDatabase(context); RegisterResponse response = new RegisterResponse(); try { response = new RegisterRequest() .build(context) .sender(sender) .info(info) .checkin(LastCheckinInfo.read(context)) .app(packageName, pkgSignature) .delete(true) .getResponse(); } catch (IOException e) { Log.w(TAG, e); } if (!packageName.equals(response.deleted)) { database.noteAppRegistrationError(packageName, response.responseText); } else { database.noteAppUnregistered(packageName, pkgSignature); } database.close(); return response; } public interface BundleCallback { void onResult(Bundle bundle); } public static void completeRegisterRequest(Context context, GcmDatabase database, RegisterRequest request, BundleCallback callback) { completeRegisterRequest(context, database, null, request, callback); } public static void completeRegisterRequest(Context context, GcmDatabase database, String requestId, RegisterRequest request, BundleCallback callback) { if (request.app != null) { if (request.appVersion <= 0) request.appVersion = PackageUtils.versionCode(context, request.app); if (!request.delete) { if (request.appSignature == null) { request.appSignature = PackageUtils.firstSignatureDigest(context, request.app); } request.sdkVersion = PackageUtils.targetSdkVersion(context, request.app); if (!request.hasExtraParam(GcmConstants.EXTRA_APP_VERSION_NAME)) request.extraParam(GcmConstants.EXTRA_APP_VERSION_NAME, PackageUtils.versionName(context, request.app)); } } GcmDatabase.App app = database.getApp(request.app); GcmPrefs prefs = GcmPrefs.get(context); if (!request.delete) { if (!prefs.isEnabled() || (app != null && !app.allowRegister) || LastCheckinInfo.read(context).getLastCheckin() <= 0) { Bundle bundle = new Bundle(); bundle.putString(EXTRA_ERROR, ERROR_SERVICE_NOT_AVAILABLE); callback.onResult(bundle); return; } } else { if (database.getRegistrationsByApp(request.app).isEmpty()) { Bundle bundle = new Bundle(); bundle.putString(EXTRA_UNREGISTERED, attachRequestId(request.app, requestId)); callback.onResult(bundle); return; } } request.getResponseAsync(new HttpFormClient.Callback() { @Override public void onResponse(RegisterResponse response) { callback.onResult(handleResponse(database, request, response, requestId)); } @Override public void onException(Exception e) { Log.w(TAG, e); callback.onResult(handleResponse(database, request, e, requestId)); } }); } private static Bundle handleResponse(GcmDatabase database, RegisterRequest request, RegisterResponse response, String requestId) { return handleResponse(database, request, response, null, requestId); } private static Bundle handleResponse(GcmDatabase database, RegisterRequest request, Exception e, String requestId) { return handleResponse(database, request, null, e, requestId); } private static Bundle handleResponse(GcmDatabase database, RegisterRequest request, RegisterResponse response, Exception e, String requestId) { Bundle resultBundle = new Bundle(); if (response == null && e == null) { resultBundle.putString(EXTRA_ERROR, attachRequestId(ERROR_SERVICE_NOT_AVAILABLE, requestId)); } else if (e != null) { if (e.getMessage() != null && e.getMessage().startsWith("Error=")) { String errorMessage = e.getMessage().substring(6); database.noteAppRegistrationError(request.app, errorMessage); resultBundle.putString(EXTRA_ERROR, attachRequestId(errorMessage, requestId)); } else { resultBundle.putString(EXTRA_ERROR, attachRequestId(ERROR_SERVICE_NOT_AVAILABLE, requestId)); } } else { if (!request.delete) { if (response.token == null) { database.noteAppRegistrationError(request.app, response.responseText); resultBundle.putString(EXTRA_ERROR, attachRequestId(ERROR_SERVICE_NOT_AVAILABLE, requestId)); } else { database.noteAppRegistered(request.app, request.appSignature, response.token); resultBundle.putString(EXTRA_REGISTRATION_ID, attachRequestId(response.token, requestId)); } } else { if (!request.app.equals(response.deleted) && !request.app.equals(response.token)) { database.noteAppRegistrationError(request.app, response.responseText); resultBundle.putString(EXTRA_ERROR, attachRequestId(ERROR_SERVICE_NOT_AVAILABLE, requestId)); } else { database.noteAppUnregistered(request.app, request.appSignature); resultBundle.putString(EXTRA_UNREGISTERED, attachRequestId(request.app, requestId)); } } if (response.retryAfter != null && !response.retryAfter.contains(":")) { resultBundle.putLong(EXTRA_RETRY_AFTER, Long.parseLong(response.retryAfter)); } } return resultBundle; } public static String attachRequestId(String msg, String requestId) { if (requestId == null) return msg; return "|ID|" + requestId + "|" + msg; } }