Merge changes from topic "VPN_APPOPS"
* changes: Add startOp and finishOp to track the behavior of VPN app Add new appOps to track the behavior of VPN app
This commit is contained in:
@@ -475,6 +475,8 @@ package android.app {
|
|||||||
field public static final String OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = "android:auto_revoke_permissions_if_unused";
|
field public static final String OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = "android:auto_revoke_permissions_if_unused";
|
||||||
field public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE = "android:bind_accessibility_service";
|
field public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE = "android:bind_accessibility_service";
|
||||||
field public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
|
field public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
|
||||||
|
field public static final String OPSTR_ESTABLISH_VPN_MANAGER = "android:establish_vpn_manager";
|
||||||
|
field public static final String OPSTR_ESTABLISH_VPN_SERVICE = "android:establish_vpn_service";
|
||||||
field public static final String OPSTR_GET_ACCOUNTS = "android:get_accounts";
|
field public static final String OPSTR_GET_ACCOUNTS = "android:get_accounts";
|
||||||
field public static final String OPSTR_GPS = "android:gps";
|
field public static final String OPSTR_GPS = "android:gps";
|
||||||
field public static final String OPSTR_INSTANT_APP_START_FOREGROUND = "android:instant_app_start_foreground";
|
field public static final String OPSTR_INSTANT_APP_START_FOREGROUND = "android:instant_app_start_foreground";
|
||||||
|
|||||||
@@ -1313,9 +1313,23 @@ public class AppOpsManager {
|
|||||||
public static final int OP_RECORD_INCOMING_PHONE_AUDIO =
|
public static final int OP_RECORD_INCOMING_PHONE_AUDIO =
|
||||||
AppProtoEnums.APP_OP_RECORD_INCOMING_PHONE_AUDIO;
|
AppProtoEnums.APP_OP_RECORD_INCOMING_PHONE_AUDIO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VPN app establishes a connection through the VpnService API.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int OP_ESTABLISH_VPN_SERVICE = AppProtoEnums.APP_OP_ESTABLISH_VPN_SERVICE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VPN app establishes a connection through the VpnManager API.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int OP_ESTABLISH_VPN_MANAGER = AppProtoEnums.APP_OP_ESTABLISH_VPN_MANAGER;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||||
public static final int _NUM_OP = 117;
|
public static final int _NUM_OP = 119;
|
||||||
|
|
||||||
/** Access to coarse location information. */
|
/** Access to coarse location information. */
|
||||||
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
|
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
|
||||||
@@ -1754,6 +1768,22 @@ public class AppOpsManager {
|
|||||||
public static final String OPSTR_RECORD_INCOMING_PHONE_AUDIO =
|
public static final String OPSTR_RECORD_INCOMING_PHONE_AUDIO =
|
||||||
"android:record_incoming_phone_audio";
|
"android:record_incoming_phone_audio";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VPN app establishes a connection through the VpnService API.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi
|
||||||
|
public static final String OPSTR_ESTABLISH_VPN_SERVICE = "android:establish_vpn_service";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VPN app establishes a connection through the VpnManager API.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi
|
||||||
|
public static final String OPSTR_ESTABLISH_VPN_MANAGER = "android:establish_vpn_manager";
|
||||||
|
|
||||||
/** {@link #sAppOpsToNote} not initialized yet for this op */
|
/** {@link #sAppOpsToNote} not initialized yet for this op */
|
||||||
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
|
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
|
||||||
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
|
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
|
||||||
@@ -1970,6 +2000,8 @@ public class AppOpsManager {
|
|||||||
OP_BLUETOOTH_ADVERTISE, // OP_BLUETOOTH_ADVERTISE
|
OP_BLUETOOTH_ADVERTISE, // OP_BLUETOOTH_ADVERTISE
|
||||||
OP_RECORD_INCOMING_PHONE_AUDIO, // OP_RECORD_INCOMING_PHONE_AUDIO
|
OP_RECORD_INCOMING_PHONE_AUDIO, // OP_RECORD_INCOMING_PHONE_AUDIO
|
||||||
OP_NEARBY_WIFI_DEVICES, // OP_NEARBY_WIFI_DEVICES
|
OP_NEARBY_WIFI_DEVICES, // OP_NEARBY_WIFI_DEVICES
|
||||||
|
OP_ESTABLISH_VPN_SERVICE, // OP_ESTABLISH_VPN_SERVICE
|
||||||
|
OP_ESTABLISH_VPN_MANAGER, // OP_ESTABLISH_VPN_MANAGER
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2093,6 +2125,8 @@ public class AppOpsManager {
|
|||||||
OPSTR_BLUETOOTH_ADVERTISE,
|
OPSTR_BLUETOOTH_ADVERTISE,
|
||||||
OPSTR_RECORD_INCOMING_PHONE_AUDIO,
|
OPSTR_RECORD_INCOMING_PHONE_AUDIO,
|
||||||
OPSTR_NEARBY_WIFI_DEVICES,
|
OPSTR_NEARBY_WIFI_DEVICES,
|
||||||
|
OPSTR_ESTABLISH_VPN_SERVICE,
|
||||||
|
OPSTR_ESTABLISH_VPN_MANAGER,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2216,7 +2250,9 @@ public class AppOpsManager {
|
|||||||
"ACTIVITY_RECOGNITION_SOURCE",
|
"ACTIVITY_RECOGNITION_SOURCE",
|
||||||
"BLUETOOTH_ADVERTISE",
|
"BLUETOOTH_ADVERTISE",
|
||||||
"RECORD_INCOMING_PHONE_AUDIO",
|
"RECORD_INCOMING_PHONE_AUDIO",
|
||||||
"NEARBY_WIFI_DEVICES"
|
"NEARBY_WIFI_DEVICES",
|
||||||
|
"ESTABLISH_VPN_SERVICE",
|
||||||
|
"ESTABLISH_VPN_MANAGER",
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2342,6 +2378,8 @@ public class AppOpsManager {
|
|||||||
Manifest.permission.BLUETOOTH_ADVERTISE,
|
Manifest.permission.BLUETOOTH_ADVERTISE,
|
||||||
null, // no permission for OP_RECORD_INCOMING_PHONE_AUDIO,
|
null, // no permission for OP_RECORD_INCOMING_PHONE_AUDIO,
|
||||||
Manifest.permission.NEARBY_WIFI_DEVICES,
|
Manifest.permission.NEARBY_WIFI_DEVICES,
|
||||||
|
null, // no permission for OP_ESTABLISH_VPN_SERVICE
|
||||||
|
null, // no permission for OP_ESTABLISH_VPN_MANAGER
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2467,6 +2505,8 @@ public class AppOpsManager {
|
|||||||
null, // BLUETOOTH_ADVERTISE
|
null, // BLUETOOTH_ADVERTISE
|
||||||
null, // RECORD_INCOMING_PHONE_AUDIO
|
null, // RECORD_INCOMING_PHONE_AUDIO
|
||||||
null, // NEARBY_WIFI_DEVICES
|
null, // NEARBY_WIFI_DEVICES
|
||||||
|
null, // ESTABLISH_VPN_SERVICE
|
||||||
|
null, // ESTABLISH_VPN_MANAGER
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2591,6 +2631,8 @@ public class AppOpsManager {
|
|||||||
null, // BLUETOOTH_ADVERTISE
|
null, // BLUETOOTH_ADVERTISE
|
||||||
null, // RECORD_INCOMING_PHONE_AUDIO
|
null, // RECORD_INCOMING_PHONE_AUDIO
|
||||||
null, // NEARBY_WIFI_DEVICES
|
null, // NEARBY_WIFI_DEVICES
|
||||||
|
null, // ESTABLISH_VPN_SERVICE
|
||||||
|
null, // ESTABLISH_VPN_MANAGER
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2714,6 +2756,8 @@ public class AppOpsManager {
|
|||||||
AppOpsManager.MODE_ALLOWED, // BLUETOOTH_ADVERTISE
|
AppOpsManager.MODE_ALLOWED, // BLUETOOTH_ADVERTISE
|
||||||
AppOpsManager.MODE_ALLOWED, // RECORD_INCOMING_PHONE_AUDIO
|
AppOpsManager.MODE_ALLOWED, // RECORD_INCOMING_PHONE_AUDIO
|
||||||
AppOpsManager.MODE_ALLOWED, // NEARBY_WIFI_DEVICES
|
AppOpsManager.MODE_ALLOWED, // NEARBY_WIFI_DEVICES
|
||||||
|
AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_SERVICE
|
||||||
|
AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_MANAGER
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2841,6 +2885,8 @@ public class AppOpsManager {
|
|||||||
false, // BLUETOOTH_ADVERTISE
|
false, // BLUETOOTH_ADVERTISE
|
||||||
false, // RECORD_INCOMING_PHONE_AUDIO
|
false, // RECORD_INCOMING_PHONE_AUDIO
|
||||||
false, // NEARBY_WIFI_DEVICES
|
false, // NEARBY_WIFI_DEVICES
|
||||||
|
false, // OP_ESTABLISH_VPN_SERVICE
|
||||||
|
false, // OP_ESTABLISH_VPN_MANAGER
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ import com.android.server.net.BaseNetworkObserver;
|
|||||||
import libcore.io.IoUtils;
|
import libcore.io.IoUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileDescriptor;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@@ -195,6 +196,7 @@ public class Vpn {
|
|||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final ConnectivityManager mConnectivityManager;
|
private final ConnectivityManager mConnectivityManager;
|
||||||
|
private final AppOpsManager mAppOpsManager;
|
||||||
// The context is for specific user which is created from mUserId
|
// The context is for specific user which is created from mUserId
|
||||||
private final Context mUserIdContext;
|
private final Context mUserIdContext;
|
||||||
@VisibleForTesting final Dependencies mDeps;
|
@VisibleForTesting final Dependencies mDeps;
|
||||||
@@ -407,6 +409,46 @@ public class Vpn {
|
|||||||
public boolean isInterfacePresent(final Vpn vpn, final String iface) {
|
public boolean isInterfacePresent(final Vpn vpn, final String iface) {
|
||||||
return vpn.jniCheck(iface) != 0;
|
return vpn.jniCheck(iface) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ParcelFileDescriptor#adoptFd(int)
|
||||||
|
*/
|
||||||
|
public ParcelFileDescriptor adoptFd(Vpn vpn, int mtu) {
|
||||||
|
return ParcelFileDescriptor.adoptFd(jniCreate(vpn, mtu));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call native method to create the VPN interface and return the FileDescriptor of /dev/tun.
|
||||||
|
*/
|
||||||
|
public int jniCreate(Vpn vpn, int mtu) {
|
||||||
|
return vpn.jniCreate(mtu);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call native method to get the interface name of VPN.
|
||||||
|
*/
|
||||||
|
public String jniGetName(Vpn vpn, int fd) {
|
||||||
|
return vpn.jniGetName(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call native method to set the VPN addresses and return the number of addresses.
|
||||||
|
*/
|
||||||
|
public int jniSetAddresses(Vpn vpn, String interfaze, String addresses) {
|
||||||
|
return vpn.jniSetAddresses(interfaze, addresses);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see IoUtils#setBlocking(FileDescriptor, boolean)
|
||||||
|
*/
|
||||||
|
public void setBlocking(FileDescriptor fd, boolean blocking) {
|
||||||
|
try {
|
||||||
|
IoUtils.setBlocking(fd, blocking);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Cannot set tunnel's fd as blocking=" + blocking, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd,
|
public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd,
|
||||||
@@ -431,6 +473,7 @@ public class Vpn {
|
|||||||
mVpnProfileStore = vpnProfileStore;
|
mVpnProfileStore = vpnProfileStore;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
|
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
|
||||||
|
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
|
||||||
mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
|
mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
|
||||||
mDeps = deps;
|
mDeps = deps;
|
||||||
mNms = netService;
|
mNms = netService;
|
||||||
@@ -826,7 +869,6 @@ public class Vpn {
|
|||||||
VpnProfile profile = getVpnProfilePrivileged(alwaysOnPackage);
|
VpnProfile profile = getVpnProfilePrivileged(alwaysOnPackage);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
startVpnProfilePrivileged(profile, alwaysOnPackage);
|
startVpnProfilePrivileged(profile, alwaysOnPackage);
|
||||||
|
|
||||||
// If the above startVpnProfilePrivileged() call returns, the Ikev2VpnProfile was
|
// If the above startVpnProfilePrivileged() call returns, the Ikev2VpnProfile was
|
||||||
// correctly parsed, and the VPN has started running in a different thread. The only
|
// correctly parsed, and the VPN has started running in a different thread. The only
|
||||||
// other possibility is that the above call threw an exception, which will be
|
// other possibility is that the above call threw an exception, which will be
|
||||||
@@ -974,9 +1016,15 @@ public class Vpn {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
mAppOpsManager.finishOp(
|
||||||
|
AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage, null);
|
||||||
mContext.unbindService(mConnection);
|
mContext.unbindService(mConnection);
|
||||||
cleanupVpnStateLocked();
|
cleanupVpnStateLocked();
|
||||||
} else if (mVpnRunner != null) {
|
} else if (mVpnRunner != null) {
|
||||||
|
if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
|
||||||
|
mAppOpsManager.finishOp(
|
||||||
|
AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null);
|
||||||
|
}
|
||||||
// cleanupVpnStateLocked() is called from mVpnRunner.exit()
|
// cleanupVpnStateLocked() is called from mVpnRunner.exit()
|
||||||
mVpnRunner.exit();
|
mVpnRunner.exit();
|
||||||
}
|
}
|
||||||
@@ -1041,10 +1089,8 @@ public class Vpn {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final AppOpsManager appOpMgr =
|
|
||||||
(AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
|
|
||||||
for (final String appOpStr : toChange) {
|
for (final String appOpStr : toChange) {
|
||||||
appOpMgr.setMode(
|
mAppOpsManager.setMode(
|
||||||
appOpStr,
|
appOpStr,
|
||||||
uid,
|
uid,
|
||||||
packageName,
|
packageName,
|
||||||
@@ -1366,9 +1412,9 @@ public class Vpn {
|
|||||||
Set<Range<Integer>> oldUsers = mNetworkCapabilities.getUids();
|
Set<Range<Integer>> oldUsers = mNetworkCapabilities.getUids();
|
||||||
|
|
||||||
// Configure the interface. Abort if any of these steps fails.
|
// Configure the interface. Abort if any of these steps fails.
|
||||||
ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
|
final ParcelFileDescriptor tun = mDeps.adoptFd(this, config.mtu);
|
||||||
try {
|
try {
|
||||||
String interfaze = jniGetName(tun.getFd());
|
final String interfaze = mDeps.jniGetName(this, tun.getFd());
|
||||||
|
|
||||||
// TEMP use the old jni calls until there is support for netd address setting
|
// TEMP use the old jni calls until there is support for netd address setting
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
@@ -1376,7 +1422,7 @@ public class Vpn {
|
|||||||
builder.append(" ");
|
builder.append(" ");
|
||||||
builder.append(address);
|
builder.append(address);
|
||||||
}
|
}
|
||||||
if (jniSetAddresses(interfaze, builder.toString()) < 1) {
|
if (mDeps.jniSetAddresses(this, interfaze, builder.toString()) < 1) {
|
||||||
throw new IllegalArgumentException("At least one address must be specified");
|
throw new IllegalArgumentException("At least one address must be specified");
|
||||||
}
|
}
|
||||||
Connection connection = new Connection();
|
Connection connection = new Connection();
|
||||||
@@ -1422,11 +1468,11 @@ public class Vpn {
|
|||||||
jniReset(oldInterface);
|
jniReset(oldInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
mDeps.setBlocking(tun.getFileDescriptor(), config.blocking);
|
||||||
IoUtils.setBlocking(tun.getFileDescriptor(), config.blocking);
|
// Record that the VPN connection is established by an app which uses VpnService API.
|
||||||
} catch (IOException e) {
|
if (oldNetworkAgent != mNetworkAgent) {
|
||||||
throw new IllegalStateException(
|
mAppOpsManager.startOp(
|
||||||
"Cannot set tunnel's fd as blocking=" + config.blocking, e);
|
AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage, null, null);
|
||||||
}
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
IoUtils.closeQuietly(tun);
|
IoUtils.closeQuietly(tun);
|
||||||
@@ -1781,9 +1827,17 @@ public class Vpn {
|
|||||||
synchronized (Vpn.this) {
|
synchronized (Vpn.this) {
|
||||||
if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
|
if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
|
||||||
if (mConnection != null) {
|
if (mConnection != null) {
|
||||||
|
mAppOpsManager.finishOp(
|
||||||
|
AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage,
|
||||||
|
null);
|
||||||
mContext.unbindService(mConnection);
|
mContext.unbindService(mConnection);
|
||||||
cleanupVpnStateLocked();
|
cleanupVpnStateLocked();
|
||||||
} else if (mVpnRunner != null) {
|
} else if (mVpnRunner != null) {
|
||||||
|
if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
|
||||||
|
mAppOpsManager.finishOp(
|
||||||
|
AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage,
|
||||||
|
null);
|
||||||
|
}
|
||||||
// cleanupVpnStateLocked() is called from mVpnRunner.exit()
|
// cleanupVpnStateLocked() is called from mVpnRunner.exit()
|
||||||
mVpnRunner.exit();
|
mVpnRunner.exit();
|
||||||
}
|
}
|
||||||
@@ -3254,8 +3308,7 @@ public class Vpn {
|
|||||||
*
|
*
|
||||||
* @param packageName the package name of the app provisioning this profile
|
* @param packageName the package name of the app provisioning this profile
|
||||||
*/
|
*/
|
||||||
public synchronized void startVpnProfile(
|
public synchronized void startVpnProfile(@NonNull String packageName) {
|
||||||
@NonNull String packageName) {
|
|
||||||
requireNonNull(packageName, "No package name provided");
|
requireNonNull(packageName, "No package name provided");
|
||||||
|
|
||||||
enforceNotRestrictedUser();
|
enforceNotRestrictedUser();
|
||||||
@@ -3318,6 +3371,13 @@ public class Vpn {
|
|||||||
Log.d(TAG, "Unknown VPN profile type: " + profile.type);
|
Log.d(TAG, "Unknown VPN profile type: " + profile.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Record that the VPN connection is established by an app which uses VpnManager API.
|
||||||
|
if (!VpnConfig.LEGACY_VPN.equals(packageName)) {
|
||||||
|
mAppOpsManager.startOp(
|
||||||
|
AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null,
|
||||||
|
null);
|
||||||
|
}
|
||||||
} catch (GeneralSecurityException e) {
|
} catch (GeneralSecurityException e) {
|
||||||
// Reset mConfig
|
// Reset mConfig
|
||||||
mConfig = null;
|
mConfig = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user