Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56c85244 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

MTP: Add support for battery level device property

Bug: 7342482

Change-Id: I810e55fe9695e2206816f57334ad14f65e9c641d
parent daeb3936
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -16,15 +16,19 @@

package android.mtp;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContentValues;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.MediaScanner;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.RemoteException;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio;
@@ -113,11 +117,35 @@ public class MtpDatabase {
                                            + Files.FileColumns.PARENT + "=?";

    private final MediaScanner mMediaScanner;
    private MtpServer mServer;

    // read from native code
    private int mBatteryLevel;
    private int mBatteryScale;

    static {
        System.loadLibrary("media_jni");
    }

    private BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() {
          @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                mBatteryScale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
                int newLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
                if (newLevel != mBatteryLevel) {
                    mBatteryLevel = newLevel;
                    if (mServer != null) {
                        // send device property changed event
                        mServer.sendDevicePropertyChanged(
                                MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL);
                    }
                }
            }
        }
    };

    public MtpDatabase(Context context, String volumeName, String storagePath,
            String[] subDirectories) {
        native_setup();
@@ -171,6 +199,18 @@ public class MtpDatabase {
        initDeviceProperties(context);
    }

    public void setServer(MtpServer server) {
        mServer = server;

        // register for battery notifications when we are connected
        if (server != null) {
            mContext.registerReceiver(mBatteryReceiver,
                    new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        } else {
            mContext.unregisterReceiver(mBatteryReceiver);
        }
    }

    @Override
    protected void finalize() throws Throwable {
        try {
@@ -663,6 +703,7 @@ public class MtpDatabase {
            MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,
            MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,
            MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE,
            MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL,
        };
    }

@@ -819,6 +860,8 @@ public class MtpDatabase {
                outStringValue[imageSize.length()] = 0;
                return MtpConstants.RESPONSE_OK;

            // DEVICE_PROPERTY_BATTERY_LEVEL is implemented in the JNI code

            default:
                return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
        }
+6 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ public class MtpServer implements Runnable {

    public MtpServer(MtpDatabase database, boolean usePtp) {
        native_setup(database, usePtp);
        database.setServer(this);
    }

    public void start() {
@@ -51,6 +52,10 @@ public class MtpServer implements Runnable {
        native_send_object_removed(handle);
    }

    public void sendDevicePropertyChanged(int property) {
        native_send_device_property_changed(property);
    }

    public void addStorage(MtpStorage storage) {
        native_add_storage(storage);
    }
@@ -64,6 +69,7 @@ public class MtpServer implements Runnable {
    private native final void native_cleanup();
    private native final void native_send_object_added(int handle);
    private native final void native_send_object_removed(int handle);
    private native final void native_send_device_property_changed(int property);
    private native final void native_add_storage(MtpStorage storage);
    private native final void native_remove_storage(int storageId);
}
+84 −58
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ static jmethodID method_sessionStarted;
static jmethodID method_sessionEnded;

static jfieldID field_context;
static jfieldID field_batteryLevel;
static jfieldID field_batteryScale;

// MtpPropertyList fields
static jfieldID field_mCount;
@@ -527,12 +529,18 @@ MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,

MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
                                            MtpDataPacket& packet) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();

    if (property == MTP_DEVICE_PROPERTY_BATTERY_LEVEL) {
        // special case - implemented here instead of Java
        packet.putUInt8((uint8_t)env->GetIntField(mDatabase, field_batteryLevel));
        return MTP_RESPONSE_OK;
    } else {
        int type;

        if (!getDevicePropertyInfo(property, type))
            return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;

    JNIEnv* env = AndroidRuntime::getJNIEnv();
        jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
                    (jint)property, mLongBuffer, mStringBuffer);
        if (result != MTP_RESPONSE_OK) {
@@ -590,6 +598,7 @@ MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property
        checkAndClearExceptionFromCallback(env, __FUNCTION__);
        return MTP_RESPONSE_OK;
    }
}

MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
                                            MtpDataPacket& packet) {
@@ -923,6 +932,7 @@ static const PropertyTableEntry kDevicePropertyTable[] = {
    {   MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,    MTP_TYPE_STR },
    {   MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,       MTP_TYPE_STR },
    {   MTP_DEVICE_PROPERTY_IMAGE_SIZE,                 MTP_TYPE_STR },
    {   MTP_DEVICE_PROPERTY_BATTERY_LEVEL,              MTP_TYPE_UINT8 },
};

bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
@@ -1046,7 +1056,7 @@ MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
        case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
            writable = true;
            // fall through
        case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
        case MTP_DEVICE_PROPERTY_IMAGE_SIZE: {
            result = new MtpProperty(property, MTP_TYPE_STR, writable);

            // get current value
@@ -1064,6 +1074,12 @@ MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
            }
            break;
        }
        case MTP_DEVICE_PROPERTY_BATTERY_LEVEL:
            result = new MtpProperty(property, MTP_TYPE_UINT8);
            result->setFormRange(0, env->GetIntField(mDatabase, field_batteryScale), 1);
            result->mCurrentValue.u.u8 = (uint8_t)env->GetIntField(mDatabase, field_batteryLevel);
            break;
    }

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
@@ -1234,6 +1250,16 @@ int register_android_mtp_MtpDatabase(JNIEnv *env)
        ALOGE("Can't find MtpDatabase.mNativeContext");
        return -1;
    }
    field_batteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
    if (field_batteryLevel == NULL) {
        ALOGE("Can't find MtpDatabase.mBatteryLevel");
        return -1;
    }
    field_batteryScale = env->GetFieldID(clazz, "mBatteryScale", "I");
    if (field_batteryScale == NULL) {
        ALOGE("Can't find MtpDatabase.mBatteryScale");
        return -1;
    }

    // now set up fields for MtpPropertyList class
    clazz = env->FindClass("android/mtp/MtpPropertyList");
+14 −0
Original line number Diff line number Diff line
@@ -117,6 +117,18 @@ android_mtp_MtpServer_send_object_removed(JNIEnv *env, jobject thiz, jint handle
        ALOGE("server is null in send_object_removed");
}

static void
android_mtp_MtpServer_send_device_property_changed(JNIEnv *env, jobject thiz, jint property)
{
    Mutex::Autolock autoLock(sMutex);

    MtpServer* server = getMtpServer(env, thiz);
    if (server)
        server->sendDevicePropertyChanged(property);
    else
        ALOGE("server is null in send_object_removed");
}

static void
android_mtp_MtpServer_add_storage(JNIEnv *env, jobject thiz, jobject jstorage)
{
@@ -174,6 +186,8 @@ static JNINativeMethod gMethods[] = {
    {"native_cleanup",              "()V",  (void *)android_mtp_MtpServer_cleanup},
    {"native_send_object_added",    "(I)V", (void *)android_mtp_MtpServer_send_object_added},
    {"native_send_object_removed",  "(I)V", (void *)android_mtp_MtpServer_send_object_removed},
    {"native_send_device_property_changed",  "(I)V",
                                    (void *)android_mtp_MtpServer_send_device_property_changed},
    {"native_add_storage",          "(Landroid/mtp/MtpStorage;)V",
                                            (void *)android_mtp_MtpServer_add_storage},
    {"native_remove_storage",       "(I)V", (void *)android_mtp_MtpServer_remove_storage},