mirror of
https://github.com/YTVanced/VancedMicroG
synced 2024-11-28 06:03:00 +00:00
sync
This commit is contained in:
parent
8595edcf0e
commit
02910572d7
21 changed files with 605 additions and 664 deletions
|
@ -1,49 +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 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);
|
||||
}
|
||||
}
|
|
@ -1,68 +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 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;
|
||||
}
|
||||
}
|
10
play-services-core/src/main/java/org/microg/gms/ui/AboutFragment.java
Normal file → Executable file
10
play-services-core/src/main/java/org/microg/gms/ui/AboutFragment.java
Normal file → Executable file
|
@ -18,7 +18,7 @@ package org.microg.gms.ui;
|
|||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.mgoogle.android.gms.BuildConfig;
|
||||
import com.google.android.gms.BuildConfig;
|
||||
|
||||
import org.microg.tools.ui.AbstractAboutFragment;
|
||||
import org.microg.tools.ui.AbstractSettingsActivity;
|
||||
|
@ -29,12 +29,18 @@ public class AboutFragment extends AbstractAboutFragment {
|
|||
|
||||
@Override
|
||||
protected void collectLibraries(List<AbstractAboutFragment.Library> libraries) {
|
||||
|
||||
if (BuildConfig.FLAVOR.contains("mapbox")) {
|
||||
libraries.add(new AbstractAboutFragment.Library("com.mapbox.mapboxsdk", "Mapbox Maps SDK for Android", "Three-Clause BSD, Mapbox"));
|
||||
} else {
|
||||
libraries.add(new AbstractAboutFragment.Library("org.oscim.android", "V™", "GNU LGPLv3, Hannes Janetzek and devemux86"));
|
||||
}
|
||||
libraries.add(new AbstractAboutFragment.Library("de.hdodenhof.circleimageview", "CircleImageView", "Apache License 2.0, Henning Dodenhof"));
|
||||
libraries.add(new AbstractAboutFragment.Library("su.litvak.chromecast.api.v2", "ChromeCast Java API v2", "Apache License 2.0, Vitaly Litvak"));
|
||||
libraries.add(new AbstractAboutFragment.Library("org.conscrypt", "Conscrypt", "Apache License 2.0, The Android Open Source Project"));
|
||||
libraries.add(new AbstractAboutFragment.Library("org.microg.safeparcel", "SafeParcel", "Apache License 2.0, microG Team"));
|
||||
libraries.add(new AbstractAboutFragment.Library("org.slf4j", "SLF4J", "MIT License, QOS.ch"));
|
||||
libraries.add(new AbstractAboutFragment.Library("org.microg.nlp.service", "UnifiedNlp", "Apache License 2.0, microG Team"));
|
||||
libraries.add(new AbstractAboutFragment.Library("org.microg.wearable", "Wearable", "Apache License 2.0, microG Team"));
|
||||
libraries.add(new AbstractAboutFragment.Library("com.squareup.wire", "Wire Protocol Buffers", "Apache License 2.0, Square Inc."));
|
||||
}
|
||||
|
||||
|
|
4
play-services-core/src/main/java/org/microg/gms/ui/AccountSettingsActivity.java
Normal file → Executable file
4
play-services-core/src/main/java/org/microg/gms/ui/AccountSettingsActivity.java
Normal file → Executable file
|
@ -25,7 +25,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.mgoogle.android.gms.R;
|
||||
import com.google.android.gms.R;
|
||||
|
||||
import org.microg.gms.auth.AuthConstants;
|
||||
import org.microg.gms.auth.AuthManager;
|
||||
|
@ -70,4 +70,4 @@ public class AccountSettingsActivity extends AbstractSettingsActivity {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
play-services-core/src/main/java/org/microg/gms/ui/AskPushPermission.java
Normal file → Executable file
2
play-services-core/src/main/java/org/microg/gms/ui/AskPushPermission.java
Normal file → Executable file
|
@ -10,7 +10,7 @@ import android.widget.TextView;
|
|||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.mgoogle.android.gms.R;
|
||||
import com.google.android.gms.R;
|
||||
|
||||
import org.microg.gms.gcm.GcmDatabase;
|
||||
import org.microg.gms.gcm.PushRegisterService;
|
||||
|
|
34
play-services-core/src/main/java/org/microg/gms/ui/Conditions.java
Normal file → Executable file
34
play-services-core/src/main/java/org/microg/gms/ui/Conditions.java
Normal file → Executable file
|
@ -28,7 +28,7 @@ import android.view.View;
|
|||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.mgoogle.android.gms.R;
|
||||
import com.google.android.gms.R;
|
||||
|
||||
import org.microg.gms.gcm.GcmPrefs;
|
||||
import org.microg.tools.ui.Condition;
|
||||
|
@ -64,4 +64,36 @@ public class Conditions {
|
|||
v.getContext().startActivity(intent);
|
||||
}
|
||||
}).build();
|
||||
|
||||
private static final String[] REQUIRED_PERMISSIONS = new String[]{ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE, GET_ACCOUNTS, READ_PHONE_STATE};
|
||||
public static final Condition PERMISSIONS = new Condition.Builder()
|
||||
.title(R.string.cond_perm_title)
|
||||
.summaryPlurals(R.plurals.cond_perm_summary)
|
||||
.evaluation(new Condition.Evaluation() {
|
||||
int count = 0;
|
||||
@Override
|
||||
public boolean isActive(Context context) {
|
||||
count = 0;
|
||||
if (SDK_INT >= Build.VERSION_CODES.M) {
|
||||
for (String permission : REQUIRED_PERMISSIONS) {
|
||||
if (ContextCompat.checkSelfPermission(context, permission) != PERMISSION_GRANTED)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPluralsCount() {
|
||||
return count;
|
||||
}
|
||||
})
|
||||
.firstActionPlurals(R.plurals.cond_perm_action, new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.getContext() instanceof Activity) {
|
||||
ActivityCompat.requestPermissions((Activity) v.getContext(), REQUIRED_PERMISSIONS, 0);
|
||||
}
|
||||
}
|
||||
}).build();
|
||||
}
|
||||
|
|
2
play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java
Normal file → Executable file
2
play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java
Normal file → Executable file
|
@ -23,7 +23,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.mgoogle.android.gms.R;
|
||||
import com.google.android.gms.R;
|
||||
|
||||
import org.microg.gms.gcm.GcmPrefs;
|
||||
import org.microg.gms.gcm.McsService;
|
||||
|
|
|
@ -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.mgoogle.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<GcmDatabase.Registration> 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<GcmDatabase.Registration> 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<GcmDatabase.Registration> 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.mgoogle.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<Preference> prefs, PreferenceGroup container) {
|
||||
// If there's some items to display, sort the items and add them to the container.
|
||||
Collections.sort(prefs, new Comparator<Preference>() {
|
||||
@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<GcmDatabase.App> list = database.getAppList();
|
||||
if (!list.isEmpty()) {
|
||||
List<Preference> 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<GcmDatabase.Registration> 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();
|
||||
}
|
||||
}
|
||||
}
|
2
play-services-core/src/main/java/org/microg/gms/ui/GoogleMoreFragment.java
Normal file → Executable file
2
play-services-core/src/main/java/org/microg/gms/ui/GoogleMoreFragment.java
Normal file → Executable file
|
@ -16,7 +16,7 @@
|
|||
|
||||
package org.microg.gms.ui;
|
||||
|
||||
import com.mgoogle.android.gms.R;
|
||||
import com.google.android.gms.R;
|
||||
|
||||
import org.microg.tools.ui.AbstractSettingsActivity;
|
||||
|
||||
|
|
0
play-services-core/src/main/java/org/microg/gms/ui/LocationSettingsActivity.java
Normal file → Executable file
0
play-services-core/src/main/java/org/microg/gms/ui/LocationSettingsActivity.java
Normal file → Executable file
254
play-services-core/src/main/java/org/microg/gms/ui/PlacePickerActivity.java
Executable file
254
play-services-core/src/main/java/org/microg/gms/ui/PlacePickerActivity.java
Executable file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2019 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.location.Address;
|
||||
import android.location.Geocoder;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
|
||||
import com.google.android.gms.R;
|
||||
import com.google.android.gms.common.api.CommonStatusCodes;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.location.places.internal.PlaceImpl;
|
||||
import com.google.android.gms.maps.model.LatLng;
|
||||
import com.google.android.gms.maps.model.LatLngBounds;
|
||||
|
||||
import org.microg.gms.location.LocationConstants;
|
||||
//import org.microg.gms.maps.vtm.BackendMapView;
|
||||
//import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
|
||||
import org.microg.safeparcel.SafeParcelUtil;
|
||||
//import org.oscim.core.MapPosition;
|
||||
//import org.oscim.event.Event;
|
||||
//import org.oscim.map.Map;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
|
||||
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static org.microg.gms.location.LocationConstants.EXTRA_PRIMARY_COLOR;
|
||||
import static org.microg.gms.location.LocationConstants.EXTRA_PRIMARY_COLOR_DARK;
|
||||
//import static org.microg.gms.maps.vtm.GmsMapsTypeHelper.fromLatLngBounds;
|
||||
|
||||
public class
|
||||
|
||||
|
||||
PlacePickerActivity extends AppCompatActivity /*implements Map.UpdateListener*/ {
|
||||
private static final String TAG = "GmsPlacePicker";
|
||||
|
||||
private PlaceImpl place;
|
||||
// private BackendMapView mapView;
|
||||
private Intent resultIntent;
|
||||
private AtomicBoolean geocoderInProgress = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
resultIntent = new Intent();
|
||||
place = new PlaceImpl();
|
||||
|
||||
setContentView(R.layout.pick_place);
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||
|
||||
if (getIntent().hasExtra(EXTRA_PRIMARY_COLOR)) {
|
||||
toolbar.setBackgroundColor(getIntent().getIntExtra(EXTRA_PRIMARY_COLOR, 0));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
getWindow().setStatusBarColor(getIntent().getIntExtra(EXTRA_PRIMARY_COLOR_DARK, 0));
|
||||
((TextView) findViewById(R.id.place_picker_title)).setTextColor(getIntent().getIntExtra(EXTRA_PRIMARY_COLOR_DARK, 0));
|
||||
}
|
||||
|
||||
// mapView = (BackendMapView) findViewById(R.id.map);
|
||||
// mapView.map().getEventLayer().enableRotation(false);
|
||||
// mapView.map().getEventLayer().enableTilt(false);
|
||||
// mapView.map().events.bind(this);
|
||||
|
||||
LatLngBounds latLngBounds = getIntent().getParcelableExtra(LocationConstants.EXTRA_BOUNDS);
|
||||
if (latLngBounds != null) {
|
||||
place.viewport = latLngBounds;
|
||||
// MapPosition mp = new MapPosition();
|
||||
// mp.setByBoundingBox(fromLatLngBounds(latLngBounds), mapView.map().getWidth(), mapView.map().getHeight());
|
||||
// mapView.map().getMapPosition(mp);
|
||||
} else {
|
||||
if (ActivityCompat.checkSelfPermission(PlacePickerActivity.this, ACCESS_FINE_LOCATION) != PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(PlacePickerActivity.this, new String[]{ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}, 0);
|
||||
} else {
|
||||
updateMapFromLocationManager();
|
||||
}
|
||||
}
|
||||
|
||||
findViewById(R.id.place_picker_select).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
resultIntent.putExtra(LocationConstants.EXTRA_STATUS, SafeParcelUtil.asByteArray(new Status(CommonStatusCodes.SUCCESS)));
|
||||
resultIntent.putExtra(LocationConstants.EXTRA_PLACE, SafeParcelUtil.asByteArray(place));
|
||||
resultIntent.putExtra(LocationConstants.EXTRA_FINAL_BOUNDS, SafeParcelUtil.asByteArray(place.viewport));
|
||||
setResult(RESULT_OK, resultIntent);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("MissingPermission")
|
||||
private void updateMapFromLocationManager() {
|
||||
LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
|
||||
Location last = null;
|
||||
for (String provider : lm.getAllProviders()) {
|
||||
if (lm.isProviderEnabled(provider)) {
|
||||
Location t = lm.getLastKnownLocation(provider);
|
||||
if (t != null && (last == null || t.getTime() > last.getTime())) {
|
||||
last = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "Set location to " + last);
|
||||
if (last != null) {
|
||||
// mapView.map().setMapPosition(new MapPosition(last.getLatitude(), last.getLongitude(), 4096));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
if (requestCode == 0) {
|
||||
for (int grantResult : grantResults) {
|
||||
if (grantResult != PERMISSION_GRANTED) return;
|
||||
}
|
||||
updateMapFromLocationManager();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.pick_place, menu);
|
||||
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_action_search));
|
||||
// TODO: search
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
// mapView.onPause();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public void onMapEvent(Event event, MapPosition position) {
|
||||
// place.viewport = GmsMapsTypeHelper.toLatLngBounds(mapView.map().viewport().getBBox(null, 0));
|
||||
// resultIntent.putExtra(LocationConstants.EXTRA_FINAL_BOUNDS, place.viewport);
|
||||
// place.latLng = GmsMapsTypeHelper.toLatLng(position.getGeoPoint());
|
||||
place.name = "";
|
||||
place.address = "";
|
||||
updateInfoText();
|
||||
if (geocoderInProgress.compareAndSet(false, true)) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
LatLng ll = null;
|
||||
while (ll != place.latLng) {
|
||||
ll = place.latLng;
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
Geocoder geocoder = new Geocoder(PlacePickerActivity.this);
|
||||
List<Address> addresses = geocoder.getFromLocation(place.latLng.latitude, place.latLng.longitude, 1);
|
||||
if (addresses != null && !addresses.isEmpty() && addresses.get(0).getMaxAddressLineIndex() > 0) {
|
||||
Address address = addresses.get(0);
|
||||
StringBuilder sb = new StringBuilder(address.getAddressLine(0));
|
||||
for (int i = 1; i < address.getMaxAddressLineIndex(); ++i) {
|
||||
if (i == 1 && sb.toString().equals(address.getFeatureName())) {
|
||||
sb = new StringBuilder(address.getAddressLine(i));
|
||||
continue;
|
||||
}
|
||||
sb.append(", ").append(address.getAddressLine(i));
|
||||
}
|
||||
if (place.latLng == ll) {
|
||||
place.address = sb.toString();
|
||||
place.name = address.getFeatureName();
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateInfoText();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
Log.w(TAG, ignored);
|
||||
} finally {
|
||||
geocoderInProgress.lazySet(false);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}*/
|
||||
|
||||
private void updateInfoText() {
|
||||
if (TextUtils.isEmpty(place.address)) {
|
||||
((TextView) findViewById(R.id.place_picker_info)).setText(getString(R.string.place_picker_location_lat_lng, place.latLng.latitude, place.latLng.longitude));
|
||||
} else if (TextUtils.isEmpty(place.name)) {
|
||||
((TextView) findViewById(R.id.place_picker_info)).setText(place.address);
|
||||
} else {
|
||||
((TextView) findViewById(R.id.place_picker_info)).setText(Html.fromHtml("<b>" + place.name + "</b>, " + place.address));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.google.android.gms.R;
|
||||
|
||||
import org.microg.tools.ui.AbstractSettingsActivity;
|
||||
import org.microg.tools.ui.RadioButtonPreference;
|
||||
import org.microg.tools.ui.ResourceSettingsFragment;
|
||||
|
||||
import static org.microg.gms.snet.SafetyNetPrefs.PREF_SNET_OFFICIAL;
|
||||
import static org.microg.gms.snet.SafetyNetPrefs.PREF_SNET_SELF_SIGNED;
|
||||
import static org.microg.gms.snet.SafetyNetPrefs.PREF_SNET_THIRD_PARTY;
|
||||
|
||||
public class SafetyNetAdvancedFragment extends ResourceSettingsFragment {
|
||||
|
||||
public SafetyNetAdvancedFragment() {
|
||||
preferencesResource = R.xml.preferences_snet_advanced;
|
||||
}
|
||||
|
||||
private RadioButtonPreference radioOfficial;
|
||||
private RadioButtonPreference radioSelfSigned;
|
||||
private RadioButtonPreference radioThirdParty;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
|
||||
super.onCreatePreferences(savedInstanceState, rootKey);
|
||||
|
||||
radioOfficial = (RadioButtonPreference) findPreference(PREF_SNET_OFFICIAL);
|
||||
radioSelfSigned = (RadioButtonPreference) findPreference(PREF_SNET_SELF_SIGNED);
|
||||
radioThirdParty = (RadioButtonPreference) findPreference(PREF_SNET_THIRD_PARTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(Preference preference) {
|
||||
if (preference == radioOfficial) {
|
||||
radioOfficial.setChecked(true);
|
||||
radioSelfSigned.setChecked(false);
|
||||
radioThirdParty.setChecked(false);
|
||||
return true;
|
||||
} else if (preference == radioSelfSigned) {
|
||||
radioOfficial.setChecked(false);
|
||||
radioSelfSigned.setChecked(true);
|
||||
radioThirdParty.setChecked(false);
|
||||
return true;
|
||||
} else if (preference == radioThirdParty) {
|
||||
radioOfficial.setChecked(false);
|
||||
radioSelfSigned.setChecked(false);
|
||||
radioThirdParty.setChecked(true);
|
||||
return true;
|
||||
}
|
||||
return super.onPreferenceTreeClick(preference);
|
||||
}
|
||||
|
||||
public static class AsActivity extends AbstractSettingsActivity {
|
||||
public AsActivity() {
|
||||
showHomeAsUp = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Fragment getFragment() {
|
||||
return new SafetyNetAdvancedFragment();
|
||||
}
|
||||
}
|
||||
}
|
4
play-services-core/src/main/java/org/microg/gms/ui/SelfCheckFragment.java
Normal file → Executable file
4
play-services-core/src/main/java/org/microg/gms/ui/SelfCheckFragment.java
Normal file → Executable file
|
@ -23,9 +23,11 @@ import android.view.LayoutInflater;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.microg.tools.selfcheck.InstalledPackagesChecks;
|
||||
//import org.microg.tools.selfcheck.NlpOsCompatChecks;
|
||||
//import org.microg.tools.selfcheck.NlpStatusChecks;
|
||||
import org.microg.tools.selfcheck.PermissionCheckGroup;
|
||||
import org.microg.tools.selfcheck.RomSpoofSignatureChecks;
|
||||
import org.microg.tools.selfcheck.SelfCheckGroup;
|
||||
import org.microg.tools.selfcheck.SystemChecks;
|
||||
import org.microg.tools.ui.AbstractSelfCheckFragment;
|
||||
|
@ -44,6 +46,8 @@ public class SelfCheckFragment extends AbstractSelfCheckFragment {
|
|||
|
||||
@Override
|
||||
protected void prepareSelfCheckList(List<SelfCheckGroup> checks) {
|
||||
checks.add(new RomSpoofSignatureChecks());
|
||||
checks.add(new InstalledPackagesChecks());
|
||||
if (SDK_INT > LOLLIPOP_MR1) {
|
||||
checks.add(new PermissionCheckGroup(ACCESS_COARSE_LOCATION, "android.permission.ACCESS_BACKGROUND_LOCATION", WRITE_EXTERNAL_STORAGE, GET_ACCOUNTS, READ_PHONE_STATE));
|
||||
}
|
||||
|
|
92
play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java
Normal file → Executable file
92
play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java
Normal file → Executable file
|
@ -1,88 +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 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.mgoogle.android.gms.R;
|
||||
import com.google.android.gms.R;
|
||||
|
||||
import org.microg.gms.gcm.GcmDatabase;
|
||||
import org.microg.gms.gcm.GcmPrefs;
|
||||
import org.microg.tools.ui.AbstractDashboardActivity;
|
||||
import org.microg.tools.ui.ResourceSettingsFragment;
|
||||
public class SettingsActivity extends AppCompatActivity {
|
||||
private AppBarConfiguration appBarConfiguration;
|
||||
|
||||
public class SettingsActivity extends AbstractDashboardActivity {
|
||||
|
||||
public SettingsActivity() {
|
||||
preferencesResource = R.xml.preferences_start;
|
||||
addCondition(Conditions.GCM_BATTERY_OPTIMIZATIONS);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// 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));
|
||||
|
||||
}
|
||||
@Override
|
||||
public boolean onSupportNavigateUp() {
|
||||
return NavigationUI.navigateUp(getNavController(), appBarConfiguration) || super.onSupportNavigateUp();
|
||||
}
|
||||
}
|
||||
|
|
0
play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java
Normal file → Executable file
0
play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java
Normal file → Executable file
45
play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java
Normal file → Executable file
45
play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java
Normal file → Executable file
|
@ -5,16 +5,21 @@ import android.os.Bundle;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
|
||||
import com.mgoogle.android.gms.R;
|
||||
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;
|
||||
|
@ -50,5 +55,43 @@ public class SettingsFragment extends ResourceSettingsFragment {
|
|||
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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
0
play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java
Normal file → Executable file
0
play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java
Normal file → Executable file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.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 static org.microg.tools.selfcheck.SelfCheckGroup.Result.Negative;
|
||||
import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Positive;
|
||||
|
||||
public class InstalledPackagesChecks implements SelfCheckGroup {
|
||||
|
||||
@Override
|
||||
public String getGroupName(Context context) {
|
||||
return context.getString(R.string.self_check_cat_gms_packages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doChecks(Context context, ResultCollector collector) {
|
||||
addPackageInstalledAndSignedResult(context, collector, context.getString(R.string.self_check_pkg_gms), Constants.GMS_PACKAGE_NAME, Constants.GMS_PACKAGE_SIGNATURE_SHA1);
|
||||
addPackageInstalledAndSignedResult(context, collector, context.getString(R.string.self_check_pkg_vending), "com.android.vending", Constants.GMS_PACKAGE_SIGNATURE_SHA1);
|
||||
addPackageInstalledResult(context, collector, context.getString(R.string.self_check_pkg_gsf), Constants.GSF_PACKAGE_NAME);
|
||||
}
|
||||
|
||||
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 ? Positive : Negative,
|
||||
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 ? Positive : Negative,
|
||||
context.getString(R.string.self_check_resolution_app_installed, nicePackageName));
|
||||
return packageExists;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.tools.selfcheck;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.gms.R;
|
||||
|
||||
import org.microg.gms.common.Constants;
|
||||
import org.microg.gms.common.PackageUtils;
|
||||
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static org.microg.gms.common.Constants.GMS_PACKAGE_SIGNATURE_SHA1;
|
||||
import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Negative;
|
||||
import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Positive;
|
||||
import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Unknown;
|
||||
|
||||
public class RomSpoofSignatureChecks implements SelfCheckGroup {
|
||||
|
||||
public static final String FAKE_SIGNATURE_PERMISSION = "android.permission.FAKE_PACKAGE_SIGNATURE";
|
||||
|
||||
@Override
|
||||
public String getGroupName(Context context) {
|
||||
return context.getString(R.string.self_check_cat_fake_sig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doChecks(Context context, ResultCollector collector) {
|
||||
boolean hasPermission = addRomKnowsFakeSignaturePermission(context, collector);
|
||||
if (hasPermission) {
|
||||
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 ? Positive : Unknown,
|
||||
context.getString(R.string.self_check_resolution_fake_sig_perm));
|
||||
return knowsPermission;
|
||||
}
|
||||
|
||||
private boolean addSystemGrantsFakeSignaturePermission(Context context, ResultCollector collector) {
|
||||
boolean grantsPermission = ContextCompat.checkSelfPermission(context, FAKE_SIGNATURE_PERMISSION) == PERMISSION_GRANTED;
|
||||
collector.addResult(context.getString(R.string.self_check_name_perm_granted), grantsPermission ? Positive : Negative,
|
||||
context.getString(R.string.self_check_resolution_perm_granted), new CheckResolver() {
|
||||
@Override
|
||||
public void tryResolve(Fragment fragment) {
|
||||
fragment.requestPermissions(new String[]{FAKE_SIGNATURE_PERMISSION}, 0);
|
||||
}
|
||||
});
|
||||
return grantsPermission;
|
||||
}
|
||||
|
||||
private boolean addSystemSpoofsSignature(Context context, ResultCollector collector) {
|
||||
boolean spoofsSignature = GMS_PACKAGE_SIGNATURE_SHA1.equals(PackageUtils.firstSignatureDigest(context, Constants.GMS_PACKAGE_NAME));
|
||||
collector.addResult(context.getString(R.string.self_check_name_system_spoofs), spoofsSignature ? Positive : Negative,
|
||||
context.getString(R.string.self_check_resolution_system_spoofs));
|
||||
return spoofsSignature;
|
||||
}
|
||||
}
|
2
play-services-core/src/main/java/org/microg/tools/selfcheck/SystemChecks.java
Normal file → Executable file
2
play-services-core/src/main/java/org/microg/tools/selfcheck/SystemChecks.java
Normal file → Executable file
|
@ -25,7 +25,7 @@ import android.provider.Settings;
|
|||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.mgoogle.android.gms.R;
|
||||
import com.google.android.gms.R;
|
||||
|
||||
import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Negative;
|
||||
import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Positive;
|
||||
|
|
Loading…
Reference in a new issue