下面列出了android.os.ParcelFileDescriptor#getFd ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private TextClassifierImplNative getNative(LocaleList localeList)
throws FileNotFoundException {
synchronized (mLock) {
localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;
final ModelFile bestModel = findBestModelLocked(localeList);
if (bestModel == null) {
throw new FileNotFoundException("No model for " + localeList.toLanguageTags());
}
if (mNative == null || mNative.isClosed() || !Objects.equals(mModel, bestModel)) {
Log.d(DEFAULT_LOG_TAG, "Loading " + bestModel);
final ParcelFileDescriptor fd = ParcelFileDescriptor.open(
new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
mNative = new TextClassifierImplNative(fd.getFd());
mNativeCleaner = Cleaner.create(this, new NativeCloser(mNative));
closeAndLogError(fd);
mModel = bestModel;
}
return mNative;
}
}
/**
* 指定したidに対応するUriが存在する時にその下に生成したファイルのrawファイルディスクリプタを返す
* @param context
* @param treeUri
* @param mime
* @param fileName
* @return
* @throws UnsupportedOperationException
* @throws FileNotFoundException
* @throws IOException
*/
@Deprecated
public static int createStorageFileFD(
@NonNull final Context context,
final Uri treeUri, final String mime, final String fileName)
throws IOException, UnsupportedOperationException {
if (DEBUG) Log.v(TAG, "createStorageFileFD:" + fileName);
if (BuildCheck.isLollipop()) {
if ((treeUri != null) && !TextUtils.isEmpty(fileName)) {
final DocumentFile saveTree = DocumentFile.fromTreeUri(context, treeUri);
final DocumentFile target = saveTree.createFile(mime, fileName);
try {
final ParcelFileDescriptor fd
= context.getContentResolver().openFileDescriptor(target.getUri(), "rw");
return fd != null ? fd.getFd() : 0;
} catch (final FileNotFoundException e) {
Log.w(TAG, e);
}
}
throw new FileNotFoundException();
} else {
throw new UnsupportedOperationException("should be API>=21");
}
}
private boolean sendTunFD(String needed, String extra) {
if (!extra.equals("tun")) {
// We only support tun
VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!", extra));
return false;
}
ParcelFileDescriptor pfd = mOpenVPNService.openTun();
if (pfd == null) return false;
Method setInt;
int fdint = pfd.getFd();
try {
setInt = FileDescriptor.class.getDeclaredMethod("setInt$", int.class);
FileDescriptor fdtosend = new FileDescriptor();
setInt.invoke(fdtosend, fdint);
FileDescriptor[] fds = {fdtosend};
mSocket.setFileDescriptorsForSend(fds);
// Trigger a send so we can close the fd on our side of the channel
// The API documentation fails to mention that it will not reset the file descriptor to
// be send and will happily send the file descriptor on every write ...
String cmd = String.format("needok '%s' %s\n", needed, "ok");
managmentCommand(cmd);
// Set the FileDescriptor to null to stop this mad behavior
mSocket.setFileDescriptorsForSend(null);
pfd.close();
return true;
} catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException |
IOException | IllegalAccessException exp) {
VpnStatus.logException("Could not send fd over socket", exp);
}
return false;
}
private boolean sendTunFD(String needed, String extra) {
if (!extra.equals("tun")) {
// We only support tun
VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!", extra));
return false;
}
ParcelFileDescriptor pfd = mOpenVPNService.openTun();
if (pfd == null)
return false;
Method setInt;
int fdint = pfd.getFd();
try {
setInt = FileDescriptor.class.getDeclaredMethod("setInt$", int.class);
FileDescriptor fdtosend = new FileDescriptor();
setInt.invoke(fdtosend, fdint);
FileDescriptor[] fds = {fdtosend};
mSocket.setFileDescriptorsForSend(fds);
// Trigger a send so we can close the fd on our side of the channel
// The API documentation fails to mention that it will not reset the file descriptor to
// be send and will happily send the file descriptor on every write ...
String cmd = String.format("needok '%s' %s\n", needed, "ok");
managmentCommand(cmd);
// Set the FileDescriptor to null to stop this mad behavior
mSocket.setFileDescriptorsForSend(null);
pfd.close();
return true;
} catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException |
IOException | IllegalAccessException exp) {
VpnStatus.logException("Could not send fd over socket", exp);
}
return false;
}
private boolean sendTunFD(String needed, String extra) {
if (!extra.equals("tun")) {
// We only support tun
VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!", extra));
return false;
}
ParcelFileDescriptor pfd = mOpenVPNService.openTun();
if (pfd == null) return false;
Method setInt;
int fdint = pfd.getFd();
try {
setInt = FileDescriptor.class.getDeclaredMethod("setInt$", int.class);
FileDescriptor fdtosend = new FileDescriptor();
setInt.invoke(fdtosend, fdint);
FileDescriptor[] fds = {fdtosend};
mSocket.setFileDescriptorsForSend(fds);
// Trigger a send so we can close the fd on our side of the channel
// The API documentation fails to mention that it will not reset the file descriptor to
// be send and will happily send the file descriptor on every write ...
String cmd = String.format("needok '%s' %s\n", needed, "ok");
managmentCommand(cmd);
// Set the FileDescriptor to null to stop this mad behavior
mSocket.setFileDescriptorsForSend(null);
pfd.close();
return true;
} catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException |
IOException | IllegalAccessException exp) {
VpnStatus.logException("Could not send fd over socket", exp);
}
return false;
}
public static File parcelFdToFile(ParcelFileDescriptor fd) {
return new File("/proc/self/fd/" + fd.getFd());
}
public PFDRandomAccessIO(ParcelFileDescriptor pfd)
{
super(pfd.getFd());
_pfd = pfd;
}
private boolean sendTunFD(String needed, String extra) {
if (!extra.equals("tun")) {
// We only support tun
VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!", extra));
return false;
}
ParcelFileDescriptor pfd = mOpenVPNService.openTun();
if (pfd == null)
return false;
Method setInt;
int fdint = pfd.getFd();
try {
setInt = FileDescriptor.class.getDeclaredMethod("setInt$", int.class);
FileDescriptor fdtosend = new FileDescriptor();
setInt.invoke(fdtosend, fdint);
FileDescriptor[] fds = {fdtosend};
mSocket.setFileDescriptorsForSend(fds);
// Trigger a send so we can close the fd on our side of the channel
// The API documentation fails to mention that it will not reset the file descriptor to
// be send and will happily send the file descriptor on every write ...
String cmd = String.format("needok '%s' %s\n", needed, "ok");
managmentCommand(cmd);
// Set the FileDescriptor to null to stop this mad behavior
mSocket.setFileDescriptorsForSend(null);
pfd.close();
return true;
} catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException |
IOException | IllegalAccessException exp) {
VpnStatus.logException("Could not send fd over socket", exp);
}
return false;
}
@Override
public void onWrite(
final PageRange[] ranges,
final ParcelFileDescriptor destination,
final CancellationSignal cancellationSignal,
final PrintDocumentAdapterWrapper.WriteResultCallbackWrapper callback) {
if (mPrintingContext == null) {
callback.onWriteFailed(mErrorMessage);
resetCallbacks();
return;
}
// TODO(cimamoglu): Make use of CancellationSignal.
mOnWriteCallback = callback;
mFileDescriptor = destination.getFd();
// Update file descriptor to PrintingContext mapping in the owner class.
mPrintingContext.updatePrintingContextMap(mFileDescriptor, false);
// We need to convert ranges list into an array of individual numbers for
// easier JNI passing and compatibility with the native side.
if (ranges.length == 1 && ranges[0].equals(PageRange.ALL_PAGES)) {
// null corresponds to all pages in Chromium printing logic.
mPages = null;
} else {
mPages = normalizeRanges(ranges);
}
if (mPrintingState == PRINTING_STATE_READY) {
// If this onWrite is without a preceding onLayout, start Chromium PDF generation here.
if (mPrintable.print()) {
mPrintingState = PRINTING_STATE_STARTED_FROM_ONWRITE;
} else {
callback.onWriteFailed(mErrorMessage);
resetCallbacks();
}
} else if (mPrintingState == PRINTING_STATE_STARTED_FROM_ONLAYOUT) {
// Otherwise, continue previously started operation.
mPrintingContext.askUserForSettingsReply(true);
}
// We are guaranteed by the framework that we will not have two onWrite calls at once.
// We may get a CancellationSignal, after replying it (via WriteResultCallback) we might
// get another onWrite call.
}
public static int getFd(ParcelFileDescriptor descriptor) {
return descriptor.getFd();
}
private boolean sendTunFD(String needed, String extra) {
if (!extra.equals("tun")) {
// We only support tun
VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!", extra));
return false;
}
ParcelFileDescriptor pfd = mOpenVPNService.openTun();
if (pfd == null)
return false;
Method setInt;
int fdint = pfd.getFd();
try {
setInt = FileDescriptor.class.getDeclaredMethod("setInt$", int.class);
FileDescriptor fdtosend = new FileDescriptor();
setInt.invoke(fdtosend, fdint);
FileDescriptor[] fds = {fdtosend};
mSocket.setFileDescriptorsForSend(fds);
// Trigger a send so we can close the fd on our side of the channel
// The API documentation fails to mention that it will not reset the file descriptor to
// be send and will happily send the file descriptor on every write ...
String cmd = String.format("needok '%s' %s\n", needed, "ok");
managmentCommand(cmd);
// Set the FileDescriptor to null to stop this mad behavior
mSocket.setFileDescriptorsForSend(null);
pfd.close();
return true;
} catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException |
IOException | IllegalAccessException exp) {
VpnStatus.logException("Could not send fd over socket", exp);
}
return false;
}