Merge "Revert^2 "Remove deprecated Beam APIs""
This commit is contained in:
@@ -27503,24 +27503,15 @@ package android.nfc {
|
||||
|
||||
public final class NfcAdapter {
|
||||
method public void disableForegroundDispatch(android.app.Activity);
|
||||
method @Deprecated public void disableForegroundNdefPush(android.app.Activity);
|
||||
method public void disableReaderMode(android.app.Activity);
|
||||
method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]);
|
||||
method @Deprecated public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
|
||||
method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
|
||||
method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
|
||||
method @Nullable public android.nfc.NfcAntennaInfo getNfcAntennaInfo();
|
||||
method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler);
|
||||
method @Deprecated public boolean invokeBeam(android.app.Activity);
|
||||
method public boolean isEnabled();
|
||||
method @Deprecated public boolean isNdefPushEnabled();
|
||||
method public boolean isSecureNfcEnabled();
|
||||
method public boolean isSecureNfcSupported();
|
||||
method @Deprecated public void setBeamPushUris(android.net.Uri[], android.app.Activity);
|
||||
method @Deprecated public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity);
|
||||
method @Deprecated public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
|
||||
method @Deprecated public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...);
|
||||
method @Deprecated public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
|
||||
field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
|
||||
field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
|
||||
field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
|
||||
|
||||
@@ -252,6 +252,22 @@ package android.net {
|
||||
|
||||
}
|
||||
|
||||
package android.nfc {
|
||||
|
||||
public final class NfcAdapter {
|
||||
method @Deprecated public void disableForegroundNdefPush(android.app.Activity);
|
||||
method @Deprecated public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
|
||||
method @Deprecated public boolean invokeBeam(android.app.Activity);
|
||||
method @Deprecated public boolean isNdefPushEnabled();
|
||||
method @Deprecated public void setBeamPushUris(android.net.Uri[], android.app.Activity);
|
||||
method @Deprecated public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity);
|
||||
method @Deprecated public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
|
||||
method @Deprecated public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...);
|
||||
method @Deprecated public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.os {
|
||||
|
||||
public class BatteryManager {
|
||||
|
||||
@@ -9112,9 +9112,7 @@ package android.nfc {
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean addNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler, String[]);
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable();
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush();
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
|
||||
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
|
||||
@@ -9123,10 +9121,8 @@ package android.nfc {
|
||||
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
|
||||
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean);
|
||||
method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
|
||||
field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
|
||||
field public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff
|
||||
field public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0; // 0x0
|
||||
field public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2; // 0xfffffffe
|
||||
|
||||
@@ -140,6 +140,17 @@ package android.media.tv {
|
||||
|
||||
}
|
||||
|
||||
package android.nfc {
|
||||
|
||||
public final class NfcAdapter {
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush();
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
|
||||
method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
|
||||
field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.os {
|
||||
|
||||
public class Build {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.nfc;
|
||||
|
||||
parcelable BeamShareData;
|
||||
@@ -1,67 +0,0 @@
|
||||
package android.nfc;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.UserHandle;
|
||||
|
||||
/**
|
||||
* Class to IPC data to be shared over Android Beam.
|
||||
* Allows bundling NdefMessage, Uris and flags in a single
|
||||
* IPC call. This is important as we want to reduce the
|
||||
* amount of IPC calls at "touch time".
|
||||
* @hide
|
||||
*/
|
||||
public final class BeamShareData implements Parcelable {
|
||||
public final NdefMessage ndefMessage;
|
||||
public final Uri[] uris;
|
||||
public final UserHandle userHandle;
|
||||
public final int flags;
|
||||
|
||||
public BeamShareData(NdefMessage msg, Uri[] uris, UserHandle userHandle, int flags) {
|
||||
this.ndefMessage = msg;
|
||||
this.uris = uris;
|
||||
this.userHandle = userHandle;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
int urisLength = (uris != null) ? uris.length : 0;
|
||||
dest.writeParcelable(ndefMessage, 0);
|
||||
dest.writeInt(urisLength);
|
||||
if (urisLength > 0) {
|
||||
dest.writeTypedArray(uris, 0);
|
||||
}
|
||||
dest.writeParcelable(userHandle, 0);
|
||||
dest.writeInt(this.flags);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<BeamShareData> CREATOR =
|
||||
new Parcelable.Creator<BeamShareData>() {
|
||||
@Override
|
||||
public BeamShareData createFromParcel(Parcel source) {
|
||||
Uri[] uris = null;
|
||||
NdefMessage msg = source.readParcelable(NdefMessage.class.getClassLoader(), android.nfc.NdefMessage.class);
|
||||
int numUris = source.readInt();
|
||||
if (numUris > 0) {
|
||||
uris = new Uri[numUris];
|
||||
source.readTypedArray(uris, Uri.CREATOR);
|
||||
}
|
||||
UserHandle userHandle = source.readParcelable(UserHandle.class.getClassLoader(), android.os.UserHandle.class);
|
||||
int flags = source.readInt();
|
||||
|
||||
return new BeamShareData(msg, uris, userHandle, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeamShareData[] newArray(int size) {
|
||||
return new BeamShareData[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package android.nfc;
|
||||
|
||||
import android.nfc.BeamShareData;
|
||||
import android.nfc.Tag;
|
||||
|
||||
/**
|
||||
@@ -24,7 +23,5 @@ import android.nfc.Tag;
|
||||
*/
|
||||
interface IAppCallback
|
||||
{
|
||||
BeamShareData createBeamShareData(byte peerLlcpVersion);
|
||||
oneway void onNdefPushComplete(byte peerLlcpVersion);
|
||||
oneway void onTagDiscovered(in Tag tag);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package android.nfc;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.IntentFilter;
|
||||
import android.nfc.BeamShareData;
|
||||
import android.nfc.NdefMessage;
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.TechListParcel;
|
||||
@@ -47,24 +46,18 @@ interface INfcAdapter
|
||||
int getState();
|
||||
boolean disable(boolean saveState);
|
||||
boolean enable();
|
||||
boolean enableNdefPush();
|
||||
boolean disableNdefPush();
|
||||
boolean isNdefPushEnabled();
|
||||
void pausePolling(int timeoutInMs);
|
||||
void resumePolling();
|
||||
|
||||
void setForegroundDispatch(in PendingIntent intent,
|
||||
in IntentFilter[] filters, in TechListParcel techLists);
|
||||
void setAppCallback(in IAppCallback callback);
|
||||
oneway void invokeBeam();
|
||||
oneway void invokeBeamInternal(in BeamShareData shareData);
|
||||
|
||||
boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback);
|
||||
|
||||
void dispatch(in Tag tag);
|
||||
|
||||
void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras);
|
||||
void setP2pModes(int initatorModes, int targetModes);
|
||||
|
||||
void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList);
|
||||
void removeNfcUnlockHandler(INfcUnlockHandler unlockHandler);
|
||||
|
||||
@@ -19,9 +19,6 @@ package android.nfc;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.nfc.NfcAdapter.ReaderCallback;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
@@ -110,14 +107,8 @@ public final class NfcActivityManager extends IAppCallback.Stub
|
||||
class NfcActivityState {
|
||||
boolean resumed = false;
|
||||
Activity activity;
|
||||
NdefMessage ndefMessage = null; // static NDEF message
|
||||
NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
|
||||
NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
|
||||
NfcAdapter.CreateBeamUrisCallback uriCallback = null;
|
||||
Uri[] uris = null;
|
||||
int flags = 0;
|
||||
int readerModeFlags = 0;
|
||||
NfcAdapter.ReaderCallback readerCallback = null;
|
||||
int readerModeFlags = 0;
|
||||
Bundle readerModeExtras = null;
|
||||
Binder token;
|
||||
|
||||
@@ -137,24 +128,16 @@ public final class NfcActivityManager extends IAppCallback.Stub
|
||||
unregisterApplication(activity.getApplication());
|
||||
resumed = false;
|
||||
activity = null;
|
||||
ndefMessage = null;
|
||||
ndefMessageCallback = null;
|
||||
onNdefPushCompleteCallback = null;
|
||||
uriCallback = null;
|
||||
uris = null;
|
||||
readerCallback = null;
|
||||
readerModeFlags = 0;
|
||||
readerModeExtras = null;
|
||||
token = null;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder("[").append(" ");
|
||||
s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
|
||||
s.append(uriCallback).append(" ");
|
||||
if (uris != null) {
|
||||
for (Uri uri : uris) {
|
||||
s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
|
||||
}
|
||||
}
|
||||
StringBuilder s = new StringBuilder("[");
|
||||
s.append(readerCallback);
|
||||
s.append("]");
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
@@ -245,92 +228,6 @@ public final class NfcActivityManager extends IAppCallback.Stub
|
||||
}
|
||||
}
|
||||
|
||||
public void setNdefPushContentUri(Activity activity, Uri[] uris) {
|
||||
boolean isResumed;
|
||||
synchronized (NfcActivityManager.this) {
|
||||
NfcActivityState state = getActivityState(activity);
|
||||
state.uris = uris;
|
||||
isResumed = state.resumed;
|
||||
}
|
||||
if (isResumed) {
|
||||
// requestNfcServiceCallback() verifies permission also
|
||||
requestNfcServiceCallback();
|
||||
} else {
|
||||
// Crash API calls early in case NFC permission is missing
|
||||
verifyNfcPermission();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setNdefPushContentUriCallback(Activity activity,
|
||||
NfcAdapter.CreateBeamUrisCallback callback) {
|
||||
boolean isResumed;
|
||||
synchronized (NfcActivityManager.this) {
|
||||
NfcActivityState state = getActivityState(activity);
|
||||
state.uriCallback = callback;
|
||||
isResumed = state.resumed;
|
||||
}
|
||||
if (isResumed) {
|
||||
// requestNfcServiceCallback() verifies permission also
|
||||
requestNfcServiceCallback();
|
||||
} else {
|
||||
// Crash API calls early in case NFC permission is missing
|
||||
verifyNfcPermission();
|
||||
}
|
||||
}
|
||||
|
||||
public void setNdefPushMessage(Activity activity, NdefMessage message, int flags) {
|
||||
boolean isResumed;
|
||||
synchronized (NfcActivityManager.this) {
|
||||
NfcActivityState state = getActivityState(activity);
|
||||
state.ndefMessage = message;
|
||||
state.flags = flags;
|
||||
isResumed = state.resumed;
|
||||
}
|
||||
if (isResumed) {
|
||||
// requestNfcServiceCallback() verifies permission also
|
||||
requestNfcServiceCallback();
|
||||
} else {
|
||||
// Crash API calls early in case NFC permission is missing
|
||||
verifyNfcPermission();
|
||||
}
|
||||
}
|
||||
|
||||
public void setNdefPushMessageCallback(Activity activity,
|
||||
NfcAdapter.CreateNdefMessageCallback callback, int flags) {
|
||||
boolean isResumed;
|
||||
synchronized (NfcActivityManager.this) {
|
||||
NfcActivityState state = getActivityState(activity);
|
||||
state.ndefMessageCallback = callback;
|
||||
state.flags = flags;
|
||||
isResumed = state.resumed;
|
||||
}
|
||||
if (isResumed) {
|
||||
// requestNfcServiceCallback() verifies permission also
|
||||
requestNfcServiceCallback();
|
||||
} else {
|
||||
// Crash API calls early in case NFC permission is missing
|
||||
verifyNfcPermission();
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnNdefPushCompleteCallback(Activity activity,
|
||||
NfcAdapter.OnNdefPushCompleteCallback callback) {
|
||||
boolean isResumed;
|
||||
synchronized (NfcActivityManager.this) {
|
||||
NfcActivityState state = getActivityState(activity);
|
||||
state.onNdefPushCompleteCallback = callback;
|
||||
isResumed = state.resumed;
|
||||
}
|
||||
if (isResumed) {
|
||||
// requestNfcServiceCallback() verifies permission also
|
||||
requestNfcServiceCallback();
|
||||
} else {
|
||||
// Crash API calls early in case NFC permission is missing
|
||||
verifyNfcPermission();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request or unrequest NFC service callbacks.
|
||||
* Makes IPC call - do not hold lock.
|
||||
@@ -351,86 +248,6 @@ public final class NfcActivityManager extends IAppCallback.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback from NFC service, usually on binder thread */
|
||||
@Override
|
||||
public BeamShareData createBeamShareData(byte peerLlcpVersion) {
|
||||
NfcAdapter.CreateNdefMessageCallback ndefCallback;
|
||||
NfcAdapter.CreateBeamUrisCallback urisCallback;
|
||||
NdefMessage message;
|
||||
Activity activity;
|
||||
Uri[] uris;
|
||||
int flags;
|
||||
NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
|
||||
synchronized (NfcActivityManager.this) {
|
||||
NfcActivityState state = findResumedActivityState();
|
||||
if (state == null) return null;
|
||||
|
||||
ndefCallback = state.ndefMessageCallback;
|
||||
urisCallback = state.uriCallback;
|
||||
message = state.ndefMessage;
|
||||
uris = state.uris;
|
||||
flags = state.flags;
|
||||
activity = state.activity;
|
||||
}
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
// Make callbacks without lock
|
||||
if (ndefCallback != null) {
|
||||
message = ndefCallback.createNdefMessage(event);
|
||||
}
|
||||
if (urisCallback != null) {
|
||||
uris = urisCallback.createBeamUris(event);
|
||||
if (uris != null) {
|
||||
ArrayList<Uri> validUris = new ArrayList<Uri>();
|
||||
for (Uri uri : uris) {
|
||||
if (uri == null) {
|
||||
Log.e(TAG, "Uri not allowed to be null.");
|
||||
continue;
|
||||
}
|
||||
String scheme = uri.getScheme();
|
||||
if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
|
||||
!scheme.equalsIgnoreCase("content"))) {
|
||||
Log.e(TAG, "Uri needs to have " +
|
||||
"either scheme file or scheme content");
|
||||
continue;
|
||||
}
|
||||
uri = ContentProvider.maybeAddUserId(uri, activity.getUserId());
|
||||
validUris.add(uri);
|
||||
}
|
||||
|
||||
uris = validUris.toArray(new Uri[validUris.size()]);
|
||||
}
|
||||
}
|
||||
if (uris != null && uris.length > 0) {
|
||||
for (Uri uri : uris) {
|
||||
// Grant the NFC process permission to read these URIs
|
||||
activity.grantUriPermission("com.android.nfc", uri,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
return new BeamShareData(message, uris, activity.getUser(), flags);
|
||||
}
|
||||
|
||||
/** Callback from NFC service, usually on binder thread */
|
||||
@Override
|
||||
public void onNdefPushComplete(byte peerLlcpVersion) {
|
||||
NfcAdapter.OnNdefPushCompleteCallback callback;
|
||||
synchronized (NfcActivityManager.this) {
|
||||
NfcActivityState state = findResumedActivityState();
|
||||
if (state == null) return;
|
||||
|
||||
callback = state.onNdefPushCompleteCallback;
|
||||
}
|
||||
NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
|
||||
// Make callback without lock
|
||||
if (callback != null) {
|
||||
callback.onNdefPushComplete(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTagDiscovered(Tag tag) throws RemoteException {
|
||||
NfcAdapter.ReaderCallback callback;
|
||||
|
||||
@@ -343,8 +343,12 @@ public final class NfcAdapter {
|
||||
*/
|
||||
public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* @hide
|
||||
* @removed
|
||||
*/
|
||||
@SystemApi
|
||||
@UnsupportedAppUsage
|
||||
public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1;
|
||||
|
||||
/** @hide */
|
||||
@@ -418,7 +422,6 @@ public final class NfcAdapter {
|
||||
// Guarded by NfcAdapter.class
|
||||
static boolean sIsInitialized = false;
|
||||
static boolean sHasNfcFeature;
|
||||
static boolean sHasBeamFeature;
|
||||
static boolean sHasCeFeature;
|
||||
|
||||
// Final after first constructor, except for
|
||||
@@ -484,7 +487,7 @@ public final class NfcAdapter {
|
||||
* A callback to be invoked when the system successfully delivers your {@link NdefMessage}
|
||||
* to another device.
|
||||
* @see #setOnNdefPushCompleteCallback
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @deprecated this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
@@ -510,7 +513,7 @@ public final class NfcAdapter {
|
||||
* content currently visible to the user. Alternatively, you can call {@link
|
||||
* #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the
|
||||
* same data.
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @deprecated this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
@@ -540,7 +543,7 @@ public final class NfcAdapter {
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @deprecated this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
@@ -616,7 +619,6 @@ public final class NfcAdapter {
|
||||
PackageManager pm;
|
||||
pm = context.getPackageManager();
|
||||
sHasNfcFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC);
|
||||
sHasBeamFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM);
|
||||
sHasCeFeature =
|
||||
pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
|
||||
|| pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)
|
||||
@@ -1114,35 +1116,17 @@ public final class NfcAdapter {
|
||||
* @param uris an array of Uri(s) to push over Android Beam
|
||||
* @param activity activity for which the Uri(s) will be pushed
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @removed this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
@UnsupportedAppUsage
|
||||
public void setBeamPushUris(Uri[] uris, Activity activity) {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (!sHasBeamFeature) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity cannot be null");
|
||||
}
|
||||
if (uris != null) {
|
||||
for (Uri uri : uris) {
|
||||
if (uri == null) throw new NullPointerException("Uri not " +
|
||||
"allowed to be null");
|
||||
String scheme = uri.getScheme();
|
||||
if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
|
||||
!scheme.equalsIgnoreCase("content"))) {
|
||||
throw new IllegalArgumentException("URI needs to have " +
|
||||
"either scheme file or scheme content");
|
||||
}
|
||||
}
|
||||
}
|
||||
mNfcActivityManager.setNdefPushContentUri(activity, uris);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1202,23 +1186,17 @@ public final class NfcAdapter {
|
||||
* @param callback callback, or null to disable
|
||||
* @param activity activity for which the Uri(s) will be pushed
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @removed this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
@UnsupportedAppUsage
|
||||
public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (!sHasBeamFeature) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity cannot be null");
|
||||
}
|
||||
mNfcActivityManager.setNdefPushContentUriCallback(activity, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1292,58 +1270,32 @@ public final class NfcAdapter {
|
||||
* to only register one at a time, and to do so in that activity's
|
||||
* {@link Activity#onCreate}
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @removed this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
@UnsupportedAppUsage
|
||||
public void setNdefPushMessage(NdefMessage message, Activity activity,
|
||||
Activity ... activities) {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (!sHasBeamFeature) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int targetSdkVersion = getSdkVersion();
|
||||
try {
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity cannot be null");
|
||||
}
|
||||
mNfcActivityManager.setNdefPushMessage(activity, message, 0);
|
||||
for (Activity a : activities) {
|
||||
if (a == null) {
|
||||
throw new NullPointerException("activities cannot contain null");
|
||||
}
|
||||
mNfcActivityManager.setNdefPushMessage(a, message, 0);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
||||
// Less strict on old applications - just log the error
|
||||
Log.e(TAG, "Cannot call API with Activity that has already " +
|
||||
"been destroyed", e);
|
||||
} else {
|
||||
// Prevent new applications from making this mistake, re-throw
|
||||
throw(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @removed
|
||||
*/
|
||||
@SystemApi
|
||||
@UnsupportedAppUsage
|
||||
public void setNdefPushMessage(NdefMessage message, Activity activity, int flags) {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity cannot be null");
|
||||
}
|
||||
mNfcActivityManager.setNdefPushMessage(activity, message, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1411,54 +1363,18 @@ public final class NfcAdapter {
|
||||
* to only register one at a time, and to do so in that activity's
|
||||
* {@link Activity#onCreate}
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @removed this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
@UnsupportedAppUsage
|
||||
public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
|
||||
Activity ... activities) {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (!sHasBeamFeature) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int targetSdkVersion = getSdkVersion();
|
||||
try {
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity cannot be null");
|
||||
}
|
||||
mNfcActivityManager.setNdefPushMessageCallback(activity, callback, 0);
|
||||
for (Activity a : activities) {
|
||||
if (a == null) {
|
||||
throw new NullPointerException("activities cannot contain null");
|
||||
}
|
||||
mNfcActivityManager.setNdefPushMessageCallback(a, callback, 0);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
||||
// Less strict on old applications - just log the error
|
||||
Log.e(TAG, "Cannot call API with Activity that has already " +
|
||||
"been destroyed", e);
|
||||
} else {
|
||||
// Prevent new applications from making this mistake, re-throw
|
||||
throw(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
|
||||
int flags) {
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity cannot be null");
|
||||
}
|
||||
mNfcActivityManager.setNdefPushMessageCallback(activity, callback, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1498,41 +1414,17 @@ public final class NfcAdapter {
|
||||
* to only register one at a time, and to do so in that activity's
|
||||
* {@link Activity#onCreate}
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @removed this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
@UnsupportedAppUsage
|
||||
public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
|
||||
Activity activity, Activity ... activities) {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (!sHasBeamFeature) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int targetSdkVersion = getSdkVersion();
|
||||
try {
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity cannot be null");
|
||||
}
|
||||
mNfcActivityManager.setOnNdefPushCompleteCallback(activity, callback);
|
||||
for (Activity a : activities) {
|
||||
if (a == null) {
|
||||
throw new NullPointerException("activities cannot contain null");
|
||||
}
|
||||
mNfcActivityManager.setOnNdefPushCompleteCallback(a, callback);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
||||
// Less strict on old applications - just log the error
|
||||
Log.e(TAG, "Cannot call API with Activity that has already " +
|
||||
"been destroyed", e);
|
||||
} else {
|
||||
// Prevent new applications from making this mistake, re-throw
|
||||
throw(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1715,46 +1607,18 @@ public final class NfcAdapter {
|
||||
* @param activity the current foreground Activity that has registered data to share
|
||||
* @return whether the Beam animation was successfully invoked
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @removed this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
@UnsupportedAppUsage
|
||||
public boolean invokeBeam(Activity activity) {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (!sHasBeamFeature) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity may not be null.");
|
||||
}
|
||||
enforceResumed(activity);
|
||||
try {
|
||||
sService.invokeBeam();
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "invokeBeam: NFC process has died.");
|
||||
attemptDeadServiceRecovery(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public boolean invokeBeam(BeamShareData shareData) {
|
||||
try {
|
||||
Log.e(TAG, "invokeBeamInternal()");
|
||||
sService.invokeBeamInternal(shareData);
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "invokeBeam: NFC process has died.");
|
||||
attemptDeadServiceRecovery(e);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1780,25 +1644,18 @@ public final class NfcAdapter {
|
||||
*
|
||||
* @param activity foreground activity
|
||||
* @param message a NDEF Message to push over NFC
|
||||
* @throws IllegalStateException if the activity is not currently in the foreground
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||
* @deprecated use {@link #setNdefPushMessage} instead
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable
|
||||
* @removed this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@Deprecated
|
||||
@UnsupportedAppUsage
|
||||
public void enableForegroundNdefPush(Activity activity, NdefMessage message) {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (!sHasBeamFeature) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (activity == null || message == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
enforceResumed(activity);
|
||||
mNfcActivityManager.setNdefPushMessage(activity, message, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1817,27 +1674,18 @@ public final class NfcAdapter {
|
||||
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
|
||||
*
|
||||
* @param activity the Foreground activity
|
||||
* @throws IllegalStateException if the Activity has already been paused
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||
* @deprecated use {@link #setNdefPushMessage} instead
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable
|
||||
* @removed this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@Deprecated
|
||||
@UnsupportedAppUsage
|
||||
public void disableForegroundNdefPush(Activity activity) {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (!sHasBeamFeature) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (activity == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
enforceResumed(activity);
|
||||
mNfcActivityManager.setNdefPushMessage(activity, null, 0);
|
||||
mNfcActivityManager.setNdefPushMessageCallback(activity, null, 0);
|
||||
mNfcActivityManager.setOnNdefPushCompleteCallback(activity, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1971,40 +1819,26 @@ public final class NfcAdapter {
|
||||
* Enable NDEF Push feature.
|
||||
* <p>This API is for the Settings application.
|
||||
* @hide
|
||||
* @removed
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
|
||||
@UnsupportedAppUsage
|
||||
public boolean enableNdefPush() {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
try {
|
||||
return sService.enableNdefPush();
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable NDEF Push feature.
|
||||
* <p>This API is for the Settings application.
|
||||
* @hide
|
||||
* @removed
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
|
||||
@UnsupportedAppUsage
|
||||
public boolean disableNdefPush() {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
try {
|
||||
return sService.disableNdefPush();
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2030,26 +1864,18 @@ public final class NfcAdapter {
|
||||
* @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS
|
||||
* @return true if NDEF Push feature is enabled
|
||||
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||
* @deprecated this feature is deprecated. File sharing can work using other technology like
|
||||
* @removed this feature is removed. File sharing can work using other technology like
|
||||
* Bluetooth.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public boolean isNdefPushEnabled() {
|
||||
synchronized (NfcAdapter.class) {
|
||||
if (!sHasNfcFeature) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (!sHasBeamFeature) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
return sService.isNdefPushEnabled();
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2139,17 +1965,6 @@ public final class NfcAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setP2pModes(int initiatorModes, int targetModes) {
|
||||
try {
|
||||
sService.setP2pModes(initiatorModes, targetModes);
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new NFC unlock handler with the NFC service.
|
||||
*
|
||||
|
||||
@@ -806,12 +806,9 @@ public class Build {
|
||||
* PackageManager.setComponentEnabledSetting} will now throw an
|
||||
* IllegalArgumentException if the given component class name does not
|
||||
* exist in the application's manifest.
|
||||
* <li> {@link android.nfc.NfcAdapter#setNdefPushMessage
|
||||
* NfcAdapter.setNdefPushMessage},
|
||||
* {@link android.nfc.NfcAdapter#setNdefPushMessageCallback
|
||||
* NfcAdapter.setNdefPushMessageCallback} and
|
||||
* {@link android.nfc.NfcAdapter#setOnNdefPushCompleteCallback
|
||||
* NfcAdapter.setOnNdefPushCompleteCallback} will throw
|
||||
* <li> {@code NfcAdapter.setNdefPushMessage},
|
||||
* {@code NfcAdapter.setNdefPushMessageCallback} and
|
||||
* {@code NfcAdapter.setOnNdefPushCompleteCallback} will throw
|
||||
* IllegalStateException if called after the Activity has been destroyed.
|
||||
* <li> Accessibility services must require the new
|
||||
* {@link android.Manifest.permission#BIND_ACCESSIBILITY_SERVICE} permission or
|
||||
|
||||
@@ -1596,7 +1596,6 @@ public final class Settings {
|
||||
* Input: Nothing.
|
||||
* <p>
|
||||
* Output: Nothing
|
||||
* @see android.nfc.NfcAdapter#isNdefPushEnabled()
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
|
||||
public static final String ACTION_NFCSHARING_SETTINGS =
|
||||
|
||||
@@ -60,7 +60,7 @@ message NfcServiceDumpProto {
|
||||
optional bool secure_nfc_capable = 13;
|
||||
optional bool vr_mode_enabled = 14;
|
||||
optional DiscoveryParamsProto discovery_params = 15;
|
||||
optional P2pLinkManagerProto p2p_link_manager = 16;
|
||||
reserved 16;
|
||||
optional com.android.nfc.cardemulation.CardEmulationManagerProto card_emulation_manager = 17;
|
||||
optional NfcDispatcherProto nfc_dispatcher = 18;
|
||||
optional string native_crash_logs = 19 [(.android.privacy).dest = DEST_EXPLICIT];
|
||||
@@ -77,38 +77,6 @@ message DiscoveryParamsProto {
|
||||
optional bool enable_p2p = 5;
|
||||
}
|
||||
|
||||
// Debugging information for com.android.nfc.P2pLinkManager
|
||||
message P2pLinkManagerProto {
|
||||
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
|
||||
|
||||
enum LinkState {
|
||||
LINK_STATE_UNKNOWN = 0;
|
||||
LINK_STATE_DOWN = 1;
|
||||
LINK_STATE_DEBOUNCE = 2;
|
||||
LINK_STATE_UP = 3;
|
||||
}
|
||||
|
||||
enum SendState {
|
||||
SEND_STATE_UNKNOWN = 0;
|
||||
SEND_STATE_NOTHING_TO_SEND = 1;
|
||||
SEND_STATE_NEED_CONFIRMATION = 2;
|
||||
SEND_STATE_SENDING = 3;
|
||||
SEND_STATE_COMPLETE = 4;
|
||||
SEND_STATE_CANCELED = 5;
|
||||
}
|
||||
|
||||
optional int32 default_miu = 1;
|
||||
optional int32 default_rw_size = 2;
|
||||
optional LinkState link_state = 3;
|
||||
optional SendState send_state = 4;
|
||||
optional int32 send_flags = 5;
|
||||
optional bool send_enabled = 6;
|
||||
optional bool receive_enabled = 7;
|
||||
optional string callback_ndef = 8 [(.android.privacy).dest = DEST_EXPLICIT];
|
||||
optional .android.nfc.NdefMessageProto message_to_send = 9;
|
||||
repeated string uris_to_send = 10 [(.android.privacy).dest = DEST_EXPLICIT];
|
||||
}
|
||||
|
||||
// Debugging information for com.android.nfc.NfcDispatcher
|
||||
message NfcDispatcherProto {
|
||||
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
|
||||
|
||||
Reference in New Issue
Block a user