diff options
author | alk3pInjection <webmaster@raspii.tech> | 2023-01-18 16:40:30 +0800 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2023-01-18 16:40:30 +0800 |
commit | 15ac9dd4c3ec87af302104c033f0645ab5d292d0 (patch) | |
tree | cf3094df629d91b9abc4cc17aaf4bf2d7593e8a6 | |
parent | 088f23b5f8b78746b8b868e292cfeb5361279e68 (diff) |
Revert^2 "All the Izat icon changes"
This reverts commit 9e65bcfd047bd026f043eb6a2551f9b8e38345dc.
Change-Id: If77b16e7c0403bca0a881f7de3dea2b66b510909
-rw-r--r-- | src/com/android/settings/location/AppSettingsInjector.java | 33 | ||||
-rw-r--r-- | src/com/android/settings/location/DimmableIZatIconPreference.java | 243 |
2 files changed, 274 insertions, 2 deletions
diff --git a/src/com/android/settings/location/AppSettingsInjector.java b/src/com/android/settings/location/AppSettingsInjector.java index 7bea99931e..899d4ef9cb 100644 --- a/src/com/android/settings/location/AppSettingsInjector.java +++ b/src/com/android/settings/location/AppSettingsInjector.java @@ -19,9 +19,19 @@ package com.android.settings.location; import android.content.Context; import android.content.Intent; import android.text.TextUtils; +import android.content.pm.ResolveInfo; +import android.content.pm.PackageManager; +import android.content.pm.ServiceInfo; +import android.os.UserHandle; + +import android.location.SettingInjectorService; import androidx.preference.Preference; +import java.io.IOException; + +import org.xmlpull.v1.XmlPullParserException; + import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.RestrictedAppPreference; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; @@ -43,11 +53,30 @@ public class AppSettingsInjector extends SettingsInjector { mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } + /** + * Returns the settings parsed from the attributes of the + * {@link SettingInjectorService#META_DATA_NAME} tag, or null. + * + * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}. + */ + @Override + protected InjectedSetting parseServiceInfo(ResolveInfo service, UserHandle userHandle, + PackageManager pm) throws XmlPullParserException, IOException { + InjectedSetting res = super.parseServiceInfo(service, userHandle, pm); + ServiceInfo si = service.serviceInfo; + + if ((null != res) && (!DimmableIZatIconPreference.showIzat(mContext, si.packageName))) { + res = null; + } + + return res; + } + @Override protected Preference createPreference(Context prefContext, InjectedSetting setting) { return TextUtils.isEmpty(setting.userRestriction) - ? new AppPreference(prefContext) - : new RestrictedAppPreference(prefContext, setting.userRestriction); + ? DimmableIZatIconPreference.getAppPreference(prefContext, setting) + : DimmableIZatIconPreference.getRestrictedAppPreference(prefContext, setting); } @Override diff --git a/src/com/android/settings/location/DimmableIZatIconPreference.java b/src/com/android/settings/location/DimmableIZatIconPreference.java new file mode 100644 index 0000000000..b5a6498525 --- /dev/null +++ b/src/com/android/settings/location/DimmableIZatIconPreference.java @@ -0,0 +1,243 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +package com.android.settings.location; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import androidx.preference.PreferenceViewHolder; +import android.util.Log; +import android.os.Looper; +import android.os.Handler; +import com.android.settingslib.location.InjectedSetting; +import com.android.settingslib.location.SettingsInjector; +import com.android.settingslib.widget.AppPreference; +import com.android.settings.widget.RestrictedAppPreference; +import dalvik.system.DexClassLoader; +import java.lang.ClassNotFoundException; +import java.lang.ExceptionInInitializerError; +import java.lang.IllegalAccessException; +import java.lang.IllegalArgumentException; +import java.lang.LinkageError; +import java.lang.NoSuchFieldException; +import java.lang.NoSuchMethodException; +import java.lang.NullPointerException; +import java.lang.SecurityException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import com.android.settings.R; + +public class DimmableIZatIconPreference { + private static final String TAG = "DimmableIZatIconPreference"; + private static Class mXtProxyClz; + private static Class mNotifierClz; + private static Method mGetXtProxyMethod; + private static Method mGetConsentMethod; + private static Method mShowIzatMethod; + private static String mIzatPackage; + private static DexClassLoader mLoader; + + private static void load(Context context) { + if (mLoader == null) { + try { + if (mXtProxyClz == null || mNotifierClz == null) { + mLoader = new DexClassLoader("/system_ext/framework/izat.xt.srv.jar", + context.getFilesDir().getAbsolutePath(), + null, + ClassLoader.getSystemClassLoader()); + mXtProxyClz = Class.forName("com.qti.izat.XTProxy", + true, + mLoader); + mNotifierClz = Class.forName("com.qti.izat.XTProxy$Notifier", + true, + mLoader); + mIzatPackage = (String)mXtProxyClz.getField("IZAT_XT_PACKAGE").get(null); + mGetXtProxyMethod = mXtProxyClz.getMethod("getXTProxy", + Context.class, + mNotifierClz); + mGetConsentMethod = mXtProxyClz.getMethod("getUserConsent"); + mShowIzatMethod = mXtProxyClz.getMethod("showIzat", + Context.class, + String.class); + } + } catch (NoSuchMethodException | NullPointerException | SecurityException | + NoSuchFieldException | LinkageError | IllegalAccessException | + ClassNotFoundException e) { + mXtProxyClz = null; + mNotifierClz = null; + mIzatPackage = null; + mGetXtProxyMethod = null; + mGetConsentMethod = null; + mShowIzatMethod = null; + e.printStackTrace(); + } + } + } + + static boolean showIzat(Context context, String packageName) { + load(context); + boolean show = true; + try { + if (mShowIzatMethod != null) { + show = (Boolean)mShowIzatMethod.invoke(null, context, packageName); + } + } catch (IllegalAccessException | IllegalArgumentException | + InvocationTargetException | ExceptionInInitializerError e) { + e.printStackTrace(); + } + return show; + } + + private static boolean isIzatPackage(Context context, InjectedSetting info) { + return (mIzatPackage != null && mIzatPackage.equals(info.packageName)); + } + + private static final int ICON_ALPHA_ENABLED = 255; + private static final int ICON_ALPHA_DISABLED = 102; + + private static void dimIcon(AppPreference pref, boolean dimmed) { + Drawable icon = pref.getIcon(); + if (icon != null) { + icon.mutate().setAlpha(dimmed ? ICON_ALPHA_DISABLED : ICON_ALPHA_ENABLED); + pref.setIcon(icon); + } + pref.setSummary(pref.getSummary()); + } + + private static class IZatAppPreference extends AppPreference { + private Handler mHandler; + private boolean mChecked; + private Context mContext; + private IZatAppPreference(Context context) { + super(context); + mContext = context; + mHandler = new Handler(Looper.getMainLooper()); + Object notifier = Proxy.newProxyInstance(mLoader, + new Class[] { mNotifierClz }, + new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + if (method.getName().equals("userConsentNotify") && + args[0] != null && args[0] instanceof Boolean) { + boolean consent = (Boolean)args[0]; + if (mChecked != consent) { + mChecked = consent; + mHandler.post(() -> { + DimmableIZatIconPreference.dimIcon( + IZatAppPreference.this, !isEnabled() || !mChecked);}); + } + } + return null; + }}); + + try { + Object xt = mGetXtProxyMethod.invoke(null, context, notifier); + mChecked = (Boolean)mGetConsentMethod.invoke(xt); + } catch (IllegalAccessException | IllegalArgumentException | + InvocationTargetException | ExceptionInInitializerError e) { + e.printStackTrace(); + } + } + + @Override + public CharSequence getSummary() { + int resId; + if (!isEnabled() || !mChecked) { + resId = R.string.notification_toggle_off; + } else { + resId = R.string.notification_toggle_on; + } + return mContext.getString(resId); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + mHandler.post(() -> { + DimmableIZatIconPreference.dimIcon( + IZatAppPreference.this, !isEnabled() || !mChecked);}); + } + } + + private static class IZatRestrictedAppPreference extends RestrictedAppPreference { + private Handler mHandler; + private boolean mChecked; + private IZatRestrictedAppPreference(Context context, String userRestriction) { + super(context, userRestriction); + mHandler = new Handler(Looper.getMainLooper()); + Object notifier = Proxy.newProxyInstance(mLoader, + new Class[] { mNotifierClz }, + new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + if (method.getName().equals("userConsentNotify") && + args[0] != null && args[0] instanceof Boolean) { + boolean consent = (Boolean)args[0]; + if (mChecked != consent) { + mChecked = consent; + mHandler.post(() -> { + DimmableIZatIconPreference.dimIcon( + IZatRestrictedAppPreference.this, !isEnabled() || !mChecked);}); + } + } + return null; + }}); + + try { + Object xt = mGetXtProxyMethod.invoke(null, context, notifier); + mChecked = (Boolean)mGetConsentMethod.invoke(xt); + } catch (IllegalAccessException | IllegalArgumentException | + InvocationTargetException | ExceptionInInitializerError e) { + e.printStackTrace(); + } + } + + @Override + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + mHandler.post(() -> { + DimmableIZatIconPreference.dimIcon( + IZatRestrictedAppPreference.this, !isEnabled() || !mChecked);}); + } + } + + static AppPreference getAppPreference(Context context, InjectedSetting info) { + return isIzatPackage(context, info) ? + new IZatAppPreference(context) : + new AppPreference(context); + } + + static RestrictedAppPreference getRestrictedAppPreference(Context context, InjectedSetting info) { + return isIzatPackage(context, info) ? + new IZatRestrictedAppPreference(context, info.userRestriction) : + new RestrictedAppPreference(context, info.userRestriction); + } +} |