Reload ModulesFragment after user removed or added (#1465)

Co-authored-by: LoveSy <shana@zju.edu.cn>
This commit is contained in:
Howard Wu 2021-12-04 21:44:40 +08:00 committed by GitHub
parent 61c447091f
commit 6a735d2064
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 185 additions and 75 deletions

View File

@ -20,6 +20,7 @@
package org.lsposed.manager;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -116,6 +117,10 @@ public class App extends Application {
}
public static final String TAG = "LSPosedManager";
private static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED";
private static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED";
private static final String ACTION_USER_INFO_CHANGED = "android.intent.action.USER_INFO_CHANGED";
private static final String EXTRA_REMOVED_FOR_ALL_USERS = "android.intent.extra.REMOVED_FOR_ALL_USERS";
private static App instance = null;
private static OkHttpClient okHttpClient;
private static Cache okHttpCache;
@ -138,6 +143,7 @@ public class App extends Application {
return !Process.isApplicationUid(Process.myUid());
}
@SuppressLint("WrongConstant")
private void setCrashReport() {
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
@ -182,17 +188,39 @@ public class App extends Application {
DayNightDelegate.setDefaultNightMode(ThemeUtil.getDarkTheme());
LocaleDelegate.setDefaultLocale(getLocale());
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("org.lsposed.manager.NOTIFICATION");
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int userId = intent.getIntExtra(Intent.EXTRA_USER, 0);
String packageName = intent.getStringExtra("android.intent.extra.PACKAGES");
boolean packageFullyRemoved = intent.getBooleanExtra(Intent.ACTION_PACKAGE_FULLY_REMOVED, false);
public void onReceive(Context context, Intent inIntent) {
var intent = (Intent) inIntent.getParcelableExtra(Intent.EXTRA_INTENT);
Log.d(TAG, "onReceive: " + intent);
switch (intent.getAction()) {
case Intent.ACTION_PACKAGE_ADDED:
case Intent.ACTION_PACKAGE_CHANGED:
case Intent.ACTION_PACKAGE_FULLY_REMOVED:
case Intent.ACTION_UID_REMOVED: {
var userId = intent.getIntExtra(Intent.EXTRA_USER, 0);
var packageName = intent.getStringExtra("android.intent.extra.PACKAGES");
var packageRemovedForAllUsers = intent.getBooleanExtra(EXTRA_REMOVED_FOR_ALL_USERS, false);
var isXposedModule = intent.getBooleanExtra("isXposedModule", false);
if (packageName != null) {
ModuleUtil.getInstance().reloadSingleModule(packageName, userId, packageFullyRemoved);
if (isXposedModule)
ModuleUtil.getInstance().reloadSingleModule(packageName, userId, packageRemovedForAllUsers);
else
App.getExecutorService().submit(() -> AppHelper.getAppList(true));
}
break;
}
case ACTION_USER_ADDED:
case ACTION_USER_REMOVED:
case ACTION_USER_INFO_CHANGED: {
App.getExecutorService().submit(() -> ModuleUtil.getInstance().reloadInstalledModules());
break;
}
}
}, new IntentFilter(Intent.ACTION_PACKAGE_CHANGED));
}
}, intentFilter);
UpdateUtil.loadRemoteVersion();

View File

