Loading play-services-core/src/main/AndroidManifest.xml +16 −2 Original line number Diff line number Diff line Loading @@ -133,7 +133,10 @@ android:name="org.microg.gms.wearable.location.WearableLocationService"> <intent-filter> <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/> <data android:scheme="wear" android:host="*" android:pathPrefix="/com/google/android/location/fused/wearable" /> <data android:host="*" android:pathPrefix="/com/google/android/location/fused/wearable" android:scheme="wear"/> </intent-filter> </service> Loading Loading @@ -282,6 +285,12 @@ android:value="1"/> </service> <service android:name=".auth.FirebaseAuthService"> <intent-filter> <action android:name="com.google.firebase.auth.api.gms.service.START"/> </intent-filter> </service> <activity android:name="org.microg.tools.AccountPickerActivity" android:excludeFromRecents="true" Loading Loading @@ -442,6 +451,12 @@ </intent-filter> </service> <service android:name="org.microg.gms.snet.SafetyNetClientService"> <intent-filter> <action android:name="com.google.android.gms.safetynet.service.START"/> </intent-filter> </service> <service android:name="org.microg.gms.DummyService"> <intent-filter> <action android:name="com.google.android.gms.plus.service.START"/> Loading @@ -468,7 +483,6 @@ <action android:name="com.google.android.gms.usagereporting.service.START"/> <action android:name="com.google.android.gms.kids.service.START"/> <action android:name="com.google.android.gms.common.download.START"/> <action android:name="com.google.android.gms.safetynet.service.START"/> <action android:name="com.google.android.contextmanager.service.ContextManagerService.START"/> <action android:name="com.google.android.gms.audiomodem.service.AudioModemService.START"/> <action android:name="com.google.android.gms.nearby.sharing.service.NearbySharingService.START"/> Loading play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientService.java 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright 2013-2016 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.snet; import android.os.RemoteException; 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; public class SafetyNetClientService extends BaseService { public SafetyNetClientService() { super("GmsSafetyNetClientSvc", GmsService.SAFETY_NET_CLIENT); } @Override public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException { callback.onPostInitComplete(0, new SafetyNetClientServiceImpl(this, request.packageName), null); } } play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java 0 → 100644 +220 −0 Original line number Diff line number Diff line /* * Copyright 2013-2016 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.snet; import android.annotation.SuppressLint; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.os.RemoteException; import android.util.Base64; import android.util.Log; import com.google.android.gms.common.api.Status; import com.google.android.gms.safetynet.AttestationData; import com.google.android.gms.safetynet.HarmfulAppsData; import com.google.android.gms.safetynet.internal.ISafetyNetCallbacks; import com.google.android.gms.safetynet.internal.ISafetyNetService; import com.squareup.wire.Wire; import org.microg.gms.common.Constants; import org.microg.gms.common.PackageUtils; import org.microg.gms.common.Utils; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.security.MessageDigest; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import okio.ByteString; public class SafetyNetClientServiceImpl extends ISafetyNetService.Stub { private static final String TAG = "GmsSafetyNetClientImpl"; public static final String ATTEST_URL = "https://www.googleapis.com/androidcheck/v1/attestations/attest?alt=PROTO&key=AIzaSyDqVnJBjE5ymo--oBJt3On7HQx9xNm1RHA"; private Context context; private String packageName; public SafetyNetClientServiceImpl(Context context, String packageName) { this.context = context; this.packageName = packageName; } private ByteString getPackageFileDigest() { try { FileInputStream is = new FileInputStream(new File(context.getPackageManager().getApplicationInfo(packageName, 0).sourceDir)); MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] data = new byte[16384]; while (true) { int read = is.read(data); if (read < 0) break; digest.update(data, 0, read); } return ByteString.of(digest.digest()); } catch (Exception e) { Log.w(TAG, e); return null; } } @SuppressLint("PackageManagerGetSignatures") private List<ByteString> getPackageSignatures() { try { PackageInfo pi = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES); ArrayList<ByteString> res = new ArrayList<>(); MessageDigest digest = MessageDigest.getInstance("SHA-256"); for (Signature signature : pi.signatures) { res.add(ByteString.of(digest.digest(signature.toByteArray()))); } return res; } catch (Exception e) { Log.w(TAG, e); return null; } } @Override public void attest(final ISafetyNetCallbacks callbacks, final byte[] nonce) throws RemoteException { if (nonce == null) { callbacks.onAttestationData(new Status(10), null); return; } new Thread(new Runnable() { @Override public void run() { SafetyNetData payload = new SafetyNetData.Builder() .nonce(ByteString.of(nonce)) .currentTimeMs(System.currentTimeMillis()) .packageName(packageName) .fileDigest(getPackageFileDigest()) .signatureDigest(getPackageSignatures()) .gmsVersionCode(Constants.MAX_REFERENCE_VERSION) .googleCn(false) .seLinuxState(new SELinuxState(true, true)) .suCandidates(Collections.<FileState>emptyList()) .build(); AttestRequest request = new AttestRequest(ByteString.of(payload.toByteArray()), ""); Log.d(TAG, "attest: " + payload); try { try { AttestResponse response = attest(request); callbacks.onAttestationData(Status.SUCCESS, new AttestationData(response.result)); } catch (IOException e) { Log.w(TAG, e); callbacks.onAttestationData(Status.INTERNAL_ERROR, null); } } catch (RemoteException e) { Log.w(TAG, e); } } }).start(); } private AttestResponse attest(AttestRequest request) throws IOException { HttpURLConnection connection = (HttpURLConnection) new URL(ATTEST_URL).openConnection(); connection.setRequestMethod("POST"); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestProperty("Content-type", "application/x-protobuf"); connection.setRequestProperty("Content-Encoding", "gzip"); connection.setRequestProperty("Accept-Encoding", "gzip"); connection.setRequestProperty("User-Agent", "SafetyNet/" + Constants.MAX_REFERENCE_VERSION); Log.d(TAG, "-- Request --\n" + request); OutputStream os = new GZIPOutputStream(connection.getOutputStream()); os.write(request.toByteArray()); os.close(); if (connection.getResponseCode() != 200) { byte[] bytes = null; String ex = null; try { bytes = Utils.readStreamToEnd(connection.getErrorStream()); ex = new String(Utils.readStreamToEnd(new GZIPInputStream(new ByteArrayInputStream(bytes)))); } catch (Exception e) { if (bytes != null) { throw new IOException(getBytesAsString(bytes), e); } throw new IOException(connection.getResponseMessage(), e); } throw new IOException(ex); } InputStream is = connection.getInputStream(); AttestResponse response = new Wire().parseFrom(new GZIPInputStream(is), AttestResponse.class); is.close(); return response; } private String getBytesAsString(byte[] bytes) { if (bytes == null) return "null"; try { CharsetDecoder d = Charset.forName("US-ASCII").newDecoder(); CharBuffer r = d.decode(ByteBuffer.wrap(bytes)); return r.toString(); } catch (Exception e) { return Base64.encodeToString(bytes, Base64.NO_WRAP); } } @Override public void getSharedUuid(ISafetyNetCallbacks callbacks) throws RemoteException { PackageUtils.checkPackageUid(context, packageName, getCallingUid()); PackageUtils.assertExtendedAccess(context); // TODO Log.d(TAG, "dummy Method: getSharedUuid"); callbacks.onString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"); } @Override public void lookupUri(ISafetyNetCallbacks callbacks, String s1, int[] threatTypes, int i, String s2) throws RemoteException { Log.d(TAG, "unimplemented Method: lookupUri"); } @Override public void init(ISafetyNetCallbacks callbacks) throws RemoteException { Log.d(TAG, "dummy Method: init"); callbacks.onBoolean(Status.SUCCESS, true); } @Override public void unknown4(ISafetyNetCallbacks callbacks) throws RemoteException { Log.d(TAG, "dummy Method: unknown4"); callbacks.onHarmfulAppsData(Status.SUCCESS, new ArrayList<HarmfulAppsData>()); } } play-services-core/src/main/protos-java/org/microg/gms/snet/AttestRequest.java 0 → 100644 +83 −0 Original line number Diff line number Diff line // Code generated by Wire protocol buffer compiler, do not edit. // Source file: protos-repo/snet.proto package org.microg.gms.snet; import com.squareup.wire.Message; import com.squareup.wire.ProtoField; import okio.ByteString; import static com.squareup.wire.Message.Datatype.BYTES; import static com.squareup.wire.Message.Datatype.STRING; public final class AttestRequest extends Message { public static final ByteString DEFAULT_SAFETYNETDATA = ByteString.EMPTY; public static final String DEFAULT_DROIDGUARDRESULT = ""; @ProtoField(tag = 1, type = BYTES) public final ByteString safetyNetData; @ProtoField(tag = 2, type = STRING) public final String droidGuardResult; public AttestRequest(ByteString safetyNetData, String droidGuardResult) { this.safetyNetData = safetyNetData; this.droidGuardResult = droidGuardResult; } private AttestRequest(Builder builder) { this(builder.safetyNetData, builder.droidGuardResult); setBuilder(builder); } @Override public boolean equals(Object other) { if (other == this) return true; if (!(other instanceof AttestRequest)) return false; AttestRequest o = (AttestRequest) other; return equals(safetyNetData, o.safetyNetData) && equals(droidGuardResult, o.droidGuardResult); } @Override public int hashCode() { int result = hashCode; if (result == 0) { result = safetyNetData != null ? safetyNetData.hashCode() : 0; result = result * 37 + (droidGuardResult != null ? droidGuardResult.hashCode() : 0); hashCode = result; } return result; } public static final class Builder extends Message.Builder<AttestRequest> { public ByteString safetyNetData; public String droidGuardResult; public Builder() { } public Builder(AttestRequest message) { super(message); if (message == null) return; this.safetyNetData = message.safetyNetData; this.droidGuardResult = message.droidGuardResult; } public Builder safetyNetData(ByteString safetyNetData) { this.safetyNetData = safetyNetData; return this; } public Builder droidGuardResult(String droidGuardResult) { this.droidGuardResult = droidGuardResult; return this; } @Override public AttestRequest build() { return new AttestRequest(this); } } } play-services-core/src/main/protos-java/org/microg/gms/snet/AttestResponse.java 0 → 100644 +62 −0 Original line number Diff line number Diff line // Code generated by Wire protocol buffer compiler, do not edit. // Source file: protos-repo/snet.proto package org.microg.gms.snet; import com.squareup.wire.Message; import com.squareup.wire.ProtoField; import static com.squareup.wire.Message.Datatype.STRING; public final class AttestResponse extends Message { public static final String DEFAULT_RESULT = ""; @ProtoField(tag = 2, type = STRING) public final String result; public AttestResponse(String result) { this.result = result; } private AttestResponse(Builder builder) { this(builder.result); setBuilder(builder); } @Override public boolean equals(Object other) { if (other == this) return true; if (!(other instanceof AttestResponse)) return false; return equals(result, ((AttestResponse) other).result); } @Override public int hashCode() { int result = hashCode; return result != 0 ? result : (hashCode = this.result != null ? this.result.hashCode() : 0); } public static final class Builder extends Message.Builder<AttestResponse> { public String result; public Builder() { } public Builder(AttestResponse message) { super(message); if (message == null) return; this.result = message.result; } public Builder result(String result) { this.result = result; return this; } @Override public AttestResponse build() { return new AttestResponse(this); } } } Loading
play-services-core/src/main/AndroidManifest.xml +16 −2 Original line number Diff line number Diff line Loading @@ -133,7 +133,10 @@ android:name="org.microg.gms.wearable.location.WearableLocationService"> <intent-filter> <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/> <data android:scheme="wear" android:host="*" android:pathPrefix="/com/google/android/location/fused/wearable" /> <data android:host="*" android:pathPrefix="/com/google/android/location/fused/wearable" android:scheme="wear"/> </intent-filter> </service> Loading Loading @@ -282,6 +285,12 @@ android:value="1"/> </service> <service android:name=".auth.FirebaseAuthService"> <intent-filter> <action android:name="com.google.firebase.auth.api.gms.service.START"/> </intent-filter> </service> <activity android:name="org.microg.tools.AccountPickerActivity" android:excludeFromRecents="true" Loading Loading @@ -442,6 +451,12 @@ </intent-filter> </service> <service android:name="org.microg.gms.snet.SafetyNetClientService"> <intent-filter> <action android:name="com.google.android.gms.safetynet.service.START"/> </intent-filter> </service> <service android:name="org.microg.gms.DummyService"> <intent-filter> <action android:name="com.google.android.gms.plus.service.START"/> Loading @@ -468,7 +483,6 @@ <action android:name="com.google.android.gms.usagereporting.service.START"/> <action android:name="com.google.android.gms.kids.service.START"/> <action android:name="com.google.android.gms.common.download.START"/> <action android:name="com.google.android.gms.safetynet.service.START"/> <action android:name="com.google.android.contextmanager.service.ContextManagerService.START"/> <action android:name="com.google.android.gms.audiomodem.service.AudioModemService.START"/> <action android:name="com.google.android.gms.nearby.sharing.service.NearbySharingService.START"/> Loading
play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientService.java 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright 2013-2016 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.snet; import android.os.RemoteException; 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; public class SafetyNetClientService extends BaseService { public SafetyNetClientService() { super("GmsSafetyNetClientSvc", GmsService.SAFETY_NET_CLIENT); } @Override public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException { callback.onPostInitComplete(0, new SafetyNetClientServiceImpl(this, request.packageName), null); } }
play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java 0 → 100644 +220 −0 Original line number Diff line number Diff line /* * Copyright 2013-2016 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.snet; import android.annotation.SuppressLint; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.os.RemoteException; import android.util.Base64; import android.util.Log; import com.google.android.gms.common.api.Status; import com.google.android.gms.safetynet.AttestationData; import com.google.android.gms.safetynet.HarmfulAppsData; import com.google.android.gms.safetynet.internal.ISafetyNetCallbacks; import com.google.android.gms.safetynet.internal.ISafetyNetService; import com.squareup.wire.Wire; import org.microg.gms.common.Constants; import org.microg.gms.common.PackageUtils; import org.microg.gms.common.Utils; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.security.MessageDigest; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import okio.ByteString; public class SafetyNetClientServiceImpl extends ISafetyNetService.Stub { private static final String TAG = "GmsSafetyNetClientImpl"; public static final String ATTEST_URL = "https://www.googleapis.com/androidcheck/v1/attestations/attest?alt=PROTO&key=AIzaSyDqVnJBjE5ymo--oBJt3On7HQx9xNm1RHA"; private Context context; private String packageName; public SafetyNetClientServiceImpl(Context context, String packageName) { this.context = context; this.packageName = packageName; } private ByteString getPackageFileDigest() { try { FileInputStream is = new FileInputStream(new File(context.getPackageManager().getApplicationInfo(packageName, 0).sourceDir)); MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] data = new byte[16384]; while (true) { int read = is.read(data); if (read < 0) break; digest.update(data, 0, read); } return ByteString.of(digest.digest()); } catch (Exception e) { Log.w(TAG, e); return null; } } @SuppressLint("PackageManagerGetSignatures") private List<ByteString> getPackageSignatures() { try { PackageInfo pi = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES); ArrayList<ByteString> res = new ArrayList<>(); MessageDigest digest = MessageDigest.getInstance("SHA-256"); for (Signature signature : pi.signatures) { res.add(ByteString.of(digest.digest(signature.toByteArray()))); } return res; } catch (Exception e) { Log.w(TAG, e); return null; } } @Override public void attest(final ISafetyNetCallbacks callbacks, final byte[] nonce) throws RemoteException { if (nonce == null) { callbacks.onAttestationData(new Status(10), null); return; } new Thread(new Runnable() { @Override public void run() { SafetyNetData payload = new SafetyNetData.Builder() .nonce(ByteString.of(nonce)) .currentTimeMs(System.currentTimeMillis()) .packageName(packageName) .fileDigest(getPackageFileDigest()) .signatureDigest(getPackageSignatures()) .gmsVersionCode(Constants.MAX_REFERENCE_VERSION) .googleCn(false) .seLinuxState(new SELinuxState(true, true)) .suCandidates(Collections.<FileState>emptyList()) .build(); AttestRequest request = new AttestRequest(ByteString.of(payload.toByteArray()), ""); Log.d(TAG, "attest: " + payload); try { try { AttestResponse response = attest(request); callbacks.onAttestationData(Status.SUCCESS, new AttestationData(response.result)); } catch (IOException e) { Log.w(TAG, e); callbacks.onAttestationData(Status.INTERNAL_ERROR, null); } } catch (RemoteException e) { Log.w(TAG, e); } } }).start(); } private AttestResponse attest(AttestRequest request) throws IOException { HttpURLConnection connection = (HttpURLConnection) new URL(ATTEST_URL).openConnection(); connection.setRequestMethod("POST"); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestProperty("Content-type", "application/x-protobuf"); connection.setRequestProperty("Content-Encoding", "gzip"); connection.setRequestProperty("Accept-Encoding", "gzip"); connection.setRequestProperty("User-Agent", "SafetyNet/" + Constants.MAX_REFERENCE_VERSION); Log.d(TAG, "-- Request --\n" + request); OutputStream os = new GZIPOutputStream(connection.getOutputStream()); os.write(request.toByteArray()); os.close(); if (connection.getResponseCode() != 200) { byte[] bytes = null; String ex = null; try { bytes = Utils.readStreamToEnd(connection.getErrorStream()); ex = new String(Utils.readStreamToEnd(new GZIPInputStream(new ByteArrayInputStream(bytes)))); } catch (Exception e) { if (bytes != null) { throw new IOException(getBytesAsString(bytes), e); } throw new IOException(connection.getResponseMessage(), e); } throw new IOException(ex); } InputStream is = connection.getInputStream(); AttestResponse response = new Wire().parseFrom(new GZIPInputStream(is), AttestResponse.class); is.close(); return response; } private String getBytesAsString(byte[] bytes) { if (bytes == null) return "null"; try { CharsetDecoder d = Charset.forName("US-ASCII").newDecoder(); CharBuffer r = d.decode(ByteBuffer.wrap(bytes)); return r.toString(); } catch (Exception e) { return Base64.encodeToString(bytes, Base64.NO_WRAP); } } @Override public void getSharedUuid(ISafetyNetCallbacks callbacks) throws RemoteException { PackageUtils.checkPackageUid(context, packageName, getCallingUid()); PackageUtils.assertExtendedAccess(context); // TODO Log.d(TAG, "dummy Method: getSharedUuid"); callbacks.onString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"); } @Override public void lookupUri(ISafetyNetCallbacks callbacks, String s1, int[] threatTypes, int i, String s2) throws RemoteException { Log.d(TAG, "unimplemented Method: lookupUri"); } @Override public void init(ISafetyNetCallbacks callbacks) throws RemoteException { Log.d(TAG, "dummy Method: init"); callbacks.onBoolean(Status.SUCCESS, true); } @Override public void unknown4(ISafetyNetCallbacks callbacks) throws RemoteException { Log.d(TAG, "dummy Method: unknown4"); callbacks.onHarmfulAppsData(Status.SUCCESS, new ArrayList<HarmfulAppsData>()); } }
play-services-core/src/main/protos-java/org/microg/gms/snet/AttestRequest.java 0 → 100644 +83 −0 Original line number Diff line number Diff line // Code generated by Wire protocol buffer compiler, do not edit. // Source file: protos-repo/snet.proto package org.microg.gms.snet; import com.squareup.wire.Message; import com.squareup.wire.ProtoField; import okio.ByteString; import static com.squareup.wire.Message.Datatype.BYTES; import static com.squareup.wire.Message.Datatype.STRING; public final class AttestRequest extends Message { public static final ByteString DEFAULT_SAFETYNETDATA = ByteString.EMPTY; public static final String DEFAULT_DROIDGUARDRESULT = ""; @ProtoField(tag = 1, type = BYTES) public final ByteString safetyNetData; @ProtoField(tag = 2, type = STRING) public final String droidGuardResult; public AttestRequest(ByteString safetyNetData, String droidGuardResult) { this.safetyNetData = safetyNetData; this.droidGuardResult = droidGuardResult; } private AttestRequest(Builder builder) { this(builder.safetyNetData, builder.droidGuardResult); setBuilder(builder); } @Override public boolean equals(Object other) { if (other == this) return true; if (!(other instanceof AttestRequest)) return false; AttestRequest o = (AttestRequest) other; return equals(safetyNetData, o.safetyNetData) && equals(droidGuardResult, o.droidGuardResult); } @Override public int hashCode() { int result = hashCode; if (result == 0) { result = safetyNetData != null ? safetyNetData.hashCode() : 0; result = result * 37 + (droidGuardResult != null ? droidGuardResult.hashCode() : 0); hashCode = result; } return result; } public static final class Builder extends Message.Builder<AttestRequest> { public ByteString safetyNetData; public String droidGuardResult; public Builder() { } public Builder(AttestRequest message) { super(message); if (message == null) return; this.safetyNetData = message.safetyNetData; this.droidGuardResult = message.droidGuardResult; } public Builder safetyNetData(ByteString safetyNetData) { this.safetyNetData = safetyNetData; return this; } public Builder droidGuardResult(String droidGuardResult) { this.droidGuardResult = droidGuardResult; return this; } @Override public AttestRequest build() { return new AttestRequest(this); } } }
play-services-core/src/main/protos-java/org/microg/gms/snet/AttestResponse.java 0 → 100644 +62 −0 Original line number Diff line number Diff line // Code generated by Wire protocol buffer compiler, do not edit. // Source file: protos-repo/snet.proto package org.microg.gms.snet; import com.squareup.wire.Message; import com.squareup.wire.ProtoField; import static com.squareup.wire.Message.Datatype.STRING; public final class AttestResponse extends Message { public static final String DEFAULT_RESULT = ""; @ProtoField(tag = 2, type = STRING) public final String result; public AttestResponse(String result) { this.result = result; } private AttestResponse(Builder builder) { this(builder.result); setBuilder(builder); } @Override public boolean equals(Object other) { if (other == this) return true; if (!(other instanceof AttestResponse)) return false; return equals(result, ((AttestResponse) other).result); } @Override public int hashCode() { int result = hashCode; return result != 0 ? result : (hashCode = this.result != null ? this.result.hashCode() : 0); } public static final class Builder extends Message.Builder<AttestResponse> { public String result; public Builder() { } public Builder(AttestResponse message) { super(message); if (message == null) return; this.result = message.result; } public Builder result(String result) { this.result = result; return this; } @Override public AttestResponse build() { return new AttestResponse(this); } } }