Skip to content

Commit

Permalink
require device restart to disable eUICC LPA
Browse files Browse the repository at this point in the history
OS code expects LPA to remain present once it had been detected.

If LPA is disabled without rebooting the device, OS code in some cases tries to connect to it in an
infinite loop.
  • Loading branch information
muhomorr authored and thestinger committed Jul 5, 2023
1 parent 26ac8b8 commit 6369183
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 15 deletions.
2 changes: 2 additions & 0 deletions res/values/strings_ext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

<string name="privileged_euicc_management_title">Enable privileged eSIM management</string>
<string name="privileged_euicc_management_summary">Requires sandboxed Google Play installation</string>
<string name="privileged_euicc_management_restart_to_disable_dialog">Device restart is required to disable this setting.</string>
<string name="privileged_euicc_management_restart_button">Restart</string>

<string name="remote_provisioning_title">Attestation key provisioning</string>
<string name="remote_provisioning_enabled_grapheneos_proxy">Enabled (GrapheneOS proxy)</string>
Expand Down
43 changes: 28 additions & 15 deletions src/com/android/settings/network/GoogleEuiccLpaController.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.android.settings.network;

import android.Manifest;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.PatternMatcher;
import android.os.PowerManager;
import android.os.Process;
import android.os.UserHandle;
import android.permission.PermissionManager;
Expand All @@ -15,12 +17,11 @@
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.TwoStatePreference;

import com.android.internal.util.GoogleEuicc;
import com.android.settings.R;
import com.android.settings.ext.AbstractTogglePrefController;

import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;

public class GoogleEuiccLpaController extends AbstractTogglePrefController implements DefaultLifecycleObserver {
Expand Down Expand Up @@ -70,27 +71,39 @@ public void updateState(Preference preference) {

@Override
public boolean setChecked(boolean isChecked) {
int state = isChecked && GoogleEuicc.checkLpaDependencies() ?
COMPONENT_ENABLED_STATE_ENABLED :
COMPONENT_ENABLED_STATE_DISABLED;
if (!isChecked) {
var b = new AlertDialog.Builder(mContext);
b.setMessage(R.string.privileged_euicc_management_restart_to_disable_dialog);
b.setPositiveButton(R.string.privileged_euicc_management_restart_button, (dialogInterface, btn) -> {
var pm = mContext.getSystemService(PowerManager.class);
pm.reboot(null);
});
b.show();
return false;
}

if (!GoogleEuicc.checkLpaDependencies()) {
// this is a race condition, toggle hasn't been grayed out yet
return false;
}

PermissionManager permissionManager = mContext.getSystemService(PermissionManager.class);

try {
String pkg = GoogleEuicc.LPA_PKG_NAME;

UserHandle user = mContext.getUser();
String perm = Manifest.permission.CAMERA;
permissionManager.revokeRuntimePermission(pkg, perm, user, null);
// Previously, Camera permission was auto-granted with the FLAG_PERMISSION_SYSTEM_FIXED,
// which made it unchangeable by the user.
// Removing FLAG_PERMISSION_USER_FIXED is needed to make sure that the app is always
// able to show a permission request dialog after being enabled
String pkg = GoogleEuicc.LPA_PKG_NAME;
if (state == COMPONENT_ENABLED_STATE_ENABLED) {
UserHandle user = mContext.getUser();
String perm = Manifest.permission.CAMERA;
permissionManager.revokeRuntimePermission(pkg, perm, user, null);
int permFlagsToRemove = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
| PackageManager.FLAG_PERMISSION_USER_FIXED;
permissionManager.updatePermissionFlags(pkg, perm, permFlagsToRemove, 0, user);
}
packageManager.setApplicationEnabledSetting(pkg, state, 0);
int permFlagsToRemove = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
| PackageManager.FLAG_PERMISSION_USER_FIXED;
permissionManager.updatePermissionFlags(pkg, perm, permFlagsToRemove, 0, user);

packageManager.setApplicationEnabledSetting(pkg, COMPONENT_ENABLED_STATE_ENABLED, 0);

return true;
} catch (Exception e) {
Expand Down

0 comments on commit 6369183

Please sign in to comment.