GWD sources - Samsung Galaxy Watch
It seems the ALARM and NOTIFICATION sources aren't shown in GWD. But they may be useable by modding the xml. Likely as sources for a hand, text, digital clock etc.
Code:
package com.samsung.gwd.source;
import java.util.HashMap;
public class Source
{
public static final String SOURCE_CALORIE_CAL = "cal";
public static final String SOURCE_CALORIE_KCAL = "kcal";
public static final String SOURCE_CALORIE_UNIT_CAL = "(cal)";
public static final String SOURCE_CALORIE_UNIT_KCAL = "(kcal)";
public static final String SOURCE_DISTANCE_M = "m";
public static final String SOURCE_DISTANCE_KM = "km";
public static final String SOURCE_DISTANCE_MILE = "mile";
public static final String SOURCE_DISTANCE_UNIT_M = "(m)";
public static final String SOURCE_DISTANCE_UNIT_KM = "(km)";
public static final String SOURCE_DISTANCE_UNIT_MILE = "(mile)";
public static final String SOURCE_SPEED_M = "m/s";
public static final String SOURCE_SPEED_KM = "km/h";
public static final String SOURCE_SPEED_MILE = "mile/h";
public static final String SOURCE_SPEED_UNIT_M = "(m/s)";
public static final String SOURCE_SPEED_UNIT_KM = "(km/h)";
public static final String SOURCE_SPEED_UNIT_MILE = "(mile/h)";
public static final String SOURCE_TEMPERATURE_C = "�C";
public static final String SOURCE_TEMPERATURE_F = "�F";
public static final String SOURCE_TEMPERATURE_K = "�K";
public static final String SOURCE_TEMPERATURE_UNIT_C = "(�C)";
public static final String SOURCE_TEMPERATURE_UNIT_F = "(�F)";
public static final String SOURCE_TEMPERATURE_UNIT_K = "(�K)";
public static final String SOURCE_HUMIDITY_PERCENT = "%";
public static final String SOURCE_HUMIDITY_UNIT_PERCENT = "(%)";
public static final String WEATHER_DISPLAY_TYPE_ICON = "Icon";
public static final String WEATHER_DISPLAY_TYPE_MAIN = "Main";
public static final String WEATHER_DISPLAY_TYPE_DESCRIPTION = "Description";
public static final String WEATHER_DISPLAY_TYPE_NUMBER = "Number";
public static final String WEATHER_DISPLAY_TYPE_ID = "ID";
public static final Source NONE = new Source("None", "none", 0.0D, 0.0D, false, 0.0D, 0.0D, null, new String[] { "None" });
public static final Source HOUR = new Source("Hour in Day", "hour0-23", 0.0D, 24.0D, true, 0.0D, 720.0D, null, new String[] { "%d" });
public static final Source HOUR_MINUTE = new Source("Hour in Day", "hour0-23.minute", 0.0D, 24.0D, true, 0.0D, 720.0D, null, new String[] { "%f" });
public static final Source MINUTE = new Source("Minute in Hours", "minute", 0.0D, 60.0D, false, 0.0D, 360.0D, null, new String[] { "%d" });
public static final Source MINUTE_SECOND = new Source("Minute in Hours", "minute.second", 0.0D, 60.0D, true, 0.0D, 360.0D, null, new String[] { "%f" });
public static final Source SECOND = new Source("Second in Minute", "second", 0.0D, 60.0D, false, 0.0D, 360.0D, null, new String[] { "%d" });
public static final Source SECOND_SWEEP = new Source("Second in Minute", "second.millisecond", 0.0D, 60.0D, true, 0.0D, 360.0D, null, new String[] { "%f" });
public static final Source DAY = new Source("Day of Month", "day", 0.0D, 31.0D, false, 0.0D, 360.0D, null, new String[] { "%d" });
public static final Source MONTH = new Source("Month of Year", "month", 0.0D, 12.0D, false, 0.0D, 360.0D, null, new String[] { "%d" });
public static final Source DAY_OF_WEEK = new Source("Day of Week", "dayOfWeek", 1.0D, 8.0D, false, 0.0D, 360.0D, null, new String[] { "%d" });
public static final Source DAY_OF_YEAR = new Source("Day of Year", "month0-11.day", 0.0D, 12.0D, true, 0.0D, 360.0D, null, new String[] { "%d" });
public static final Source BATTERY_PERCENT = new Source("Battery %", "battery.percent", 0.0D, 100.0D, false, 0.0D, 360.0D,
null, new String[] { "%d %", "%d", "% %d" });
public static final Source BATTERY_LEVEL = new Source("Battery Level", "battery.level", 0.0D, 4.0D, false, 0.0D, 360.0D,
null, new String[] { "%d" });
public static final Source BATTERY_CHARGING_STATUS = new Source("Battery charging status", "battery.chargingStatus", 0.0D, 1.0D, false, 0.0D, 180.0D,
null, new String[] { "%d" });
public static final Source PEDOMETER_STEP_PERCENT = new Source("Steps %", "pedometer.stepPercent", 0.0D, 100.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d %", "%d", "% %d" });
public static final Source PEDOMETER_CALORIE = new Source("Burned calorie", "pedometer.calorie", 0.0D, 1000000.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d kcal",
"%d (kcal)" },
new String[] { "kcal" },
new String[] { "0" },
"kcal", "0");
public static final Source PEDOMETER_DISTANCE = new Source("Moved distance", "pedometer.distance", 0.0D, 10000.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d km",
"%d m",
"%d mile",
"%d (km)",
"%d (m)",
"%d (mile)" },
new String[] { "m", "km", "mile" },
new String[] { "0", "1", "2", "3" },
"km", "1");
public static final Source PEDOMETER_SPEED = new Source("Speed", "stepsPerSec", 0.0D, 20.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d km/h",
"%d m/s",
"%d mile/h",
"%d (km/h)",
"%d (m/s)",
"%d (mile/h)" },
new String[] { "m/s", "km/h", "mile/h" },
new String[] { "0", "1", "2", "3" },
"km/h", "1");
public static final Source PEDOMETER_STEP_COUNT = new Source("Step counts", "pedometer.step", 0.0D, 10000.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d steps", "%d" });
public static final Source PEDOMETER_STEP_GOAL = new Source("Steps goal", "pedometer.target", 0.0D, 100.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d steps", "%d" });
public static final Source PEDOMETER_FLOOR = new Source("Floor", "floor", 0.0D, 100.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d floor", "%d" });
public static final Source HEARTRATE = new Source("Heart rate (bpm)", "heartrate.recent", 0.0D, 200.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d bpm", "%d" });
public static final Source WATER_INTAKE = new Source("Water Intake", "water", 0.0D, 100.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d" });
public static final Source WATER_GOAL = new Source("Water Goal", "water.goal", 0.0D, 100.0D, false, 0.0D, 360.0D,
null, new String[] { "%d" });
public static final Source CAFFEINE_INTAKE = new Source("Caffeine Intake", "caffeine", 0.0D, 100.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/healthinfo", new String[] { "%d" });
public static final Source CAFFEINE_GOAL = new Source("Caffeine Goal", "caffeine.goal", 0.0D, 100.0D, false, 0.0D, 360.0D,
null, new String[] { "%d" });
public static final Source ALARM_HOUR = new Source("Alarm hour", "alarm.hour0-23", 0.0D, 24.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/alarm.get", new String[] { "%d" });
public static final Source ALARM_MINUTE = new Source("Alarm minute", "alarm.minute", 0.0D, 60.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/alarm.get", new String[] { "%d" });
public static final Source ALARM_STATE = new Source("Alarm state", "alarm.state", 0.0D, 2.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/alarm.get", new String[] { "%d" });
public static final Source MOONPHASE_POSITION = new Source("Moon Phase Position", "moonphase.position", 0.0D, 28.0D, true, 0.0D, 360.0D,
null, new String[] { "%f" },
null,
new String[] { "0", "1", "2", "3", "4", "5" },
null, "0");
public static final Source MOONPHASE_TYPE = new Source("Moon Phase Type", "moonphase.type", 0.0D, 8.0D, false, 0.0D, 360.0D,
null, new String[] { "%d" });
public static final Source NOTIFICATION_UNREAD = new Source("Notification unread", "notification.unread", 0.0D, 100.0D, false, 0.0D, 360.0D,
"http://tizen.org/privilege/notification", new String[] { "%d" });
public static final Source WEATHER_TYPE = new Source("Weather Type", "Weather Type", 0.0D, 100.0D, false, 0.0D, 360.0D,
null, new String[] { "Main",
"Icon",
"Description",
"Number",
"ID" });
public static final Source CURRENT_TEMPERATURE = new Source("Current Temperature", "Current Temperature", -50.0D, 50.0D, false, 0.0D, 360.0D,
null, new String[] { "%f �C",
"%f �F",
"%f �K",
"%f (�C)",
"%f (�F)",
"%f (�K)" },
new String[] { "�C", "�F", "�K" },
new String[] { "0", "1", "2", "3" },
"�C", "1");
public static final Source WEATHER_HUMIDITY = new Source("Weather Humidity", "Weather Humidity", 0.0D, 100.0D, false, 0.0D, 360.0D,
null,
new String[] { "%d %",
"%d (%)" },
new String[] { "%" },
new String[] { "0" },
"%", "0");
public static final Source WEATHER_CITY_NAME = new Source("City Name", "City Name", 0.0D, 100.0D, false, 0.0D, 360.0D,
null, new String[] { "%d" });
public static final Source WEATHER_LAST_UPDATE_TIME = new Source("Last update Time", "Last update Time", 0.0D, 100.0D, false, 0.0D, 360.0D,
null, new String[] { "M/d HH:mm", "HH : mm" });
private static final HashMap<String, Source> map = new HashMap();
public final String name;
public final String id;
public double startValue;
public double endValue;
public boolean real;
public double startAngle;
public double endAngle;
public final String privilege;
public final String[] display;
public final String[] unit;
public final String[] precision;
public final String defaultUnit;
public final String defaultPrecision;
static
{
map.put(NONE.id, NONE);
map.put(HOUR_MINUTE.id, HOUR_MINUTE);
map.put(HOUR.id, HOUR);
map.put(MINUTE.id, MINUTE);
map.put(MINUTE_SECOND.id, MINUTE_SECOND);
map.put(SECOND.id, SECOND);
map.put(SECOND_SWEEP.id, SECOND_SWEEP);
map.put(DAY.id, DAY);
map.put(MONTH.id, MONTH);
map.put(DAY_OF_WEEK.id, DAY_OF_WEEK);
map.put(DAY_OF_YEAR.id, DAY_OF_YEAR);
map.put(BATTERY_PERCENT.id, BATTERY_PERCENT);
map.put(BATTERY_LEVEL.id, BATTERY_LEVEL);
map.put(BATTERY_CHARGING_STATUS.id, BATTERY_CHARGING_STATUS);
map.put(PEDOMETER_STEP_PERCENT.id, PEDOMETER_STEP_PERCENT);
map.put(PEDOMETER_CALORIE.id, PEDOMETER_CALORIE);
map.put(PEDOMETER_DISTANCE.id, PEDOMETER_DISTANCE);
map.put(PEDOMETER_SPEED.id, PEDOMETER_SPEED);
map.put(PEDOMETER_STEP_COUNT.id, PEDOMETER_STEP_COUNT);
map.put(PEDOMETER_STEP_GOAL.id, PEDOMETER_STEP_GOAL);
map.put(PEDOMETER_FLOOR.id, PEDOMETER_FLOOR);
map.put(HEARTRATE.id, HEARTRATE);
map.put(WATER_INTAKE.id, WATER_INTAKE);
map.put(WATER_GOAL.id, WATER_GOAL);
map.put(CAFFEINE_INTAKE.id, CAFFEINE_INTAKE);
map.put(CAFFEINE_GOAL.id, CAFFEINE_GOAL);
map.put(ALARM_HOUR.id, ALARM_HOUR);
map.put(ALARM_MINUTE.id, ALARM_MINUTE);
map.put(ALARM_STATE.id, ALARM_STATE);
map.put(MOONPHASE_POSITION.id, MOONPHASE_POSITION);
map.put(MOONPHASE_TYPE.id, MOONPHASE_TYPE);
map.put(NOTIFICATION_UNREAD.id, NOTIFICATION_UNREAD);
map.put(WEATHER_TYPE.id, WEATHER_TYPE);
map.put(CURRENT_TEMPERATURE.id, CURRENT_TEMPERATURE);
map.put(WEATHER_HUMIDITY.id, WEATHER_HUMIDITY);
map.put(WEATHER_CITY_NAME.id, WEATHER_CITY_NAME);
map.put(WEATHER_LAST_UPDATE_TIME.id, WEATHER_LAST_UPDATE_TIME);
map.put(NONE.name, NONE);
map.put(HOUR_MINUTE.name, HOUR_MINUTE);
map.put(HOUR.name, HOUR);
map.put(MINUTE.name, MINUTE);
map.put(MINUTE_SECOND.name, MINUTE_SECOND);
map.put(SECOND.name, SECOND);
map.put(SECOND_SWEEP.name, SECOND_SWEEP);
map.put(DAY.name, DAY);
map.put(MONTH.name, MONTH);
map.put(DAY_OF_WEEK.name, DAY_OF_WEEK);
map.put(DAY_OF_YEAR.name, DAY_OF_YEAR);
map.put(BATTERY_PERCENT.name, BATTERY_PERCENT);
map.put(BATTERY_LEVEL.name, BATTERY_LEVEL);
map.put(BATTERY_CHARGING_STATUS.name, BATTERY_CHARGING_STATUS);
map.put(PEDOMETER_STEP_PERCENT.name, PEDOMETER_STEP_PERCENT);
map.put(PEDOMETER_CALORIE.name, PEDOMETER_CALORIE);
map.put(PEDOMETER_DISTANCE.name, PEDOMETER_DISTANCE);
map.put(PEDOMETER_SPEED.name, PEDOMETER_SPEED);
map.put(PEDOMETER_STEP_COUNT.name, PEDOMETER_STEP_COUNT);
map.put(PEDOMETER_STEP_GOAL.name, PEDOMETER_STEP_GOAL);
map.put(PEDOMETER_FLOOR.name, PEDOMETER_FLOOR);
map.put(HEARTRATE.name, HEARTRATE);
map.put(WATER_INTAKE.name, WATER_INTAKE);
map.put(WATER_GOAL.name, WATER_GOAL);
map.put(CAFFEINE_INTAKE.name, CAFFEINE_INTAKE);
map.put(CAFFEINE_GOAL.name, CAFFEINE_GOAL);
map.put(ALARM_HOUR.name, ALARM_HOUR);
map.put(ALARM_MINUTE.name, ALARM_MINUTE);
map.put(ALARM_STATE.name, ALARM_STATE);
map.put(MOONPHASE_POSITION.name, MOONPHASE_POSITION);
map.put(MOONPHASE_TYPE.name, MOONPHASE_TYPE);
map.put(NOTIFICATION_UNREAD.name, NOTIFICATION_UNREAD);
map.put(WEATHER_TYPE.name, WEATHER_TYPE);
map.put(CURRENT_TEMPERATURE.name, CURRENT_TEMPERATURE);
map.put(WEATHER_HUMIDITY.name, WEATHER_HUMIDITY);
map.put(WEATHER_CITY_NAME.name, WEATHER_CITY_NAME);
map.put(WEATHER_LAST_UPDATE_TIME.name, WEATHER_LAST_UPDATE_TIME);
}
public Source(String name, String id, double startValue, double endValue, boolean real, double startAngle, double endAngle, String privilege, String[] display, String[] unit, String[] precision, String defaultUnit, String defaultPrecision)
{
this.name = name;
this.id = id;
this.startValue = startValue;
this.endValue = endValue;
this.real = real;
this.startAngle = startAngle;
this.endAngle = endAngle;
this.privilege = privilege;
this.display = display;
this.unit = unit;
this.precision = precision;
this.defaultUnit = defaultUnit;
this.defaultPrecision = defaultPrecision;
}
public Source(String name, String id, double startValue, double endValue, boolean real, double startAngle, double endAngle, String privilege, String[] display)
{
this(name, id, startValue, endValue, real, startAngle, endAngle, privilege, display, null, null, null, null);
}
public Source(Source source)
{
this(source.name, source.id, source.startValue, source.endValue, source.real, source.startAngle, source.endAngle, source.privilege, source.display, source.unit, source.precision, source.defaultUnit, source.defaultPrecision);
}
public boolean equals(Object obj)
{
if ((obj instanceof Source)) {
return (this.name.equals(((Source)obj).name)) && (this.id.equals(((Source)obj).id)) &&
(this.startValue == ((Source)obj).startValue) && (this.endValue == ((Source)obj).endValue) && (this.real == ((Source)obj).real) &&
(this.startAngle == ((Source)obj).startAngle) && (this.endAngle == ((Source)obj).endAngle);
}
return false;
}
public static Source findById(String id)
{
Source result = (Source)map.get(id);
if (result == null) {
return NONE;
}
return result;
}
public static Source findByName(String name)
{
return (Source)map.get(name);
}
}
Related
XClasses - A Xposed Library
Hello guys, I want to share my library XClasses. My idea was to see every XClass as an extension of the original class. My aim was to improve the user experience during the development. Also I wanted to increase the readability of xposed code. So it's nothing special. It's just my personal opinion how readable code should look like. A small example: Code: public class XposedMain implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { if(lpparam.packageName.equals("com.android.systemui")) { XposedHelpers.findAndHookMethod(TextView.class, "setText", CharSequence.class, TextView.BufferType.class, boolean.class, int.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { TextView tv = (TextView)param.thisObject; CharSequence text = (CharSequence)param.args[0]; TextView.BufferType type = (TextView.BufferType)param.args[1]; boolean notifyBefore = (Boolean)param.args[2]; int oldlen = (Integer)param.args[3]; XposedBridge.log("setText "+text+" with size "+tv.getTextSize()); } }); } } } The same code with XClasses: Code: // class 1 public class XposedMain implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { if(lpparam.packageName.equals("com.android.systemui")) { setup(lpparam.classLoader); hook(XTextView.class); } } } // class 2 public class XTextView extends AbstractXClass<TextView> { public static String getOriginalClassName() { return TextView.class.getCanonicalName(); } public XTextView(TextView objectThis) { super(objectThis); } @BeforeOriginalMethod private void setText_Before(CharSequence text, TextView.BufferType type, boolean notifyBefore, int oldlen) throws Throwable { XposedBridge.log("setText "+text+" with size "+getThis().getTextSize()); } } If you would like to know more you should visit the following site: https://github.com/seebye/XClasses Regards, Seebye
Galaxy S3 ver 4.1.1 - Trying to start Activity from Emergency Dialer after placeCall
We are working with a Galaxy S3 (Android 4.1.1). We are able to get the activity from param.thisObject and change the title by getting the activity and calling setTitle(), but when we want to start a new activity, the activity doesn't start. Does anyone know how to spawn a new activity? Our code is building off of SmileyClock in the tutorial. Main.java --------------------------------------------------------------------------------------------------------------------------------------------------------------- package com.example.SmileyClock; import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; import android.aMain.javapp.Activity; import android.content.Intent; import android.util.Log; import android.view.View; import android.widget.TextView; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XSharedPreferences; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; public class Main implements IXposedHookLoadPackage { @override public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable { // TODO Auto-generated method stub if (!lpparam.packageName.equals("com.android.phone"))//check if the package being loaded is systemUI return; //All code here is only called if it is indeed SystemUI findAndHookMethod("com.android.phone.EmergencyDialer", lpparam.classLoader, "placeCall", new XC_MethodHook() { @override protected void afterHookedMethod(MethodHookParam param) throws Throwable { Activity emergencyDialer = (Activity) param.thisObject; emergencyDialer.setTitle("Title has been changed!"); Intent newIntent = new Intent(emergencyDialer, BlackScreenActivity.class); newIntent.addFlgags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); emergencyDialer.startActivity(newIntent); Activity emergencyDialer = (Activity) param.thisObject; Object[] args = param.args; View view = (View) args[0]; emergencyDialer.setTitle("" + view.getId()); Intent newIntent = new Intent(Intent.ACTION_VIEW, null, emergencyDialer, BlackScreenActivity.class); emergencyDialer.startActivity(newIntent); } }); } } BlackScreenActivity.java --------------------------------------------------------------------------------------------------------------------------------------------------------------- package com.example.SmileyClock; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.Window; import android.view.WindowManager; public class BlackScreenActivity extends Activity { @override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_black_screen); //Remove title bar this.requestWindowFeature(Window.FEATURE_NO_TITLE); //Remove notification bar this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //set content view AFTER ABOVE sequence (to avoid crash) this.setContentView(R.layout.activity_black_screen); try { Thread.sleep(3000); finish(); Log.v("Xposed", "Sleep is done"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.v("ERROR CATCH THING", e.toString()); } } @override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.black_screen, menu); return true; } @override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
[Q] Extract live wallpaper
Does anyone know where I can find code handling the current live wallpaper engine / view? I am trying to extract the live wallpaper for further processing (e.g. blurring). I already found an entrance point: If the LWP used the standard com.android.internal.view.BaseSurfaceHolder supplied by the base class android.service.wallpaper.WallpaperService.Engine i can hook into lockCanvas and unlockCanvas to grab the image. But most LWPs do not use this, so I need another (more general) solution. I thought about hooking all subclasses of android.service.wallpaper.WallpaperService, but AFAIK that's not possible without loading every single class and check if it's a subclass. Any ideas? Implementation for reference: Code: public class Hook implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { final Class<?> engingeClass = findClass("android.service.wallpaper.WallpaperService.Engine", loadPackageParam.classLoader); final String packageName = loadPackageParam.packageName; final Class<?> surfaceHolderClass = findClass("com.android.internal.view.BaseSurfaceHolder",loadPackageParam.classLoader); findAndHookMethod(engingeClass, "getSurfaceHolder", new XC_MethodHook() { private boolean isFirstCall = true; @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { Field field = findField(param.thisObject.getClass(), "this$0"); WallpaperService service = (WallpaperService) field.get(param.thisObject); WallpaperManager wallpaperManager = WallpaperManager.getInstance(service); if (isFirstCall && wallpaperManager.getWallpaperInfo().getPackageName().equals(packageName)) { isFirstCall = false; XposedBridge.log("Got context. Set up hooks..."); hook(surfaceHolderClass,service); } } }); } Bitmap bitmap; Canvas internalCanvas; Canvas originalCanvas; private void hook(Class<?> clazz, final Context context) { hookAllMethods(clazz, "lockCanvas", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { originalCanvas = (Canvas) param.getResult(); bitmap = Bitmap.createBitmap(originalCanvas.getWidth(),originalCanvas.getHeight(), Bitmap.Config.ARGB_8888); internalCanvas = new Canvas(bitmap); param.setResult(internalCanvas); XposedBridge.log("Locked Canvas"); } }); findAndHookMethod(clazz, "unlockCanvasAndPost", Canvas.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { originalCanvas.drawBitmap(bitmap,0,0,null); param.args[0] = originalCanvas; Intent intent = new Intent("com.faendir.lwpextractor.WALLPAPER_CHANGE"); ByteArrayOutputStream bs = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG,100,bs); intent.putExtra("bmp",bs.toByteArray()); context.sendBroadcast(intent, "com.faendir.lwpextractor.RECEIVE_WALLPAPER_CHANGE"); XposedBridge.log("Unlocked Canvas"); } }); } } [this post is a copy of http://forum.xda-developers.com/xposed/modules/extract-live-wallpaper-t3260128, now posted here, because @Spott07 pointed out it would fit better]
Hooking a protected List in an Inner Class with an odd set of Parameters
So, I'm getting fairly good at hooking and modifying classes, but this one is so unique, I'm not quite sure how to approach hooking it to do what I want. Code for the method/class I want to attack: Code: private class CreateLaunchPointListTask extends AsyncTask<Void, Void, List<LaunchPoint>> { private CreateLaunchPointListTask() {} protected List<LaunchPoint> doInBackground(Void... paramVarArgs) { paramVarArgs = mContext.getString(2131558445); Object localObject = new Intent("android.intent.action.MAIN"); ((Intent)localObject).addCategory(paramVarArgs); paramVarArgs = new LinkedList(); PackageManager localPackageManager = mContext.getPackageManager(); localObject = localPackageManager.queryIntentActivities((Intent)localObject, 129); int j = ((List)localObject).size(); int i = 0; while (i < j) { ResolveInfo localResolveInfo = (ResolveInfo)((List)localObject).get(i); if (activityInfo != null) { paramVarArgs.add(new LaunchPoint(mContext, localPackageManager, localResolveInfo)); } i += 1; } return paramVarArgs; } public void onPostExecute(List<LaunchPoint> arg1) { synchronized (mLock) { mAllLaunchPoints.clear(); mAllLaunchPoints.addAll(???); synchronized (mCachedActions) { LaunchPointListGenerator.access$502(LaunchPointListGenerator.this, true); if (!mCachedActions.isEmpty()) { ((LaunchPointListGenerator.CachedAction)mCachedActions.remove()).apply(); } } } LaunchPointListGenerator.access$602(LaunchPointListGenerator.this, true); Iterator localIterator = mListeners.iterator(); while (localIterator.hasNext()) { ((LaunchPointListGenerator.Listener)localIterator.next()).onLaunchPointListGeneratorReady(); } } } So, while this is a big chunk of code, everything I want to do is really in the first few lines: Code: paramVarArgs = mContext.getString(2131558445); Object localObject = new Intent("android.intent.action.MAIN"); ((Intent)localObject).addCategory(paramVarArgs); So, string 2131558445 is a specific intent. What I would like to do is add *another* category after 2131558445 is added to localObject. That would be the simplest implementation. A more advanced implementation would be to actually and return a second LinkedList, paramVarArgs2, that only matches up to the second intent category that we're inserting. Any help would be greatly appreciated.
[Q] How to use a variable from one hook in another? (Why is this an NPE?)
Hello, I have made this code Link : http://hastebin.com/hiyupafibi.java Duplicated here : Code: //In my module, I have this activity MainActivity, which has a function to generate random number private int randomNumber() { return (new Random()).nextInt(3); } //Toast this random number somewhere in the main activity Toast.makeText(MainActivity.this, " " + randomNumber(), Toast.LENGTH_LONG).show(); //In XposedMod, make a hook public class XposedMod implements IXposedHookLoadPackage { private TextView tv; public static final String PACKAGE_NAME = "......."; @Override public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable { if (lpparam.packageName.equals(PACKAGE_NAME)) { Class<?> MainActivityClass = XposedHelpers.findClass(PACKAGE_NAME + ".MainActivity", lpparam.classLoader); XposedHelpers.findAndHookMethod(MainActivityClass, "randomNumber", new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable { try { tv.setText("No NPE"); return 45; } catch (NullPointerException e) { return 44; } } }); } else if (lpparam.packageName.equals("com.android.systemui")) { Class<?> someClass = XposedHelpers.findClass("com.android.systemui.SomeClass", lpparam.classLoader); XposedHelpers.findAndHookMethod(someClass, "someMethod", Context.class, new XC_MethodHook() { @Override protected Object beforeHookedMethod(MethodHookParam methodHookParam) throws Throwable { tv = new TextView((Context) param.args[0]); if (tv==null) XposedBridge.log("tv is null, apologies!"); } }); } } } Everytime that toast is supposed to be shown, I get the answer to be 44 (that is, tv is null), but that should not be the case, because the log statement when tv is null is not shown. What am I doing wrong? Thanks for the help, I appreciate it. Cheers!