com.amossys.hooker.common.InterceptEvent.java Source code

Java tutorial

Introduction

Here is the source code for com.amossys.hooker.common.InterceptEvent.java

Source

/*----------------------------------------------------------------------------+
 *|                                                                           |
 *|                          Android's Hooker                                 |
 *|                                                                           |
 *+---------------------------------------------------------------------------+
 *| Copyright (C) 2011 Georges Bossert and Dimitri Kirchner                   |
 *| 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 3 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, see <http://www.gnu.org/licenses/>.      |
 *+---------------------------------------------------------------------------+
 *| @url      : http://www.amossys.fr                                         |
 *| @contact  : android-hooker@amossys.fr                                     |
 *| @sponsors : Amossys, http://www.amossys.fr                                |
 *+---------------------------------------------------------------------------+
 */

package com.amossys.hooker.common;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Map.Entry;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.amossys.hooker.SubstrateMain;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * InterceptEvent class contains data we want to extract.
 * This class implements Parcelable so we can send it to our Service.
 * @author Dimitri Kirchner & Georges Bossert.
 *
 */
public class InterceptEvent implements Parcelable {

    // unique ID of the event
    private UUID idEvent;
    // experiment iD
    private String IDXP;
    // creation date of the event
    private long timestamp;
    // relative creation date of the event
    private long relativeTimestamp;
    // name of the hooker who created this event
    private String hookerName;
    // 0: Nothing related personal info,
    // 1: Reading personal info
    // 2: Writing personal info
    private int intrusiveLevel;
    // instance id
    private int instanceID;
    // name of the package in which we hooked this event
    private String packageName;
    // name of the class we attached on
    private String className;
    // name of the method we attached on
    private String methodName;
    // list of parameters used to class this method
    private List<Entry<String, String>> parameters = new ArrayList<Entry<String, String>>();
    // returned values of this method
    private Entry<String, String> returns;
    // optional data added to this event
    private Map<String, String> data = new HashMap<String, String>();

    /**
     * Constructor which will be used to read in the Parcel.
     * @param in
     */
    private InterceptEvent(Parcel in) {
        idEvent = UUID.fromString(in.readString());
        IDXP = in.readString();
        timestamp = in.readLong();
        relativeTimestamp = in.readLong();
        hookerName = in.readString();
        intrusiveLevel = in.readInt();
        instanceID = in.readInt();
        packageName = in.readString();
        className = in.readString();
        methodName = in.readString();

        readParametersList(in);
        readReturnsEntry(in);
        readDataMap(in);
    }

    /**
     * Write to the parcel to build the class.
     */
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(idEvent.toString());
        out.writeString(IDXP);
        out.writeLong(timestamp);
        out.writeLong(relativeTimestamp);
        out.writeString(hookerName);
        out.writeInt(intrusiveLevel);
        out.writeInt(instanceID);
        out.writeString(packageName);
        out.writeString(className);
        out.writeString(methodName);

