Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <android_runtime/AndroidRuntime.h>
     18 #include <nativehelper/JNIHelp.h>
     19 #include <jni.h>
     20 #include <nativehelper/ScopedUtfChars.h>
     21 
     22 #include <utils/misc.h>
     23 #include <sys/ioctl.h>
     24 #include <sys/mount.h>
     25 #include <utils/Log.h>
     26 
     27 
     28 #include <inttypes.h>
     29 #include <fcntl.h>
     30 #include <errno.h>
     31 #include <string.h>
     32 
     33 namespace android {
     34 
     35     uint64_t get_block_device_size(int fd)
     36     {
     37         uint64_t size = 0;
     38         int ret;
     39 
     40         ret = ioctl(fd, BLKGETSIZE64, &size);
     41 
     42         if (ret)
     43             return 0;
     44 
     45         return size;
     46     }
     47 
     48     int wipe_block_device(int fd)
     49     {
     50         uint64_t range[2];
     51         int ret;
     52         uint64_t len = get_block_device_size(fd);
     53 
     54         range[0] = 0;
     55         range[1] = len;
     56 
     57         if (range[1] == 0)
     58             return 0;
     59 
     60         ret = ioctl(fd, BLKSECDISCARD, &range);
     61         if (ret < 0) {
     62             ALOGE("Something went wrong secure discarding block: %s\n", strerror(errno));
     63             range[0] = 0;
     64             range[1] = len;
     65             ret = ioctl(fd, BLKDISCARD, &range);
     66             if (ret < 0) {
     67                 ALOGE("Discard failed: %s\n", strerror(errno));
     68                 return -1;
     69             } else {
     70                 ALOGE("Wipe via secure discard failed, used non-secure discard instead\n");
     71                 return 0;
     72             }
     73 
     74         }
     75 
     76         return ret;
     77     }
     78 
     79     static jlong com_android_server_PersistentDataBlockService_getBlockDeviceSize(JNIEnv *env, jclass, jstring jpath)
     80     {
     81         ScopedUtfChars path(env, jpath);
     82         int fd = open(path.c_str(), O_RDONLY);
     83 
     84         if (fd < 0)
     85             return 0;
     86 
     87         const uint64_t size = get_block_device_size(fd);
     88 
     89         close(fd);
     90 
     91         return size;
     92     }
     93 
     94     static int com_android_server_PersistentDataBlockService_wipe(JNIEnv *env, jclass, jstring jpath) {
     95         ScopedUtfChars path(env, jpath);
     96         int fd = open(path.c_str(), O_WRONLY);
     97 
     98         if (fd < 0)
     99             return 0;
    100 
    101         const int ret = wipe_block_device(fd);
    102 
    103         close(fd);
    104 
    105         return ret;
    106     }
    107 
    108     static const JNINativeMethod sMethods[] = {
    109          /* name, signature, funcPtr */
    110         {"nativeGetBlockDeviceSize", "(Ljava/lang/String;)J", (void*)com_android_server_PersistentDataBlockService_getBlockDeviceSize},
    111         {"nativeWipe", "(Ljava/lang/String;)I", (void*)com_android_server_PersistentDataBlockService_wipe},
    112     };
    113 
    114     int register_android_server_PersistentDataBlockService(JNIEnv* env)
    115     {
    116         return jniRegisterNativeMethods(env, "com/android/server/PersistentDataBlockService",
    117                                         sMethods, NELEM(sMethods));
    118     }
    119 
    120 } /* namespace android */