diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml
index 9fa1b31f..873c0c44 100644
--- a/play-services-core/src/main/AndroidManifest.xml
+++ b/play-services-core/src/main/AndroidManifest.xml
@@ -327,6 +327,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/play-services-core/src/main/java/org/microg/gms/ui/SelfCheckActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/SelfCheckActivity.java
new file mode 100644
index 00000000..31d8e569
--- /dev/null
+++ b/play-services-core/src/main/java/org/microg/gms/ui/SelfCheckActivity.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package org.microg.gms.ui;
+
+import org.microg.tools.selfcheck.AbstractSelfCheckActivity;
+import org.microg.tools.selfcheck.InstalledPackagesChecks;
+import org.microg.tools.selfcheck.RomSpoofSignatureChecks;
+import org.microg.tools.selfcheck.SelfCheckGroup;
+
+import java.util.List;
+
+public class SelfCheckActivity extends AbstractSelfCheckActivity implements SelfCheckGroup.ResultCollector {
+
+ protected void prepareSelfCheckList(List checks) {
+ checks.add(new RomSpoofSignatureChecks());
+ checks.add(new InstalledPackagesChecks());
+ }
+}
diff --git a/play-services-core/src/main/java/org/microg/tools/selfcheck/InstalledPackagesChecks.java b/play-services-core/src/main/java/org/microg/tools/selfcheck/InstalledPackagesChecks.java
new file mode 100644
index 00000000..ecb61fc7
--- /dev/null
+++ b/play-services-core/src/main/java/org/microg/tools/selfcheck/InstalledPackagesChecks.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+package org.microg.tools.selfcheck;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import com.google.android.gms.R;
+
+import org.microg.gms.common.Constants;
+import org.microg.gms.common.PackageUtils;
+import org.microg.tools.selfcheck.SelfCheckGroup;
+
+public class InstalledPackagesChecks implements SelfCheckGroup {
+
+ @Override
+ public String getGroupName(Context context) {
+ return "Installed packages";
+ }
+
+ @Override
+ public void doChecks(Context context, ResultCollector collector) {
+ addPackageInstalledAndSignedResult(context, collector, "Play Services (GmsCore)", Constants.GMS_PACKAGE_NAME, Constants.GMS_PACKAGE_SIGNATURE_SHA1);
+ addPackageInstalledAndSignedResult(context, collector, "Play Store (Phonesky)", "com.android.vending", Constants.GMS_PACKAGE_SIGNATURE_SHA1);
+ addPackageInstalledResult(context, collector, "Services Framework (GSF)", "com.google.android.gsf");
+ }
+
+ private void addPackageInstalledAndSignedResult(Context context, ResultCollector collector, String nicePackageName, String androidPackageName, String signatureHash) {
+ if (addPackageInstalledResult(context, collector, nicePackageName, androidPackageName)) {
+ addPackageSignedResult(context, collector, nicePackageName, androidPackageName, signatureHash);
+ }
+ }
+
+ private boolean addPackageSignedResult(Context context, ResultCollector collector, String nicePackageName, String androidPackageName, String signatureHash) {
+ boolean hashMatches = signatureHash.equals(PackageUtils.firstSignatureDigest(context, androidPackageName));
+ collector.addResult(context.getString(R.string.self_check_name_correct_sig, nicePackageName), hashMatches,
+ context.getString(R.string.self_check_resolution_correct_sig, nicePackageName));
+ return hashMatches;
+ }
+
+ private boolean addPackageInstalledResult(Context context, ResultCollector collector, String nicePackageName, String androidPackageName) {
+ boolean packageExists = true;
+ try {
+ context.getPackageManager().getPackageInfo(androidPackageName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ packageExists = false;
+ }
+ collector.addResult(context.getString(R.string.self_check_name_app_installed, nicePackageName), packageExists,
+ context.getString(R.string.self_check_resolution_app_installed, nicePackageName));
+ return packageExists;
+ }
+}
diff --git a/play-services-core/src/main/java/org/microg/tools/selfcheck/RomSpoofSignatureChecks.java b/play-services-core/src/main/java/org/microg/tools/selfcheck/RomSpoofSignatureChecks.java
new file mode 100644
index 00000000..b8925d27
--- /dev/null
+++ b/play-services-core/src/main/java/org/microg/tools/selfcheck/RomSpoofSignatureChecks.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+package org.microg.tools.selfcheck;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import com.google.android.gms.R;
+
+import org.microg.gms.common.Constants;
+import org.microg.gms.common.PackageUtils;
+import org.microg.tools.selfcheck.SelfCheckGroup;
+
+public class RomSpoofSignatureChecks implements SelfCheckGroup {
+
+ public static final String FAKE_SIGNATURE_PERMISSION = "android.permission.FAKE_PACKAGE_SIGNATURE";
+
+ @Override
+ public String getGroupName(Context context) {
+ return "ROM spoof signature support";
+ }
+
+ @Override
+ public void doChecks(Context context, ResultCollector collector) {
+ if (addRomKnowsFakeSignaturePermission(context, collector)) {
+ if (addSystemGrantsFakeSignaturePermission(context, collector)) {
+ addSystemSpoofsSignature(context, collector);
+ }
+ }
+ }
+
+ private boolean addRomKnowsFakeSignaturePermission(Context context, ResultCollector collector) {
+ boolean knowsPermission = true;
+ try {
+ context.getPackageManager().getPermissionInfo(FAKE_SIGNATURE_PERMISSION, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ knowsPermission = false;
+ }
+ collector.addResult(context.getString(R.string.self_check_name_fake_sig_perm), knowsPermission,
+ context.getString(R.string.self_check_resolution_fake_sig_perm));
+ return knowsPermission;
+ }
+
+ private boolean addSystemGrantsFakeSignaturePermission(Context context, ResultCollector collector) {
+ boolean grantsPermission = context.checkCallingOrSelfPermission(FAKE_SIGNATURE_PERMISSION) == PackageManager.PERMISSION_GRANTED;
+ collector.addResult(context.getString(R.string.self_check_name_perm_granted), grantsPermission,
+ context.getString(R.string.self_check_resolution_perm_granted));
+ return grantsPermission;
+ }
+
+ private boolean addSystemSpoofsSignature(Context context, ResultCollector collector) {
+ boolean spoofsSignature = Constants.GMS_PACKAGE_SIGNATURE_SHA1.equals(PackageUtils.firstSignatureDigest(context, Constants.GMS_PACKAGE_NAME));
+ collector.addResult(context.getString(R.string.self_check_name_system_spoofs), spoofsSignature,
+ context.getString(R.string.self_check_resolution_system_spoofs));
+ return spoofsSignature;
+ }
+}
diff --git a/play-services-core/src/main/res/values/strings.xml b/play-services-core/src/main/res/values/strings.xml
index 01bed68b..bae0049b 100644
--- a/play-services-core/src/main/res/values/strings.xml
+++ b/play-services-core/src/main/res/values/strings.xml
@@ -49,6 +49,21 @@ This can take a couple of minutes."
Trust Google for app permissions
When disabled, the user is asked before an apps authorization request is sent to Google. Some applications will fail to use the Google account if this is disabled.
+ Setup
+
+ microG Self-Check
+ Check if the system is correctly set up to use microG.
+ System has signature spoofing support:
+ You ROM has no native support for signature spoofing. You can still use Xposed or other systems to spoof signature. Please check the documentation on which ROMs do support signature spoofing and how to use microG on ROMs that do not.
+ System grants signature spoofing permission:
+ This is a strong indicator that the ROM does support signature spoofing, but requires further action to activate it. Please check the documentation on which steps might be required.
+ System spoofs signature:
+ This is a strong indicator that the ROM does support signature spoofing, but requires further action to activate it. Please check the documentation on which steps might be required.
+ %1$s installed:
+ Install the application %1$s or a compatible one. Please check the documentation on which applications are compatible.
+ %1$s has correct signature:
+ Either the installed %1$s is not compatible, signature spoofing is not enabled for it or your ROM does not properly support signature spoofing. Please check the documentation on which applications and ROMs are compatible.
+
Background services
checkin_enable_service
diff --git a/play-services-core/src/main/res/xml/gms_preferences.xml b/play-services-core/src/main/res/xml/gms_preferences.xml
index 53b650f1..081e1789 100644
--- a/play-services-core/src/main/res/xml/gms_preferences.xml
+++ b/play-services-core/src/main/res/xml/gms_preferences.xml
@@ -15,30 +15,39 @@
-->
+
+
+
+
+
+ android:title="@string/pref_checkin_enable_title"/>
+ android:title="@string/pref_gcm_enable_mcs_title"/>
+ android:title="@string/pref_gcm_heartbeat_title"/>
+ android:targetPackage="com.google.android.gms"/>