@ -20,6 +20,7 @@
package org.lsposed.manager.adapters;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
@ -44,6 +45,7 @@ public class AppHelper {
private static List<PackageInfo> appList;
private static final ConcurrentHashMap<PackageInfo, CharSequence> appLabel = new ConcurrentHashMap<>();
@SuppressLint("WrongConstant")
public static Intent getSettingsIntent(String packageName, int userId) {
Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
intentToResolve.addCategory(SETTINGS_CATEGORY);
@ -63,6 +65,7 @@ public class AppHelper {
return intent;
}
@SuppressLint("WrongConstant")
public static Intent getLaunchIntentForPackage(String packageName, int userId) {
Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
intentToResolve.addCategory(Intent.CATEGORY_INFO);

View File

@ -266,6 +266,7 @@ public class ScopeAdapter extends EmptyStateRecyclerView.EmptyStateAdapter<Scope
return true;
}
@SuppressLint("WrongConstant")
public boolean onContextItemSelected(@NonNull MenuItem item) {
ApplicationInfo info = selectedInfo;
if (info == null) {

View File

@ -20,7 +20,6 @@
package org.lsposed.manager.ui.fragment;
import static android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS;
import static androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY;
import android.annotation.SuppressLint;
import android.content.Intent;
@ -37,6 +36,7 @@ import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@ -72,9 +72,9 @@ import org.lsposed.manager.App;
import org.lsposed.manager.ConfigManager;
import org.lsposed.manager.R;
import org.lsposed.manager.adapters.AppHelper;
import org.lsposed.manager.databinding.SwiperefreshRecyclerviewBinding;
import org.lsposed.manager.databinding.FragmentPagerBinding;
import org.lsposed.manager.databinding.ItemModuleBinding;
import org.lsposed.manager.databinding.SwiperefreshRecyclerviewBinding;
import org.lsposed.manager.repo.RepoLoader;
import org.lsposed.manager.ui.dialog.BlurBehindDialogBuilder;
import org.lsposed.manager.ui.widget.EmptyStateRecyclerView;
@ -95,12 +95,12 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
private static final PackageManager pm = App.getInstance().getPackageManager();
private static final ModuleUtil moduleUtil = ModuleUtil.getInstance();
private static final RepoLoader repoLoader = RepoLoader.getInstance();
private static final List<UserInfo> users = ConfigManager.getUsers();
protected FragmentPagerBinding binding;
protected SearchView searchView;
private SearchView.OnQueryTextListener searchListener;
final ArrayList<ModuleAdapter> adapters = new ArrayList<>();
SparseArray<ModuleAdapter> adapters = new SparseArray<>();
PagerAdapter pagerAdapter = null;
private ModuleUtil.InstalledModule selectedModule;
@ -110,24 +110,22 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
searchListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
adapters.forEach(adapter -> adapter.getFilter().filter(query));
forEachAdaptor(adapter -> adapter.getFilter().filter(query));
return false;
}
@Override
public boolean onQueryTextChange(String query) {
adapters.forEach(adapter -> adapter.getFilter().filter(query));
forEachAdaptor(adapter -> adapter.getFilter().filter(query));
return false;
}
};
if (users != null) {
for (var user : users) {
var adapter = new ModuleAdapter(user);
adapter.setHasStableIds(true);
adapter.setStateRestorationPolicy(PREVENT_WHEN_EMPTY);
adapters.add(adapter);
}
private void forEachAdaptor(Consumer<? super ModuleAdapter> action) {
var snapshot = adapters;
for (var i = 0; i < snapshot.size(); ++i) {
action.accept(snapshot.valueAt(i));
}
}
@ -149,7 +147,8 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
binding = FragmentPagerBinding.inflate(inflater, container, false);
binding.appBar.setLiftable(true);
setupToolbar(binding.toolbar, binding.clickView, R.string.Modules, R.menu.menu_modules);
binding.viewPager.setAdapter(new PagerAdapter(this));
pagerAdapter = new PagerAdapter(this);
binding.viewPager.setAdapter(pagerAdapter);
binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
@ -159,13 +158,10 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
new TabLayoutMediator(binding.tabLayout, binding.viewPager, (tab, position) -> {
if (position < adapters.size()) {
tab.setText(adapters.get(position).getUser().name);
tab.setText(adapters.valueAt(position).getUser().name);
}
}).attach();
if (users != null && users.size() != 1) {
binding.viewPager.setUserInputEnabled(true);
binding.tabLayout.setVisibility(View.VISIBLE);
binding.tabLayout.addOnLayoutChangeListener((view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
ViewGroup vg = (ViewGroup) binding.tabLayout.getChildAt(0);
int tabLayoutWidth = IntStream.range(0, binding.tabLayout.getTabCount()).map(i -> vg.getChildAt(i).getWidth()).sum();
@ -174,14 +170,10 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
binding.tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
}
});
binding.fab.show();
} else {
binding.viewPager.setUserInputEnabled(false);
binding.tabLayout.setVisibility(View.GONE);
}
binding.fab.setOnClickListener(v -> {
var bundle = new Bundle();
var user = adapters.get(binding.viewPager.getCurrentItem()).getUser();
var user = adapters.valueAt(binding.viewPager.getCurrentItem()).getUser();
bundle.putParcelable("userInfo", user);
var f = new RecyclerViewDialogFragment();
f.setArguments(bundle);
@ -190,7 +182,7 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
moduleUtil.addListener(this);
repoLoader.addListener(this);
updateModuleSummary();
onModulesReloaded();
return binding.getRoot();
}
@ -214,23 +206,48 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
@Override
public void onResume() {
super.onResume();
adapters.forEach(ModuleAdapter::refresh);
forEachAdaptor(ModuleAdapter::refresh);
}
@Override
public void onSingleModuleReloaded(ModuleUtil.InstalledModule module) {
adapters.forEach(ModuleAdapter::refresh);
forEachAdaptor(ModuleAdapter::refresh);
}
@Override
public void onModulesReloaded() {
adapters.forEach(ModuleAdapter::refresh);
var users = moduleUtil.getUsers();
if (users == null) return;
if (users.size() != 1) {
binding.viewPager.setUserInputEnabled(true);
binding.tabLayout.setVisibility(View.VISIBLE);
binding.fab.show();
} else {
binding.viewPager.setUserInputEnabled(false);
binding.tabLayout.setVisibility(View.GONE);
}
var tmp = new SparseArray<ModuleAdapter>(users.size());
var snapshot = adapters;
for (var user : users) {
if (snapshot.indexOfKey(user.id) >= 0) {
tmp.put(user.id, snapshot.get(user.id));
} else {
var adapter = new ModuleAdapter(user);
adapter.setHasStableIds(true);
tmp.put(user.id, adapter);
}
}
adapters = tmp;
forEachAdaptor(ModuleAdapter::refresh);
runOnUiThread(pagerAdapter::notifyDataSetChanged);
updateModuleSummary();
}
@Override
public void onRepoLoaded() {
adapters.forEach(ModuleAdapter::refresh);
forEachAdaptor(ModuleAdapter::refresh);
}
private void updateModuleSummary() {
@ -261,6 +278,7 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
.show();
}
@SuppressLint("WrongConstant")
@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {
if (selectedModule == null) {
@ -348,9 +366,9 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
if (fragment == null || arguments == null) {
return null;
}
int position = arguments.getInt("position");
int userId = arguments.getInt("user_id");
binding = SwiperefreshRecyclerviewBinding.inflate(getLayoutInflater(), container, false);
adapter = fragment.adapters.get(position);
adapter = fragment.adapters.get(userId);
binding.recyclerView.setAdapter(adapter);
binding.recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
binding.swipeRefreshLayout.setOnRefreshListener(adapter::fullRefresh);
@ -430,7 +448,7 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
@Override
public Fragment createFragment(int position) {
Bundle bundle = new Bundle();
bundle.putInt("position", position);
bundle.putInt("user_id", adapters.keyAt(position));
Fragment fragment = new ModuleListFragment();
fragment.setArguments(bundle);
return fragment;
@ -443,7 +461,12 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
@Override
public long getItemId(int position) {
return position;
return adapters.keyAt(position);
}
@Override
public boolean containsItem(long itemId) {
return adapters.indexOfKey((int) itemId) >= 0;
}
}

View File

@ -30,11 +30,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.util.Pair;
import org.lsposed.lspd.models.UserInfo;
import org.lsposed.manager.App;
import org.lsposed.manager.ConfigManager;
import org.lsposed.manager.repo.RepoLoader;
import org.lsposed.manager.repo.model.OnlineModule;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@ -50,6 +52,7 @@ public final class ModuleUtil {
private final PackageManager pm;
private final Set<ModuleListener> listeners = ConcurrentHashMap.newKeySet();
private HashSet<String> enabledModules = new HashSet<>();
private List<UserInfo> users = new ArrayList<>();
private Map<Pair<String, Integer>, InstalledModule> installedModules = new HashMap<>();
private boolean modulesLoaded = false;
@ -89,6 +92,7 @@ public final class ModuleUtil {
}
Map<Pair<String, Integer>, InstalledModule> modules = new HashMap<>();
var users = ConfigManager.getUsers();
for (PackageInfo pkg : ConfigManager.getInstalledPackagesFromAllUsers(PackageManager.GET_META_DATA, false)) {
ApplicationInfo app = pkg.applicationInfo;
@ -100,11 +104,18 @@ public final class ModuleUtil {
installedModules = modules;
this.users = users;
enabledModules = new HashSet<>(Arrays.asList(ConfigManager.getEnabledModules()));
modulesLoaded = true;
listeners.forEach(ModuleListener::onModulesReloaded);
}
@Nullable
public List<UserInfo> getUsers() {
return modulesLoaded ? users : null;
}
public InstalledModule reloadSingleModule(String packageName, int userId) {
return reloadSingleModule(packageName, userId, false);
}

View File

@ -21,6 +21,7 @@ package org.lsposed.lspd.service;
import static org.lsposed.lspd.service.ServiceManager.TAG;
import android.annotation.SuppressLint;
import android.app.IActivityManager;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
@ -101,17 +102,16 @@ public class ActivityManagerService {
return am.startUserInBackground(userId);
}
@SuppressLint("NewApi")
public static Intent registerReceiver(String callerPackage,
String callingFeatureId, IIntentReceiver receiver, IntentFilter filter,
String requiredPermission, int userId, int flags) throws RemoteException {
IActivityManager am = getActivityManager();
if (am == null || thread == null) return null;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S || (Build.VERSION.SDK_INT == Build.VERSION_CODES.R && Build.VERSION.PREVIEW_SDK_INT != 0))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && Build.VERSION.PREVIEW_SDK_INT != 0))
return am.registerReceiverWithFeature(thread, callerPackage, callingFeatureId, "null", receiver, filter, requiredPermission, userId, flags);
} catch (Throwable ignored) {
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return am.registerReceiverWithFeature(thread, callerPackage, callingFeatureId, receiver, filter, requiredPermission, userId, flags);
} else {
return am.registerReceiver(thread, callerPackage, receiver, filter, requiredPermission, userId, flags);

View File

@ -252,13 +252,11 @@ public class LSPManagerService extends ILSPManagerService.Stub {
}
@SuppressLint("WrongConstant")
public static void broadcastIntent(String modulePackageName, int moduleUserId, boolean packageFullyRemoved) {
Intent intent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
public static void broadcastIntent(Intent inIntent) {
var intent = new Intent("org.lsposed.manager.NOTIFICATION");
intent.putExtra(Intent.EXTRA_INTENT, inIntent);
intent.addFlags(0x01000000); //Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
intent.addFlags(0x00400000); //Intent.FLAG_RECEIVER_FROM_SHELL
intent.putExtra("android.intent.extra.PACKAGES", modulePackageName);
intent.putExtra(Intent.EXTRA_USER, moduleUserId);
intent.putExtra(Intent.ACTION_PACKAGE_FULLY_REMOVED, packageFullyRemoved);
intent.setPackage(BuildConfig.MANAGER_INJECTED_PKG_NAME);
try {
ActivityManagerService.broadcastIntentWithFeature(null, intent,

View File

@ -42,6 +42,10 @@ import java.util.Arrays;
public class LSPosedService extends ILSPosedService.Stub {
private static final int AID_NOBODY = 9999;
private static final int USER_NULL = -10000;
private static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED";
public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED";
private static final String EXTRA_USER_HANDLE = "android.intent.extra.user_handle";
private static final String EXTRA_REMOVED_FOR_ALL_USERS = "android.intent.extra.REMOVED_FOR_ALL_USERS";
@Override
public ILSPApplicationService requestApplicationService(int uid, int pid, String processName, IBinder heartBeat) {
@ -79,7 +83,7 @@ public class LSPosedService extends ILSPosedService.Stub {
if (uid == AID_NOBODY || uid <= 0) return;
int userId = intent.getIntExtra("android.intent.extra.user_handle", USER_NULL);
var intentAction = intent.getAction();
var allUsers = intent.getBooleanExtra("android.intent.extra.REMOVED_FOR_ALL_USERS", false);
var allUsers = intent.getBooleanExtra(EXTRA_REMOVED_FOR_ALL_USERS, false);
if (userId == USER_NULL) userId = uid % PER_USER_RANGE;
Uri uri = intent.getData();
String moduleName = (uri != null) ? uri.getSchemeSpecificPart() : ConfigManager.getInstance().getModule(uid);
@ -102,8 +106,8 @@ public class LSPosedService extends ILSPosedService.Stub {
// because we only care about when the apk is gone
if (moduleName != null && allUsers)
if (ConfigManager.getInstance().removeModule(moduleName)) {
broadcastOrShowNotification(moduleName, userId, intent);
isXposedModule = true;
broadcastAndShowNotification(moduleName, userId, intent, true);
}
break;
}
@ -115,8 +119,8 @@ public class LSPosedService extends ILSPosedService.Stub {
if (components != null && !Arrays.stream(components).reduce(false, (p, c) -> p || c.equals(moduleName), Boolean::logicalOr)) {
return;
}
broadcastAndShowNotification(moduleName, userId, intent, isXposedModule);
if (isXposedModule) {
broadcastOrShowNotification(moduleName, userId, intent);
// When installing a new Xposed module, we update the apk path to mark it as a
// module to send a broadcast when modules that have not been activated are
// uninstalled.
@ -132,8 +136,8 @@ public class LSPosedService extends ILSPosedService.Stub {
case Intent.ACTION_UID_REMOVED: {
// when a package is removed (rather than hide) for a single user
// (apk may still be there because of multi-user)
broadcastAndShowNotification(moduleName, userId, intent, isXposedModule);
if (isXposedModule) {
broadcastOrShowNotification(moduleName, userId, intent);
// it will automatically remove obsolete scope from database
ConfigManager.getInstance().updateCache();
} else if (ConfigManager.getInstance().isUidHooked(uid)) {
@ -159,18 +163,34 @@ public class LSPosedService extends ILSPosedService.Stub {
}
}
private void broadcastOrShowNotification(String moduleName, int userId, Intent intent) {
Log.d(TAG, "module " + moduleName + " changed, dispatching to manager");
var internAction = intent.getAction();
var allUsers = intent.getBooleanExtra("android.intent.extra.REMOVED_FOR_ALL_USERS", false);
LSPManagerService.broadcastIntent(moduleName, userId, allUsers);
private void broadcastAndShowNotification(String packageName, int userId, Intent intent, boolean isXposedModule) {
Log.d(TAG, "package " + packageName + " changed, dispatching to manager");
var action = intent.getAction();
var allUsers = intent.getBooleanExtra(EXTRA_REMOVED_FOR_ALL_USERS, false);
intent.putExtra("android.intent.extra.PACKAGES", packageName);
intent.putExtra(Intent.EXTRA_USER, userId);
intent.putExtra("isXposedModule", isXposedModule);
LSPManagerService.broadcastIntent(intent);
if (isXposedModule) {
var enabledModules = ConfigManager.getInstance().enabledModules();
var scope = ConfigManager.getInstance().getModuleScope(moduleName);
var scope = ConfigManager.getInstance().getModuleScope(packageName);
boolean systemModule = scope != null &&
scope.parallelStream().anyMatch(app -> app.packageName.equals("android"));
boolean enabled = Arrays.asList(enabledModules).contains(moduleName);
if (!(Intent.ACTION_UID_REMOVED.equals(internAction) || Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(internAction) || allUsers))
LSPManagerService.showNotification(moduleName, userId, enabled, systemModule);
boolean enabled = Arrays.asList(enabledModules).contains(packageName);
if (!(Intent.ACTION_UID_REMOVED.equals(action) || Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action) || allUsers))
LSPManagerService.showNotification(packageName, userId, enabled, systemModule);
}
}
synchronized public void dispatchUserChanged(Intent intent) {
if (intent == null) return;
int uid = intent.getIntExtra(EXTRA_USER_HANDLE, AID_NOBODY);
if (uid == AID_NOBODY || uid <= 0) return;
try {
LSPManagerService.broadcastIntent(intent);
} catch (Throwable e) {
Log.e(TAG, "dispatch user info changed", e);
}
}
synchronized public void dispatchUserUnlocked(Intent intent) {
@ -335,6 +355,31 @@ public class LSPosedService extends ILSPosedService.Stub {
Log.d(TAG, "registered boot receiver");
}
private void registerUserChangeReceiver() {
try {
IntentFilter userFilter = new IntentFilter();
userFilter.addAction(ACTION_USER_ADDED);
userFilter.addAction(ACTION_USER_REMOVED);
var receiver = new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
getExecutorService().submit(() -> dispatchUserChanged(intent));
try {
ActivityManagerService.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (Throwable e) {
Log.e(TAG, "finish receiver", e);
}
}
};
ActivityManagerService.registerReceiver("android", null, receiver, userFilter, null, -1, 0);
} catch (Throwable e) {
Log.e(TAG, "register user info change receiver", e);
}
Log.d(TAG, "registered user info change receiver");
}
@Override
public void dispatchSystemServerContext(IBinder activityThread, IBinder activityToken, String api) {
Log.d(TAG, "received system context");
@ -345,6 +390,7 @@ public class LSPosedService extends ILSPosedService.Stub {
registerConfigurationReceiver();
registerSecretCodeReceiver();
registerBootCompleteReceiver();
registerUserChangeReceiver();
}
@Override