        writeParametersList(out);
        writeReturnsEntry(out);
        writeDataMap(out);
    }

    /**
     * Read and write functions to handle the parameters list.
     * @param in
     */
    private void readParametersList(Parcel in) {
        int size = in.readInt();
        if (size != 0) {
            for (int i = 0; i < size; i++) {
                String key = in.readString();
                String value = in.readString();
                parameters.add(new AbstractMap.SimpleEntry<String, String>(key, value));
            }
        }
    }

    private void writeParametersList(Parcel out) {
        if (parameters == null) {
            out.writeInt(0);
        } else {
            out.writeInt(parameters.size());
            for (Entry<String, String> entry : parameters) {
                out.writeString(entry.getKey());
                out.writeString(entry.getValue());
            }
        }
    }

    /**
     * Read and write function to handle the returns list.
     * @param in
     */
    private void readReturnsEntry(Parcel in) {
        int tmp = in.readInt();
        if (tmp == 0) {

        } else {
            String key = in.readString();
            String value = in.readString();
            returns = new AbstractMap.SimpleEntry<String, String>(key, value);
        }
    }

    private void writeReturnsEntry(Parcel out) {
        if (returns == null) {
            out.writeInt(0);
        } else {
            out.writeInt(1);
            out.writeString(returns.getKey());
            out.writeString(returns.getValue());
        }
    }

    /**
     * Read and write function to handle the data map.
     * @param in
     */
    private void readDataMap(Parcel in) {
        int size = in.readInt();
        if (size != 0) {
            for (int i = 0; i < size; i++) {
                String key = in.readString();
                String value = in.readString();
                data.put(key, value);
            }
        }
    }

    private void writeDataMap(Parcel out) {
        if (data == null) {
            out.writeInt(0);
        } else {
            out.writeInt(data.size());
            for (String key : data.keySet()) {
                out.writeString(key);
                out.writeString(data.get(key));
            }
        }
    }

    /**
     * Creator necessary to build a Parcelable class
     */
    public static final Parcelable.Creator<InterceptEvent> CREATOR = new Parcelable.Creator<InterceptEvent>() {
        public InterceptEvent createFromParcel(Parcel in) {
            return new InterceptEvent(in);
        }

        public InterceptEvent[] newArray(int size) {
            return new InterceptEvent[size];
        }
    };

    /**
    * Simple constructor for event.
    */
    public InterceptEvent(String hookerName, int intrusiveLevel, int instanceId, String packageName,
            String className, String methodName) {
        this(buildRandomUUID(), 0l, 0, hookerName, intrusiveLevel, instanceId, packageName, className, methodName,
                null, null, null);
    }

    /**
     * Detailed constructor.
     */
    public InterceptEvent(UUID idEvent, long timestamp, long relativeTimestamp, String hookerName,
            int intrusiveLevel, int instanceId, String packageName, String className, String methodName,
            List<Entry<String, String>> parameters, Entry<String, String> returns, Map<String, String> data) {

        super();
        this.idEvent = idEvent;
        if (timestamp == 0) {
            try {
                timestamp = Calendar.getInstance().getTime().getTime();
            } catch (Exception e) {
                timestamp = 0;
                SubstrateMain.log("Error while computing the current timestamp...", e);
            }
        }
        this.timestamp = timestamp;
        this.relativeTimestamp = relativeTimestamp;
        this.hookerName = hookerName;
        this.intrusiveLevel = intrusiveLevel;
        this.instanceID = instanceId;
        this.packageName = packageName;
        this.className = className;
        this.methodName = methodName;
        this.parameters = parameters;
        this.returns = returns;
        this.data = data;
    }

    /**
     * @return a random UUID number.
     * @todo When the system starts, we do not have any class UUID, so we must construct ourselves the UUID.
     * In order to do this better, we have to implement a small random UUID generator.
     */
    private static UUID buildRandomUUID() {
        try {
            return UUID.randomUUID();
        } catch (Exception e) {
            return UUID.fromString("00000000-1111-2222-3333-444444444444");
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    /**
    * Register a new parameter
    * @param type: type of the parameter
    * @param value: value of the parameter
    */
    public void addParameter(String type, String value) {
        if (this.parameters == null) {
            this.parameters = new ArrayList<Map.Entry<String, String>>();
        }
        this.parameters.add(new AbstractMap.SimpleEntry<String, String>(type, value));
    }

    /**
     * @return the idEvent
     */
    public UUID getIdEvent() {
        return idEvent;
    }

    /**
     * @param idEvent the idEvent to set
     */
    public void setIdEvent(UUID idEvent) {
        this.idEvent = idEvent;
    }

    /**
     * @return the timestamp
     */
    public long getTimestamp() {
        return timestamp;
    }

    /**
     * @param timestamp the timestamp to set
     */
    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    /**
     * @return the relativeTimestamp
     */
    public long getRelativeTimestamp() {
        return relativeTimestamp;
    }

    /**
     * @param relativeTimestamp the relativeTimestamp to set
     */
    public void setRelativeTimestamp(long relativeTimestamp) {
        this.relativeTimestamp = relativeTimestamp;
    }

    /**
     * @return the hookerName
     */
    public String getHookerName() {
        return hookerName;
    }

    /**
     * @param hookerName the hookerName to set
     */
    public void setHookerName(String hookerName) {
        this.hookerName = hookerName;
    }

    /**
     * @return the intrusiveLevel
     */
    public int getIntrusiveLevel() {
        return intrusiveLevel;
    }

    /**
     * @param intrusiveLevel the intrusiveLevel to set
     */
    public void setIntrusiveLevel(int intrusiveLevel) {
        this.intrusiveLevel = intrusiveLevel;
    }

    /**
     * @return the packageName
     */
    public String getPackageName() {
        return packageName;
    }

    /**
     * @param packageName the packageName to set
     */
    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    /**
     * @return the className
     */
    public String getClassName() {
        return className;
    }

    /**
     * @param className the className to set
     */
    public void setClassName(String className) {
        this.className = className;
    }

    /**
     * @return the methodName
     */
    public String getMethodName() {
        return methodName;
    }

    /**
     * @param methodName the methodName to set
     */
    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    /**
     * @return the parameters
     */
    public List<Entry<String, String>> getParameters() {
        return parameters;
    }

    /**
     * @param parameters the parameters to set
     */
    public void setParameters(List<Entry<String, String>> parameters) {
        this.parameters = parameters;
    }

    /**
     * @return the returns
     */
    public Entry<String, String> getReturns() {
        return returns;
    }

    /**
     * @param returns the returns to set
     */
    public void setReturns(Entry<String, String> returns) {
        this.returns = returns;
    }

    /**
     * @param name
     * @param string
     */
    public void setReturns(String type, String value) {
        this.returns = new AbstractMap.SimpleEntry<String, String>(type, value);

    }

    /**
     * @return the data
     */
    public Map<String, String> getData() {
        return data;
    }

    /**
     * @param data the data to set
     */
    public void setData(Map<String, String> data) {
        this.data = data;
    }

    /**
     * @return the iDXP
     */
    public String getIDXP() {
        return IDXP;
    }

    /**
     * @return the instanceID
     */
    public int getInstanceID() {
        return instanceID;
    }

    /**
     * @param instanceID the instanceID to set
     */
    public void setInstanceID(int instanceID) {
        this.instanceID = instanceID;
    }

    /**
     * @param iDXP the iDXP to set
     */
    public void setIDXP(String iDXP) {
        IDXP = iDXP;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("InterceptEvent [idEvent=");
        builder.append(idEvent);
        builder.append(", IDXP=");
        builder.append(this.IDXP);
        builder.append(", timestamp=");
        builder.append(timestamp);
        builder.append(", hookerName=");
        builder.append(hookerName);
        builder.append(", intrusiveLevel=");
        builder.append(intrusiveLevel);
        builder.append(", instanceID=");
        builder.append(instanceID);
        builder.append(", packageName=");
        builder.append(packageName);
        builder.append(", className=");
        builder.append(className);
        builder.append(", methodName=");
        builder.append(methodName);
        builder.append("]");
        return builder.toString();
    }

    /**
     * @return
     */
    public String toJson() {
        JSONObject object = new JSONObject();

        try {
            //      object.put("IdEvent", this.getIdEvent().toString());

            object.put("Timestamp", this.getTimestamp());
            object.put("RelativeTimestamp", this.getRelativeTimestamp());
            object.put("HookerName", this.getHookerName());
            object.put("IntrusiveLevel", this.getIntrusiveLevel());
            object.put("InstanceID", this.getInstanceID());
            object.put("PackageName", this.getPackageName());

            object.put("ClassName", this.getClassName());
            object.put("MethodName", this.getMethodName());

            JSONArray parameters = new JSONArray();
            if (this.getParameters() != null) {
                for (Entry<String, String> parameter : this.getParameters()) {
                    JSONObject jsonParameter = new JSONObject();
                    jsonParameter.put("ParameterType", parameter.getKey());
                    jsonParameter.put("ParameterValue", parameter.getValue());
                    parameters.put(jsonParameter);
                }
            }
            object.put("Parameters", parameters);

            JSONObject returns = new JSONObject();
            if (this.getReturns() != null) {
                returns.put("ReturnType", this.getReturns().getKey());
                returns.put("ReturnValue", this.getReturns().getValue());
            }
            object.put("Return", returns);

            JSONArray data = new JSONArray();
            if (this.getData() != null) {
                for (String dataName : this.getData().keySet()) {
                    if (dataName != null && this.getData().get(dataName) != null) {
                        JSONObject dataP = new JSONObject();
                        dataP.put("DataName", dataName);
                        dataP.put("DataValue", this.getData().get(dataName));
                    }
                }
            }
            object.put("Data", data);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return object.toString();
    }
}