summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralk3pInjection <webmaster@raspii.tech>2023-01-18 16:40:30 +0800
committeralk3pInjection <webmaster@raspii.tech>2023-01-18 16:40:30 +0800
commit15ac9dd4c3ec87af302104c033f0645ab5d292d0 (patch)
treecf3094df629d91b9abc4cc17aaf4bf2d7593e8a6
parent088f23b5f8b78746b8b868e292cfeb5361279e68 (diff)
Revert^2 "All the Izat icon changes"
This reverts commit 9e65bcfd047bd026f043eb6a2551f9b8e38345dc. Change-Id: If77b16e7c0403bca0a881f7de3dea2b66b510909
-rw-r--r--src/com/android/settings/location/AppSettingsInjector.java33
-rw-r--r--src/com/android/settings/location/DimmableIZatIconPreference.java243
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);
+ }
+}