diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b28819a08..9cbf22e37 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -111,12 +111,6 @@ android:configChanges="keyboardHidden|orientation|screenSize|locale" android:launchMode="singleInstance" /> - - - * - * Yalp Store - * Copyright (C) 2018 Sergey Yeriomin - * - * Aurora Store (a fork of Yalp Store )is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Aurora Store is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Aurora Store. If not, see . - */ - -package com.dragons.aurora.activities; - -import android.content.res.ColorStateList; -import android.os.Build; -import android.os.Bundle; -import android.support.v4.widget.ImageViewCompat; -import android.view.Display; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.TextView; - -import com.dragons.aurora.R; -import com.dragons.aurora.SpoofDeviceManager; -import com.dragons.aurora.fragment.PreferenceFragment; - -import java.util.Properties; -import java.util.TimeZone; - -public class DeviceActivity extends AuroraActivity { - String deviceName; - ImageView spoofed; - Display mDisplay; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - FrameLayout contentFrameLayout = (FrameLayout) findViewById(R.id.content_frame); - getLayoutInflater().inflate(R.layout.app_device_inc, contentFrameLayout); - - deviceName = PreferenceFragment.getString(this, PreferenceFragment.PREFERENCE_DEVICE_TO_PRETEND_TO_BE); - spoofed = (ImageView) findViewById(R.id.spoofed_indicator); - mDisplay = (this).getWindowManager().getDefaultDisplay(); - - if (isSpoofed()) - drawSpoofedDevice(); - else - drawDevice(); - } - - public boolean isSpoofed() { - return (deviceName.contains("device-")); - } - - public void drawDevice() { - ImageViewCompat.setImageTintList(spoofed, ColorStateList.valueOf((getResources().getColor(R.color.colorGreen)))); - setText(R.id.device_model, R.string.device_model, Build.MODEL, Build.DEVICE); - setText(R.id.device_manufacturer, R.string.device_manufacturer, Build.MANUFACTURER); - setText(R.id.device_architect, R.string.device_board, Build.BOARD); - setText(R.id.device_timezone, R.string.device_timezone, (CharSequence) TimeZone.getDefault().getDisplayName()); - setText(R.id.device_resolution, R.string.device_res, mDisplay.getWidth(), mDisplay.getHeight()); - setText(R.id.device_api, R.string.device_api, Build.VERSION.SDK); - setText(R.id.device_cpu, R.string.device_cpu, Build.CPU_ABI); - } - - public void drawSpoofedDevice() { - ImageViewCompat.setImageTintList(spoofed, ColorStateList.valueOf((getResources().getColor(R.color.colorRed)))); - - Properties properties = new SpoofDeviceManager(this).getProperties(deviceName); - String Model = properties.getProperty("UserReadableName"); - - setText(R.id.device_model, R.string.device_model, Model.substring(0, Model.indexOf('(')), properties.getProperty("Build.DEVICE")); - setText(R.id.device_manufacturer, R.string.device_manufacturer, properties.getProperty("Build.MANUFACTURER")); - setText(R.id.device_architect, R.string.device_board, properties.getProperty("Build.HARDWARE")); - setText(R.id.device_timezone, R.string.device_timezone, properties.getProperty("TimeZone")); - setText(R.id.device_resolution, R.string.device_res, properties.getProperty("Screen.Width"), properties.getProperty("Screen.Height")); - setText(R.id.device_api, R.string.device_api, properties.getProperty("Build.VERSION.SDK_INT")); - String Platforms = properties.getProperty("Platforms"); - setText(R.id.device_cpu, R.string.device_cpu, Platforms.substring(0, Platforms.indexOf(','))); - } - - protected void setText(int viewId, String text) { - TextView textView = (TextView) this.findViewById(viewId); - if (null != textView) - textView.setText(text); - } - - protected void setText(int viewId, int stringId, Object... text) { - setText(viewId, this.getString(stringId, text)); - } -} diff --git a/app/src/main/java/com/dragons/aurora/activities/DeviceInfoActivity.java b/app/src/main/java/com/dragons/aurora/activities/DeviceInfoActivity.java index 18c24979c..4f71dce4c 100644 --- a/app/src/main/java/com/dragons/aurora/activities/DeviceInfoActivity.java +++ b/app/src/main/java/com/dragons/aurora/activities/DeviceInfoActivity.java @@ -21,37 +21,60 @@ package com.dragons.aurora.activities; +import android.app.AlertDialog; import android.content.Intent; import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; import android.text.TextUtils; import android.util.Log; -import android.widget.TableLayout; -import android.widget.TableRow; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; +import com.dragons.aurora.ContextUtil; import com.dragons.aurora.R; import com.dragons.aurora.SpoofDeviceManager; +import com.dragons.aurora.Util; +import com.dragons.aurora.playstoreapiv2.PropertiesDeviceInfoProvider; +import com.dragons.aurora.view.PropCard; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.Properties; +import static com.dragons.aurora.fragment.PreferenceFragment.PREFERENCE_DEVICE_TO_PRETEND_TO_BE; +import static com.dragons.aurora.fragment.PreferenceFragment.PREFERENCE_DEVICE_TO_PRETEND_TO_BE_INDEX; + public class DeviceInfoActivity extends AuroraActivity { public static final String INTENT_DEVICE_NAME = "INTENT_DEVICE_NAME"; + public static final String INTENT_DEVICE_INDEX = "INTENT_DEVICE_INDEX"; + private String deviceName; + private int deviceIndex; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.deviceinfo_activity_layout); + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + getWindow().setStatusBarColor(getResources().getColor(R.color.semi_transparent)); onNewIntent(getIntent()); } + @Override + public void onBackPressed() { + super.onBackPressed(); + } + @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - String deviceName = intent.getStringExtra(INTENT_DEVICE_NAME); + deviceName = intent.getStringExtra(INTENT_DEVICE_NAME); + deviceIndex = intent.getIntExtra(INTENT_DEVICE_INDEX, 0); if (TextUtils.isEmpty(deviceName)) { Log.e(getClass().getSimpleName(), "No device name given"); finish(); @@ -59,35 +82,58 @@ public class DeviceInfoActivity extends AuroraActivity { } Properties properties = new SpoofDeviceManager(this).getProperties(deviceName); - setTitle(properties.getProperty("UserReadableName")); + ((TextView) findViewById(R.id.aurora_title)).setText(properties.getProperty("UserReadableName")); List keys = new ArrayList<>(); for (Object key : properties.keySet()) { keys.add((String) key); } - Collections.sort(keys); - TableLayout table = (TableLayout) findViewById(R.id.device_info); + Collections.sort(keys); + LinearLayout root = findViewById(R.id.device_info); for (String key : keys) { - addRow(table, key, ((String) properties.get(key)).replace(",", ", ")); + addCards(root, key, ((String) properties.get(key)).replace(",", ", ")); } + + setupButtons(); } - private void addRow(TableLayout parent, String key, String value) { - TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT); + private void addCards(LinearLayout root, String key, String value) { + root.addView(new PropCard(this, key, value)); + } - TextView textViewKey = new TextView(this); - textViewKey.setText(key); - textViewKey.setLayoutParams(rowParams); + private void setupButtons() { + ImageView toolbar_back = findViewById(R.id.toolbar_back); + toolbar_back.setOnClickListener(click -> onBackPressed()); - TextView textViewValue = new TextView(this); - textViewValue.setText(value); - textViewValue.setLayoutParams(rowParams); + FloatingActionButton incognito_fab = findViewById(R.id.incognito_fab); + incognito_fab.show(); + incognito_fab.setOnClickListener(click -> showConfirmationDialog()); + } - TableRow tableRow = new TableRow(this); - tableRow.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT)); - tableRow.addView(textViewKey); - tableRow.addView(textViewValue); + private boolean isDeviceDefinitionValid(String spoofDevice) { + PropertiesDeviceInfoProvider deviceInfoProvider = new PropertiesDeviceInfoProvider(); + deviceInfoProvider.setProperties(new SpoofDeviceManager(this).getProperties(spoofDevice)); + deviceInfoProvider.setLocaleString(Locale.getDefault().toString()); + return deviceInfoProvider.isValid(); + } - parent.addView(tableRow); + private void showConfirmationDialog() { + new AlertDialog.Builder(this) + .setMessage(R.string.pref_device_to_pretend_to_be_toast) + .setTitle(R.string.dialog_title_logout) + .setPositiveButton(R.string.action_logout, (dialogInterface, i) -> { + if (!TextUtils.isEmpty(deviceName) && !isDeviceDefinitionValid(deviceName)) { + ContextUtil.toast(this, R.string.error_invalid_device_definition); + } else { + Util.putString(this, PREFERENCE_DEVICE_TO_PRETEND_TO_BE, deviceName); + Util.putInteger(this, PREFERENCE_DEVICE_TO_PRETEND_TO_BE_INDEX, deviceIndex); + } + Util.completeCheckout(this); + dialogInterface.dismiss(); + startActivity(new Intent(this, LoginActivity.class)); + this.finish(); + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); } } diff --git a/app/src/main/java/com/dragons/aurora/activities/SpoofActivity.java b/app/src/main/java/com/dragons/aurora/activities/SpoofActivity.java index 485d193ce..81250a526 100644 --- a/app/src/main/java/com/dragons/aurora/activities/SpoofActivity.java +++ b/app/src/main/java/com/dragons/aurora/activities/SpoofActivity.java @@ -22,6 +22,7 @@ package com.dragons.aurora.activities; import android.os.Bundle; +import android.view.View; import com.dragons.aurora.R; import com.dragons.aurora.fragment.SpoofFragment; @@ -31,9 +32,10 @@ public class SpoofActivity extends AuroraActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - setContentView(R.layout.helper_activity); - + setContentView(R.layout.helper_activity_alt); + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + getWindow().setStatusBarColor(getResources().getColor(R.color.semi_transparent)); getSupportFragmentManager() .beginTransaction() .replace(R.id.content_frame, new SpoofFragment()) diff --git a/app/src/main/java/com/dragons/aurora/adapters/SingleRatingsAdapter.java b/app/src/main/java/com/dragons/aurora/adapters/SingleRatingsAdapter.java index f4044a7f3..b4464a1d6 100644 --- a/app/src/main/java/com/dragons/aurora/adapters/SingleRatingsAdapter.java +++ b/app/src/main/java/com/dragons/aurora/adapters/SingleRatingsAdapter.java @@ -118,7 +118,6 @@ public class SingleRatingsAdapter extends RecyclerView.Adapter { - checkOut(); - new PlayStoreApiAuthenticator(getContext()).logout(); + Util.completeCheckout(getContext()); dialogInterface.dismiss(); getActivity().finish(); startActivity(new Intent(getContext(), LoginActivity.class)); diff --git a/app/src/main/java/com/dragons/aurora/fragment/AccountsHelper.java b/app/src/main/java/com/dragons/aurora/fragment/AccountsHelper.java index 27748308d..f78a9f8ca 100755 --- a/app/src/main/java/com/dragons/aurora/fragment/AccountsHelper.java +++ b/app/src/main/java/com/dragons/aurora/fragment/AccountsHelper.java @@ -28,6 +28,7 @@ import android.support.v7.app.AlertDialog; import com.dragons.aurora.PlayStoreApiAuthenticator; import com.dragons.aurora.R; +import com.dragons.aurora.Util; import com.dragons.aurora.activities.LoginActivity; import com.dragons.aurora.task.AppProvidedCredentialsTask; import com.dragons.aurora.task.UserProvidedCredentialsTask; @@ -63,7 +64,7 @@ public abstract class AccountsHelper extends Fragment { public void switchDummy() { if (isLoggedIn()) - new PlayStoreApiAuthenticator(getContext()).logout(); + Util.completeCheckout(getContext()); AppProvidedCredentialsTask.LoginTask task = new AppProvidedCredentialsTask.LoginTask(getContext()); task.setContext(getContext()); @@ -77,7 +78,7 @@ public abstract class AccountsHelper extends Fragment { public void loginWithDummy() { if (isLoggedIn()) - new PlayStoreApiAuthenticator(getContext()).logout(); + Util.completeCheckout(getContext()); new AppProvidedCredentialsTask(getContext()).logInWithPredefinedAccount(); } diff --git a/app/src/main/java/com/dragons/aurora/fragment/PreferenceFragment.java b/app/src/main/java/com/dragons/aurora/fragment/PreferenceFragment.java index afa27d742..047062980 100644 --- a/app/src/main/java/com/dragons/aurora/fragment/PreferenceFragment.java +++ b/app/src/main/java/com/dragons/aurora/fragment/PreferenceFragment.java @@ -46,10 +46,8 @@ import com.dragons.aurora.Util; import com.dragons.aurora.activities.AuroraActivity; import com.dragons.aurora.fragment.preference.Blacklist; import com.dragons.aurora.fragment.preference.CheckUpdates; -import com.dragons.aurora.fragment.preference.Device; import com.dragons.aurora.fragment.preference.DownloadDirectory; import com.dragons.aurora.fragment.preference.InstallationMethod; -import com.dragons.aurora.fragment.preference.Language; public class PreferenceFragment extends android.preference.PreferenceFragment { @@ -62,7 +60,9 @@ public class PreferenceFragment extends android.preference.PreferenceFragment { public static final String PREFERENCE_BACKGROUND_UPDATE_WIFI_ONLY = "PREFERENCE_BACKGROUND_UPDATE_WIFI_ONLY"; public static final String PREFERENCE_BACKGROUND_UPDATE_INSTALL = "PREFERENCE_BACKGROUND_UPDATE_INSTALL"; public static final String PREFERENCE_REQUESTED_LANGUAGE = "PREFERENCE_REQUESTED_LANGUAGE"; + public static final String PREFERENCE_REQUESTED_LANGUAGE_INDEX = "PREFERENCE_REQUESTED_LANGUAGE_INDEX"; public static final String PREFERENCE_DEVICE_TO_PRETEND_TO_BE = "PREFERENCE_DEVICE_TO_PRETEND_TO_BE"; + public static final String PREFERENCE_DEVICE_TO_PRETEND_TO_BE_INDEX = "PREFERENCE_DEVICE_TO_PRETEND_TO_BE_INDEX"; public static final String PREFERENCE_INSTALLATION_METHOD = "PREFERENCE_INSTALLATION_METHOD"; public static final String PREFERENCE_NO_IMAGES = "PREFERENCE_NO_IMAGES"; public static final String PREFERENCE_DOWNLOAD_DIRECTORY = "PREFERENCE_DOWNLOAD_DIRECTORY"; @@ -112,9 +112,7 @@ public class PreferenceFragment extends android.preference.PreferenceFragment { setupThemes(getActivity()); setupSwitches(getActivity()); drawBlackList(); - drawLanguages(); drawUpdatesCheck(); - drawDevices(); drawInstallationMethod(); new DownloadDirectory(this).setPreference((EditTextPreference) findPreference(PREFERENCE_DOWNLOAD_DIRECTORY)).draw(); } @@ -143,18 +141,6 @@ public class PreferenceFragment extends android.preference.PreferenceFragment { checkUpdatesFragment.draw(); } - private void drawLanguages() { - Language languageFragment = new Language(this); - languageFragment.setListPreference((ListPreference) findPreference(PREFERENCE_REQUESTED_LANGUAGE)); - languageFragment.draw(); - } - - private void drawDevices() { - Device languageFragment = new Device(this); - languageFragment.setListPreference((ListPreference) findPreference(PREFERENCE_DEVICE_TO_PRETEND_TO_BE)); - languageFragment.draw(); - } - private void drawInstallationMethod() { InstallationMethod installationMethodFragment = new InstallationMethod(this); installationMethodFragment.setInstallationMethodPreference((ListPreference) findPreference(PREFERENCE_INSTALLATION_METHOD)); diff --git a/app/src/main/java/com/dragons/aurora/fragment/SpoofFragment.java b/app/src/main/java/com/dragons/aurora/fragment/SpoofFragment.java index d8f4657aa..ace16b850 100644 --- a/app/src/main/java/com/dragons/aurora/fragment/SpoofFragment.java +++ b/app/src/main/java/com/dragons/aurora/fragment/SpoofFragment.java @@ -21,30 +21,45 @@ package com.dragons.aurora.fragment; -import android.content.res.ColorStateList; +import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.v4.widget.ImageViewCompat; -import android.view.Display; +import android.support.v4.content.ContextCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; import android.widget.ImageView; +import android.widget.Spinner; import android.widget.TextView; +import com.dragons.aurora.PlayStoreApiAuthenticator; import com.dragons.aurora.R; import com.dragons.aurora.SpoofDeviceManager; +import com.dragons.aurora.Util; +import com.dragons.aurora.activities.DeviceInfoActivity; +import com.squareup.picasso.Picasso; +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; import java.util.Properties; -import java.util.TimeZone; + +import static com.dragons.aurora.fragment.PreferenceFragment.PREFERENCE_DEVICE_TO_PRETEND_TO_BE; +import static com.dragons.aurora.fragment.PreferenceFragment.PREFERENCE_DEVICE_TO_PRETEND_TO_BE_INDEX; +import static com.dragons.aurora.fragment.PreferenceFragment.PREFERENCE_REQUESTED_LANGUAGE; +import static com.dragons.aurora.fragment.PreferenceFragment.PREFERENCE_REQUESTED_LANGUAGE_INDEX; public class SpoofFragment extends UtilFragment { + static String LineageURl = "https://wiki.lineageos.org/images/devices/"; + private String deviceName; - private ImageView spoofed; - private Display mDisplay; - private View v; + private View view; @Override public void onCreate(Bundle savedInstanceState) { @@ -54,59 +69,146 @@ public class SpoofFragment extends UtilFragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - if (v != null) { - if ((ViewGroup) v.getParent() != null) - ((ViewGroup) v.getParent()).removeView(v); - return v; + if (view != null) { + if ((ViewGroup) view.getParent() != null) + ((ViewGroup) view.getParent()).removeView(view); + return view; } - v = inflater.inflate(R.layout.app_device_inc, container, false); - - deviceName = PreferenceFragment.getString(getActivity(), PreferenceFragment.PREFERENCE_DEVICE_TO_PRETEND_TO_BE); - spoofed = (ImageView) v.findViewById(R.id.spoofed_indicator); - mDisplay = (this).getActivity().getWindowManager().getDefaultDisplay(); + view = inflater.inflate(R.layout.fragment_spoof, container, false); if (isSpoofed()) drawSpoofedDevice(); else drawDevice(); - return v; + + setupLanguage(); + setupDevice(); + return view; + } + + @Override + public void onResume() { + super.onResume(); + if (isSpoofed()) + drawSpoofedDevice(); + else + drawDevice(); } public boolean isSpoofed() { + deviceName = PreferenceFragment.getString(getActivity(), PreferenceFragment.PREFERENCE_DEVICE_TO_PRETEND_TO_BE); return (deviceName.contains("device-")); } public void drawDevice() { - ImageViewCompat.setImageTintList(spoofed, ColorStateList.valueOf((getResources().getColor(R.color.colorGreen)))); + Picasso + .with(getContext()) + .load(LineageURl + Build.DEVICE + ".png") + .placeholder(ContextCompat.getDrawable(getContext(), R.drawable.ic_device)) + .into((ImageView) view.findViewById(R.id.device_avatar)); + setText(R.id.device_model, R.string.device_model, Build.MODEL, Build.DEVICE); - setText(R.id.device_manufacturer, R.string.device_manufacturer, Build.MANUFACTURER); - setText(R.id.device_architect, R.string.device_board, Build.BOARD); - setText(R.id.device_timezone, R.string.device_timezone, (CharSequence) TimeZone.getDefault().getDisplayName()); - setText(R.id.device_resolution, R.string.device_res, mDisplay.getWidth(), mDisplay.getHeight()); - setText(R.id.device_api, R.string.device_api, Build.VERSION.SDK); - setText(R.id.device_cpu, R.string.device_cpu, Build.CPU_ABI); + setText(R.id.device_manufacturer, Build.MANUFACTURER); + setText(R.id.device_architect, Build.BOARD); } public void drawSpoofedDevice() { - ImageViewCompat.setImageTintList(spoofed, ColorStateList.valueOf((getResources().getColor(R.color.colorRed)))); - Properties properties = new SpoofDeviceManager(this.getActivity()).getProperties(deviceName); String Model = properties.getProperty("UserReadableName"); + Picasso + .with(getContext()) + .load(LineageURl + properties.getProperty("Build.DEVICE") + ".png") + .placeholder(ContextCompat.getDrawable(getContext(), R.drawable.ic_device)) + .into((ImageView) view.findViewById(R.id.device_avatar)); + setText(R.id.device_model, R.string.device_model, Model.substring(0, Model.indexOf('(')), properties.getProperty("Build.DEVICE")); - setText(R.id.device_manufacturer, R.string.device_manufacturer, properties.getProperty("Build.MANUFACTURER")); - setText(R.id.device_architect, R.string.device_board, properties.getProperty("Build.HARDWARE")); - setText(R.id.device_timezone, R.string.device_timezone, properties.getProperty("TimeZone")); - setText(R.id.device_resolution, R.string.device_res, properties.getProperty("Screen.Width"), properties.getProperty("Screen.Height")); - setText(R.id.device_api, R.string.device_api, properties.getProperty("Build.VERSION.SDK_INT")); - String Platforms = properties.getProperty("Platforms"); - setText(R.id.device_cpu, R.string.device_cpu, Platforms.substring(0, Platforms.indexOf(','))); + setText(R.id.device_manufacturer, properties.getProperty("Build.MANUFACTURER")); + setText(R.id.device_architect, properties.getProperty("Build.HARDWARE")); } + void setupLanguage() { + Spinner spinner = (Spinner) view.findViewById(R.id.spoof_language); + Map locales = getLanguageKeyValueMap(); + String[] localeList = locales.values().toArray(new String[0]); + String[] localeKeys = locales.keySet().toArray(new String[0]); + + ArrayAdapter adapter = new ArrayAdapter<>( + getContext(), + android.R.layout.simple_spinner_item, + localeList + ); + + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + spinner.setSelection(Util.getInteger(getContext(), PREFERENCE_REQUESTED_LANGUAGE_INDEX), true); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if (position > 0) { + try { + new PlayStoreApiAuthenticator(getActivity()).getApi().setLocale(new Locale(localeKeys[position])); + Util.putString(getContext(), PREFERENCE_REQUESTED_LANGUAGE, localeKeys[position]); + Util.putInteger(getContext(), PREFERENCE_REQUESTED_LANGUAGE_INDEX, position); + } catch (IOException e) { + // Should be impossible to get to preferences with incorrect credentials + } + } + + if (position == 0) { + Util.putString(getContext(), PREFERENCE_REQUESTED_LANGUAGE, ""); + Util.putInteger(getContext(), PREFERENCE_REQUESTED_LANGUAGE_INDEX, 0); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } + + void setupDevice() { + Spinner spinner = view.findViewById(R.id.spoof_device); + Map devices = getDeviceKeyValueMap(); + + String[] deviceList = devices.values().toArray(new String[0]); + String[] deviceKeys = devices.keySet().toArray(new String[0]); + + ArrayAdapter adapter = new ArrayAdapter<>( + getContext(), + android.R.layout.simple_spinner_item, + deviceList + ); + + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + spinner.setSelection(Util.getInteger(getContext(), PREFERENCE_DEVICE_TO_PRETEND_TO_BE_INDEX), true); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if (position > 0) { + Intent i = new Intent(getContext(), DeviceInfoActivity.class); + i.putExtra(DeviceInfoActivity.INTENT_DEVICE_NAME, deviceKeys[position]); + i.putExtra(DeviceInfoActivity.INTENT_DEVICE_INDEX, position); + getContext().startActivity(i); + } + if (position == 0) { + Util.putString(getContext(), PREFERENCE_DEVICE_TO_PRETEND_TO_BE, ""); + Util.putInteger(getContext(), PREFERENCE_DEVICE_TO_PRETEND_TO_BE_INDEX, 0); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } protected void setText(int viewId, String text) { - TextView textView = (TextView) v.findViewById(viewId); + TextView textView = (TextView) view.findViewById(viewId); if (null != textView) textView.setText(text); } @@ -114,4 +216,28 @@ public class SpoofFragment extends UtilFragment { protected void setText(int viewId, int stringId, Object... text) { setText(viewId, this.getString(stringId, text)); } + + protected Map getDeviceKeyValueMap() { + Map devices = new SpoofDeviceManager(getContext()).getDevices(); + devices = Util.sort(devices); + Util.addToStart( + (LinkedHashMap) devices, + "", + view.getContext().getString(R.string.pref_device_to_pretend_to_be_default) + ); + return devices; + } + + protected Map getLanguageKeyValueMap() { + Map languages = new HashMap<>(); + for (Locale locale : Locale.getAvailableLocales()) { + String displayName = locale.getDisplayName(); + displayName = displayName.substring(0, 1).toUpperCase(Locale.getDefault()) + displayName.substring(1); + languages.put(locale.toString(), displayName); + } + languages = Util.sort(languages); + Util.addToStart((LinkedHashMap) languages, "", + getActivity().getString(R.string.pref_requested_language_default)); + return languages; + } } diff --git a/app/src/main/java/com/dragons/aurora/fragment/preference/Device.java b/app/src/main/java/com/dragons/aurora/fragment/preference/Device.java deleted file mode 100644 index 877ca2b44..000000000 --- a/app/src/main/java/com/dragons/aurora/fragment/preference/Device.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Aurora Store - * Copyright (C) 2018 Rahul Kumar Patel - * - * Yalp Store - * Copyright (C) 2018 Sergey Yeriomin - * - * Aurora Store (a fork of Yalp Store )is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Aurora Store is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Aurora Store. If not, see . - */ - -package com.dragons.aurora.fragment.preference; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.preference.Preference; -import android.preference.PreferenceManager; -import android.text.TextUtils; - -import com.dragons.aurora.ContextUtil; -import com.dragons.aurora.OnListPreferenceChangeListener; -import com.dragons.aurora.PlayStoreApiAuthenticator; -import com.dragons.aurora.R; -import com.dragons.aurora.SpoofDeviceManager; -import com.dragons.aurora.Util; -import com.dragons.aurora.activities.AuroraActivity; -import com.dragons.aurora.activities.DeviceInfoActivity; -import com.dragons.aurora.fragment.PreferenceFragment; -import com.dragons.aurora.playstoreapiv2.PropertiesDeviceInfoProvider; - -import java.util.LinkedHashMap; -import java.util.Locale; -import java.util.Map; - -public class Device extends List { - - private static final String PREFERENCE_DEVICE_DEFINITION_REQUESTED = "PREFERENCE_DEVICE_DEFINITION_REQUESTED"; - - public Device(PreferenceFragment activity) { - super(activity); - } - - @Override - public void draw() { - super.draw(); - listPreference.setOnPreferenceClickListener(preference -> { - ContextUtil.toast( - activity.getActivity().getApplicationContext(), - R.string.pref_device_to_pretend_to_be_notice, - PreferenceManager.getDefaultSharedPreferences(activity.getActivity()).getString(PreferenceFragment.PREFERENCE_DOWNLOAD_DIRECTORY, "") - ); - ((AlertDialog) listPreference.getDialog()).getListView().setOnItemLongClickListener((parent, v, position, id) -> { - if (position > 0) { - Intent i = new Intent(activity.getActivity(), DeviceInfoActivity.class); - i.putExtra(DeviceInfoActivity.INTENT_DEVICE_NAME, (String) keyValueMap.keySet().toArray()[position]); - activity.startActivity(i); - } - return false; - }); - return false; - }); - } - - @Override - protected OnListPreferenceChangeListener getOnListPreferenceChangeListener() { - OnListPreferenceChangeListener listener = new OnListPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (!TextUtils.isEmpty((String) newValue) && !isDeviceDefinitionValid((String) newValue)) { - ContextUtil.toast(activity.getActivity().getApplicationContext(), R.string.error_invalid_device_definition); - return false; - } - showLogOutDialog(); - return super.onPreferenceChange(preference, newValue); - } - }; - listener.setDefaultLabel(activity.getString(R.string.pref_device_to_pretend_to_be_default)); - return listener; - } - - @Override - protected Map getKeyValueMap() { - Map devices = new SpoofDeviceManager(activity.getActivity()).getDevices(); - devices = Util.sort(devices); - Util.addToStart( - (LinkedHashMap) devices, - "", - activity.getString(R.string.pref_device_to_pretend_to_be_default) - ); - return devices; - } - - private boolean isDeviceDefinitionValid(String spoofDevice) { - PropertiesDeviceInfoProvider deviceInfoProvider = new PropertiesDeviceInfoProvider(); - deviceInfoProvider.setProperties(new SpoofDeviceManager(activity.getActivity()).getProperties(spoofDevice)); - deviceInfoProvider.setLocaleString(Locale.getDefault().toString()); - return deviceInfoProvider.isValid(); - } - - private boolean showRequestDialog(boolean logOut) { - PreferenceManager.getDefaultSharedPreferences(activity.getActivity()) - .edit() - .putBoolean(PREFERENCE_DEVICE_DEFINITION_REQUESTED, true) - .apply() - ; - return true; - } - - private AlertDialog showLogOutDialog() { - return new AlertDialog.Builder(activity.getActivity()) - .setMessage(R.string.pref_device_to_pretend_to_be_toast) - .setTitle(R.string.dialog_title_logout) - .setPositiveButton(android.R.string.yes, new RequestOnClickListener(activity.getActivity(), true)) - .setNegativeButton(R.string.dialog_two_factor_cancel, new RequestOnClickListener(activity.getActivity(), false)) - .show() - ; - } - - private void finishAll() { - new PlayStoreApiAuthenticator(activity.getActivity().getApplicationContext()).logout(); - AuroraActivity.cascadeFinish(); - activity.getActivity().finish(); - } - - class RequestOnClickListener implements DialogInterface.OnClickListener { - - private boolean logOut; - private boolean askedAlready; - - public RequestOnClickListener(Activity activity, boolean logOut) { - askedAlready = PreferenceFragment.getBoolean(activity, PREFERENCE_DEVICE_DEFINITION_REQUESTED); - this.logOut = logOut; - } - - @Override - public void onClick(DialogInterface dialogInterface, int i) { - dialogInterface.dismiss(); - if (askedAlready) { - if (logOut) { - finishAll(); - } - } else { - showRequestDialog(logOut); - } - } - } - - class FinishingOnClickListener implements DialogInterface.OnClickListener { - - private boolean logOut; - - public FinishingOnClickListener(boolean logOut) { - this.logOut = logOut; - } - - @Override - public void onClick(DialogInterface dialogInterface, int i) { - dialogInterface.dismiss(); - if (logOut) { - finishAll(); - } - } - } -} diff --git a/app/src/main/java/com/dragons/aurora/fragment/preference/Language.java b/app/src/main/java/com/dragons/aurora/fragment/preference/Language.java deleted file mode 100644 index 90b008cfd..000000000 --- a/app/src/main/java/com/dragons/aurora/fragment/preference/Language.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Aurora Store - * Copyright (C) 2018 Rahul Kumar Patel - * - * Yalp Store - * Copyright (C) 2018 Sergey Yeriomin - * - * Aurora Store (a fork of Yalp Store )is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Aurora Store is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Aurora Store. If not, see . - */ - -package com.dragons.aurora.fragment.preference; - -import android.preference.Preference; - -import com.dragons.aurora.OnListPreferenceChangeListener; -import com.dragons.aurora.PlayStoreApiAuthenticator; -import com.dragons.aurora.R; -import com.dragons.aurora.Util; -import com.dragons.aurora.fragment.PreferenceFragment; - -import java.io.IOException; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Locale; -import java.util.Map; - -public class Language extends List { - - public Language(PreferenceFragment activity) { - super(activity); - } - - @Override - protected OnListPreferenceChangeListener getOnListPreferenceChangeListener() { - OnListPreferenceChangeListener listener = new OnListPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean result = super.onPreferenceChange(preference, newValue); - try { - new PlayStoreApiAuthenticator(activity.getActivity()).getApi().setLocale(new Locale((String) newValue)); - } catch (IOException e) { - // Should be impossible to get to preferences with incorrect credentials - } - return result; - } - }; - listener.setDefaultLabel(activity.getString(R.string.pref_requested_language_default)); - return listener; - } - - @Override - protected Map getKeyValueMap() { - Map languages = new HashMap<>(); - for (Locale locale : Locale.getAvailableLocales()) { - String displayName = locale.getDisplayName(); - displayName = displayName.substring(0, 1).toUpperCase(Locale.getDefault()) + displayName.substring(1); - languages.put(locale.toString(), displayName); - } - languages = Util.sort(languages); - Util.addToStart( - (LinkedHashMap) languages, - "", - activity.getString(R.string.pref_requested_language_default) - ); - return languages; - } -} diff --git a/app/src/main/java/com/dragons/aurora/fragment/preference/List.java b/app/src/main/java/com/dragons/aurora/fragment/preference/List.java deleted file mode 100644 index 5694bde3a..000000000 --- a/app/src/main/java/com/dragons/aurora/fragment/preference/List.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Aurora Store - * Copyright (C) 2018 Rahul Kumar Patel - * - * Yalp Store - * Copyright (C) 2018 Sergey Yeriomin - * - * Aurora Store (a fork of Yalp Store )is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Aurora Store is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Aurora Store. If not, see . - */ - -package com.dragons.aurora.fragment.preference; - -import android.os.AsyncTask; -import android.preference.ListPreference; - -import com.dragons.aurora.OnListPreferenceChangeListener; -import com.dragons.aurora.fragment.PreferenceFragment; - -import java.util.Map; - -public abstract class List extends Abstract { - - protected ListPreference listPreference; - protected Map keyValueMap; - - public List(PreferenceFragment activity) { - super(activity); - } - - abstract protected Map getKeyValueMap(); - - abstract protected OnListPreferenceChangeListener getOnListPreferenceChangeListener(); - - public void setListPreference(ListPreference listPreference) { - this.listPreference = listPreference; - } - - @Override - public void draw() { - new ListValuesTask(this, listPreference).execute(); - } - - static class ListValuesTask extends AsyncTask { - - private List list; - private ListPreference listPreference; - - public ListValuesTask(List list, ListPreference listPreference) { - this.list = list; - this.listPreference = listPreference; - } - - @Override - protected void onPreExecute() { - listPreference.setEntries(new String[0]); - listPreference.setEntryValues(new String[0]); - } - - @Override - protected void onPostExecute(Void aVoid) { - int count = list.keyValueMap.size(); - listPreference.setEntries(list.keyValueMap.values().toArray(new CharSequence[count])); - listPreference.setEntryValues(list.keyValueMap.keySet().toArray(new CharSequence[count])); - OnListPreferenceChangeListener listener = list.getOnListPreferenceChangeListener(); - listener.setKeyValueMap(list.keyValueMap); - listPreference.setOnPreferenceChangeListener(listener); - listener.setSummary(listPreference, listPreference.getValue()); - } - - @Override - protected Void doInBackground(Void... voids) { - list.keyValueMap = list.getKeyValueMap(); - return null; - } - } -} diff --git a/app/src/main/java/com/dragons/aurora/task/UserProvidedCredentialsTask.java b/app/src/main/java/com/dragons/aurora/task/UserProvidedCredentialsTask.java index 5da268206..6542949a0 100644 --- a/app/src/main/java/com/dragons/aurora/task/UserProvidedCredentialsTask.java +++ b/app/src/main/java/com/dragons/aurora/task/UserProvidedCredentialsTask.java @@ -123,7 +123,7 @@ public class UserProvidedCredentialsTask extends CheckCredentialsTask { if (checkBox.isChecked()) { setGooglePrefs(email, password); } - new PlayStoreApiAuthenticator(context).logout(); + Util.completeCheckout(context); getUserCredentialsTask().execute(email, password); }); diff --git a/app/src/main/java/com/dragons/aurora/task/playstore/CategoryListTask.java b/app/src/main/java/com/dragons/aurora/task/playstore/CategoryListTask.java index fc60e5df6..8c2cc5ad6 100644 --- a/app/src/main/java/com/dragons/aurora/task/playstore/CategoryListTask.java +++ b/app/src/main/java/com/dragons/aurora/task/playstore/CategoryListTask.java @@ -26,6 +26,7 @@ import android.text.TextUtils; import com.dragons.aurora.CategoryManager; import com.dragons.aurora.PlayStoreApiAuthenticator; +import com.dragons.aurora.fragment.PreferenceFragment; import com.dragons.aurora.playstoreapiv2.DocV2; import com.dragons.aurora.playstoreapiv2.GooglePlayAPI; import com.dragons.aurora.playstoreapiv2.ListResponse; @@ -74,9 +75,10 @@ public class CategoryListTask extends ExceptionTask { } private Locale getLocale(Context context) { - return new Locale.Builder() - .setLanguage(context.getResources().getConfiguration().locale.getLanguage()) - .setRegion(context.getResources().getConfiguration().locale.getCountry()) - .build(); + String locale = PreferenceFragment.getString(context, PreferenceFragment.PREFERENCE_REQUESTED_LANGUAGE); + if (TextUtils.isEmpty(locale)) + return Locale.getDefault(); + else + return new Locale(locale); } } \ No newline at end of file diff --git a/app/src/main/java/com/dragons/aurora/task/playstore/PlayStoreTask.java b/app/src/main/java/com/dragons/aurora/task/playstore/PlayStoreTask.java index 588d7f702..495e95da3 100644 --- a/app/src/main/java/com/dragons/aurora/task/playstore/PlayStoreTask.java +++ b/app/src/main/java/com/dragons/aurora/task/playstore/PlayStoreTask.java @@ -29,6 +29,7 @@ import com.dragons.aurora.ContextUtil; import com.dragons.aurora.CredentialsEmptyException; import com.dragons.aurora.PlayStoreApiAuthenticator; import com.dragons.aurora.R; +import com.dragons.aurora.Util; import com.dragons.aurora.fragment.PreferenceFragment; import com.dragons.aurora.playstoreapiv2.AuthException; import com.dragons.aurora.task.AppProvidedCredentialsTask; @@ -115,8 +116,8 @@ abstract public class PlayStoreTask extends TaskWithProgress { new AppProvidedCredentialsTask(context).refreshToken(); return; } else { - ContextUtil.toast(this.context, R.string.error_incorrect_password); - new PlayStoreApiAuthenticator(context).logout(); + ContextUtil.toast(context, R.string.error_incorrect_password); + Util.completeCheckout(context); } if (ContextUtil.isAlive(context)) { //Mehh! diff --git a/app/src/main/java/com/dragons/aurora/view/PropCard.java b/app/src/main/java/com/dragons/aurora/view/PropCard.java new file mode 100644 index 000000000..6c706da3a --- /dev/null +++ b/app/src/main/java/com/dragons/aurora/view/PropCard.java @@ -0,0 +1,58 @@ +/* + * Aurora Store + * Copyright (C) 2018 Rahul Kumar Patel + * + * Yalp Store + * Copyright (C) 2018 Sergey Yeriomin + * + * Aurora Store (a fork of Yalp Store )is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Aurora Store is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Aurora Store. If not, see . + */ + +package com.dragons.aurora.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.dragons.aurora.R; + +public class PropCard extends RelativeLayout { + + String key; + String value; + TextView card_key; + TextView card_value; + + public PropCard(Context context, String key, String value) { + super(context); + this.key = key; + this.value = value; + init(context); + } + + public PropCard(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + private void init(Context context) { + View view = inflate(context, R.layout.prop_card, this); + card_key = view.findViewById(R.id.prop_key); + card_value = view.findViewById(R.id.prop_value); + card_key.setText(key); + card_value.setText(value.isEmpty() ? "N/A" : value); + } +} diff --git a/app/src/main/res/drawable/ic_device.xml b/app/src/main/res/drawable/ic_device.xml index c3ffcfc17..69c3a5db0 100644 --- a/app/src/main/res/drawable/ic_device.xml +++ b/app/src/main/res/drawable/ic_device.xml @@ -1,28 +1,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/app/src/main/res/drawable/ic_incognito.xml b/app/src/main/res/drawable/ic_incognito.xml new file mode 100644 index 000000000..8380ffb98 --- /dev/null +++ b/app/src/main/res/drawable/ic_incognito.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_translate.xml b/app/src/main/res/drawable/ic_translate.xml new file mode 100644 index 000000000..b04075bbb --- /dev/null +++ b/app/src/main/res/drawable/ic_translate.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/app/src/main/res/layout/app_acc_inc.xml b/app/src/main/res/layout/app_acc_inc.xml index a1729fd89..4a37b7b11 100644 --- a/app/src/main/res/layout/app_acc_inc.xml +++ b/app/src/main/res/layout/app_acc_inc.xml @@ -1,5 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/deviceinfo_activity_layout.xml b/app/src/main/res/layout/deviceinfo_activity_layout.xml index d450055ee..9668aecde 100644 --- a/app/src/main/res/layout/deviceinfo_activity_layout.xml +++ b/app/src/main/res/layout/deviceinfo_activity_layout.xml @@ -18,14 +18,106 @@ ~ You should have received a copy of the GNU General Public License ~ along with Aurora Store. If not, see . --> - - - + android:layout_height="match_parent" + android:orientation="vertical"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_spoof.xml b/app/src/main/res/layout/fragment_spoof.xml new file mode 100644 index 000000000..bec2f5535 --- /dev/null +++ b/app/src/main/res/layout/fragment_spoof.xml @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/prop_card.xml b/app/src/main/res/layout/prop_card.xml new file mode 100644 index 000000000..b76ee7d31 --- /dev/null +++ b/app/src/main/res/layout/prop_card.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/nav_menu.xml b/app/src/main/res/menu/nav_menu.xml index ad7afbf8f..0bc53991f 100644 --- a/app/src/main/res/menu/nav_menu.xml +++ b/app/src/main/res/menu/nav_menu.xml @@ -32,4 +32,8 @@ android:id="@+id/action_settings" android:icon="@drawable/ic_settings" android:title="@string/action_settings" /> + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dd7892dc8..f0145c6e2 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -298,6 +298,8 @@ On Wi-Fi only Installation Spoofing + Spoof Device + Spoof Language User Interface Updates Delete .apk after installation diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index c6ff1b647..21b621d19 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -127,14 +127,4 @@ android:key="PREFERENCE_INSTALLATION_METHOD" android:title="@string/pref_installation_method" /> - - - - \ No newline at end of file