From a21958e13134f45cf8359b483108e7fe4b82dd10 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 11 Dec 2018 09:40:35 +0100 Subject: [PATCH] Moved power saver code to DeviceUtils class + removed Huawei mentions and made it more global --- .../java/org/linphone/LinphoneActivity.java | 88 +------- .../settings/LinphonePreferences.java | 8 +- .../linphone/settings/SettingsFragment.java | 18 +- .../java/org/linphone/utils/DeviceUtils.java | 213 ++++++++++++++++++ .../res/values/non_localizable_strings.xml | 2 +- app/src/main/res/values/strings.xml | 8 +- app/src/main/res/xml/preferences.xml | 2 +- 7 files changed, 235 insertions(+), 104 deletions(-) create mode 100644 app/src/main/java/org/linphone/utils/DeviceUtils.java diff --git a/app/src/main/java/org/linphone/LinphoneActivity.java b/app/src/main/java/org/linphone/LinphoneActivity.java index 50d39e7e3..2a1e47d14 100644 --- a/app/src/main/java/org/linphone/LinphoneActivity.java +++ b/app/src/main/java/org/linphone/LinphoneActivity.java @@ -27,7 +27,6 @@ import android.app.Dialog; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -51,7 +50,6 @@ import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.Button; -import android.widget.CheckBox; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; @@ -116,6 +114,7 @@ import org.linphone.recording.RecordingsFragment; import org.linphone.settings.AccountPreferencesFragment; import org.linphone.settings.LinphonePreferences; import org.linphone.settings.SettingsFragment; +import org.linphone.utils.DeviceUtils; import org.linphone.utils.LinphoneGenericActivity; import org.linphone.utils.LinphoneUtils; import org.linphone.views.AddressText; @@ -273,7 +272,9 @@ public class LinphoneActivity extends LinphoneGenericActivity // For push notifications to work on Huawei device, // app must be in "protected mode" in battery settings... // https://stackoverflow.com/questions/31638986/protected-apps-setting-on-huawei-phones-and-how-to-handle-it - displayDialogIfDeviceIsHuawei(); + DeviceUtils + .displayDialogIfDeviceHasPowerManagerThatCouldPreventPushNotifications( + LinphoneActivity.this); } } @@ -2009,87 +2010,6 @@ public class LinphoneActivity extends LinphoneGenericActivity return -1; } - private void displayDialogIfDeviceIsHuawei() { - if ("huawei".equalsIgnoreCase(android.os.Build.MANUFACTURER)) { - Log.w("[Hacks] Huawei device detected !"); - if (!LinphonePreferences.instance().hasHuaweiDialogBeenPrompted()) { - Log.w("[Hacks] Huawei device detected, asking for protected mode !"); - - final Dialog dialog = new Dialog(this); - dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.colorC)); - d.setAlpha(200); - dialog.setContentView(R.layout.dialog); - dialog.getWindow() - .setLayout( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.MATCH_PARENT); - dialog.getWindow().setBackgroundDrawable(d); - - TextView customText = dialog.findViewById(R.id.dialog_message); - customText.setText(R.string.huawei_protected_app_dialog_message); - - TextView customTitle = dialog.findViewById(R.id.dialog_title); - customTitle.setText(R.string.huawei_protected_app_dialog_title); - - dialog.findViewById(R.id.dialog_do_not_ask_again_layout) - .setVisibility(View.VISIBLE); - final CheckBox doNotAskAgain = dialog.findViewById(R.id.doNotAskAgain); - dialog.findViewById(R.id.doNotAskAgainLabel) - .setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View v) { - doNotAskAgain.setChecked(!doNotAskAgain.isChecked()); - } - }); - - Button accept = dialog.findViewById(R.id.dialog_ok_button); - accept.setVisibility(View.VISIBLE); - accept.setText(R.string.huawei_protected_app_dialog_button_go_to_settings); - accept.setOnClickListener( - new OnClickListener() { - @Override - public void onClick(View v) { - Log.w( - "[Hacks] Huawei device detected, user is going to battery settings :)"); - if (doNotAskAgain.isChecked()) { - LinphonePreferences.instance().huaweiDialogPrompted(true); - } - - Intent intent = new Intent(); - intent.setComponent( - new ComponentName( - "com.huawei.systemmanager", - "com.huawei.systemmanager.optimize.process.ProtectActivity")); - startActivity(intent); - dialog.dismiss(); - } - }); - - Button cancel = dialog.findViewById(R.id.dialog_cancel_button); - cancel.setText(R.string.huawei_protected_app_dialog_button_later); - cancel.setOnClickListener( - new OnClickListener() { - @Override - public void onClick(View v) { - Log.w( - "[Hacks] Huawei device detected, user didn't go to battery settings :("); - if (doNotAskAgain.isChecked()) { - LinphonePreferences.instance().huaweiDialogPrompted(true); - } - dialog.dismiss(); - } - }); - - Button delete = dialog.findViewById(R.id.dialog_delete_button); - delete.setVisibility(View.GONE); - - dialog.show(); - } - } - } - private class LocalOrientationEventListener extends OrientationEventListener { LocalOrientationEventListener(Context context) { super(context); diff --git a/app/src/main/java/org/linphone/settings/LinphonePreferences.java b/app/src/main/java/org/linphone/settings/LinphonePreferences.java index 0ed0ae07b..5797404e6 100644 --- a/app/src/main/java/org/linphone/settings/LinphonePreferences.java +++ b/app/src/main/java/org/linphone/settings/LinphonePreferences.java @@ -1400,12 +1400,12 @@ public class LinphonePreferences { getLc().setMaxSizeForAutoDownloadIncomingFiles(size); } - public boolean hasHuaweiDialogBeenPrompted() { - return getConfig().getBool("app", "huawei_protected_mode_dialog", false); + public boolean hasPowerSaverDialogBeenPrompted() { + return getConfig().getBool("app", "android_power_saver_dialog", false); } - public void huaweiDialogPrompted(boolean b) { - getConfig().setBool("app", "huawei_protected_mode_dialog", b); + public void powerSaverDialogPrompted(boolean b) { + getConfig().setBool("app", "android_power_saver_dialog", b); } public static class AccountBuilder { diff --git a/app/src/main/java/org/linphone/settings/SettingsFragment.java b/app/src/main/java/org/linphone/settings/SettingsFragment.java index 54d3892f1..4d4aacc23 100644 --- a/app/src/main/java/org/linphone/settings/SettingsFragment.java +++ b/app/src/main/java/org/linphone/settings/SettingsFragment.java @@ -21,7 +21,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import android.Manifest; import android.app.AlertDialog; -import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -64,6 +63,7 @@ import org.linphone.fragments.FragmentsAvailable; import org.linphone.mediastream.Log; import org.linphone.mediastream.Version; import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; +import org.linphone.utils.DeviceUtils; import org.linphone.utils.FileUtils; import org.linphone.utils.LinphoneUtils; import org.linphone.views.LedPreference; @@ -235,8 +235,8 @@ public class SettingsFragment extends PreferencesListFragment { hidePreference(R.string.pref_push_notification_key); } - if (!"huawei".equalsIgnoreCase(android.os.Build.MANUFACTURER)) { - hidePreference(R.string.pref_huawei_protected_settings_key); + if (!DeviceUtils.hasDevicePowerManager(LinphoneActivity.instance())) { + hidePreference(R.string.pref_device_power_saver_settings_key); } if (!Version.isVideoCapable() @@ -1629,17 +1629,15 @@ public class SettingsFragment extends PreferencesListFragment { } }); - findPreference(getString(R.string.pref_huawei_protected_settings_key)) + findPreference(getString(R.string.pref_device_power_saver_settings_key)) .setOnPreferenceClickListener( new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - LinphonePreferences.instance().huaweiDialogPrompted(true); - Intent intent = new Intent(); - intent.setComponent( - new ComponentName( - "com.huawei.systemmanager", - "com.huawei.systemmanager.optimize.process.ProtectActivity")); + LinphonePreferences.instance().powerSaverDialogPrompted(true); + Intent intent = + DeviceUtils.getDevicePowerManagerIntent( + LinphoneActivity.instance()); startActivity(intent); return true; } diff --git a/app/src/main/java/org/linphone/utils/DeviceUtils.java b/app/src/main/java/org/linphone/utils/DeviceUtils.java new file mode 100644 index 000000000..edf88ab28 --- /dev/null +++ b/app/src/main/java/org/linphone/utils/DeviceUtils.java @@ -0,0 +1,213 @@ +package org.linphone.utils; + +/* +DeviceUtils.java +Copyright (C) 2018 Belledonne Communications, Grenoble, France + +This program 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. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.app.Dialog; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.TextView; +import androidx.core.content.ContextCompat; +import java.util.List; +import org.linphone.R; +import org.linphone.mediastream.Log; +import org.linphone.settings.LinphonePreferences; + +public class DeviceUtils { + private static final Intent[] POWERMANAGER_INTENTS = { + new Intent() + .setComponent( + new ComponentName( + "com.miui.securitycenter", + "com.miui.permcenter.autostart.AutoStartManagementActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.letv.android.letvsafe", + "com.letv.android.letvsafe.AutobootManageActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.huawei.systemmanager", + "com.huawei.systemmanager.optimize.process.ProtectActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.huawei.systemmanager", + "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.coloros.safecenter", + "com.coloros.safecenter.permission.startup.StartupAppListActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.coloros.safecenter", + "com.coloros.safecenter.startupapp.StartupAppListActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.oppo.safe", + "com.oppo.safe.permission.startup.StartupAppListActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.iqoo.secure", + "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.iqoo.secure", + "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager")), + new Intent() + .setComponent( + new ComponentName( + "com.vivo.permissionmanager", + "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.samsung.android.lool", + "com.samsung.android.sm.ui.battery.BatteryActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.htc.pitroad", + "com.htc.pitroad.landingpage.activity.LandingPageActivity")), + new Intent() + .setComponent( + new ComponentName( + "com.asus.mobilemanager", "com.asus.mobilemanager.MainActivity")) + }; + + public static Intent getDevicePowerManagerIntent(Context context) { + for (Intent intent : POWERMANAGER_INTENTS) { + if (DeviceUtils.isIntentCallable(context, intent)) { + return intent; + } + } + return null; + } + + public static boolean hasDevicePowerManager(Context context) { + return getDevicePowerManagerIntent(context) != null; + } + + public static void displayDialogIfDeviceHasPowerManagerThatCouldPreventPushNotifications( + final Context context) { + for (final Intent intent : POWERMANAGER_INTENTS) { + if (DeviceUtils.isIntentCallable(context, intent)) { + Log.w( + "[Hacks] " + + android.os.Build.MANUFACTURER + + " device with power saver detected !"); + if (!LinphonePreferences.instance().hasPowerSaverDialogBeenPrompted()) { + Log.w("[Hacks] Asking power saver for whitelist !"); + + final Dialog dialog = new Dialog(context); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + Drawable d = new ColorDrawable(ContextCompat.getColor(context, R.color.colorC)); + d.setAlpha(200); + dialog.setContentView(R.layout.dialog); + dialog.getWindow() + .setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT); + dialog.getWindow().setBackgroundDrawable(d); + + TextView customText = dialog.findViewById(R.id.dialog_message); + customText.setText(R.string.device_power_saver_dialog_message); + + TextView customTitle = dialog.findViewById(R.id.dialog_title); + customTitle.setText(R.string.device_power_saver_dialog_title); + + dialog.findViewById(R.id.dialog_do_not_ask_again_layout) + .setVisibility(View.VISIBLE); + final CheckBox doNotAskAgain = dialog.findViewById(R.id.doNotAskAgain); + dialog.findViewById(R.id.doNotAskAgainLabel) + .setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + doNotAskAgain.setChecked(!doNotAskAgain.isChecked()); + } + }); + + Button accept = dialog.findViewById(R.id.dialog_ok_button); + accept.setVisibility(View.VISIBLE); + accept.setText(R.string.device_power_saver_dialog_button_go_to_settings); + accept.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.w( + "[Hacks] Power saver detected, user is going to settings :)"); + if (doNotAskAgain.isChecked()) { + LinphonePreferences.instance() + .powerSaverDialogPrompted(true); + } + + context.startActivity(intent); + dialog.dismiss(); + } + }); + + Button cancel = dialog.findViewById(R.id.dialog_cancel_button); + cancel.setText(R.string.device_power_saver_dialog_button_later); + cancel.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.w( + "[Hacks] Power saver detected, user didn't go to settings :("); + if (doNotAskAgain.isChecked()) { + LinphonePreferences.instance() + .powerSaverDialogPrompted(true); + } + dialog.dismiss(); + } + }); + + Button delete = dialog.findViewById(R.id.dialog_delete_button); + delete.setVisibility(View.GONE); + + dialog.show(); + } + } + } + } + + private static boolean isIntentCallable(Context context, Intent intent) { + List list = + context.getPackageManager() + .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); + return list.size() > 0; + } +} diff --git a/app/src/main/res/values/non_localizable_strings.xml b/app/src/main/res/values/non_localizable_strings.xml index eefc3d179..8cd2fbc72 100644 --- a/app/src/main/res/values/non_localizable_strings.xml +++ b/app/src/main/res/values/non_localizable_strings.xml @@ -83,7 +83,7 @@ pref_friendlist_subscribe_key pref_link_account_key pref_proxy_push_notif_key - pref_huawei_protected_settings_key + pref_huawei_protected_settings_key pref_echo_cancellation_key pref_autostart_key Outbound proxy diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9629ba62c..b77895331 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -492,10 +492,10 @@ Use Galaxy S audio hack - Huawei device detected! - It seems your device is a Huawei. In order for the app to be able to receive calls and messages while in background using push notifications, the protected toogle must be enabled in the settings. - Settings - Later + Power saver detected! + It seems your device has a power saver. In order for the app to be able to receive calls and messages while in background using push notifications, the app must be whitelisted. + Settings + Later Back diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index e8070e89d..a4eeeb24c 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -349,7 +349,7 @@ android:title="@string/pref_push_notification" />