[core] Listen to configuration change (#1174)
This commit is contained in:
parent
4e0b825cab
commit
0524ebc2f2
|
|
@ -30,6 +30,7 @@ import android.content.IIntentReceiver;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
|
@ -164,6 +165,12 @@ public class ActivityManagerService {
|
||||||
return am.getCurrentUser();
|
return am.getCurrentUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Configuration getConfiguration() throws RemoteException {
|
||||||
|
IActivityManager am = getActivityManager();
|
||||||
|
if (am == null) return null;
|
||||||
|
return am.getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
public static IContentProvider getContentProvider(String auth, int userId) throws RemoteException {
|
public static IContentProvider getContentProvider(String auth, int userId) throws RemoteException {
|
||||||
IActivityManager am = getActivityManager();
|
IActivityManager am = getActivityManager();
|
||||||
if (am == null) return null;
|
if (am == null) return null;
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ public class ConfigFileManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Resources getResources() {
|
public static Resources getResources() {
|
||||||
loadLocale();
|
loadRes();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +116,7 @@ public class ConfigFileManager {
|
||||||
return productLanguage + "-" + productRegion;
|
return productLanguage + "-" + productRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadLocale() {
|
private static void loadRes() {
|
||||||
if (res != null) return;
|
if (res != null) return;
|
||||||
try {
|
try {
|
||||||
am = AssetManager.class.newInstance();
|
am = AssetManager.class.newInstance();
|
||||||
|
|
@ -132,14 +132,16 @@ public class ConfigFileManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reloadLocale() {
|
static void reloadConfiguration() {
|
||||||
loadLocale();
|
loadRes();
|
||||||
Locale locale = Locale.forLanguageTag(readLocale());
|
try {
|
||||||
Locale.setDefault(locale);
|
var conf = ActivityManagerService.getConfiguration();
|
||||||
var conf = res.getConfiguration();
|
if (conf != null)
|
||||||
conf.setLocale(Locale.forLanguageTag(readLocale()));
|
//noinspection deprecation
|
||||||
//noinspection deprecation
|
res.updateConfiguration(conf, res.getDisplayMetrics());
|
||||||
res.updateConfiguration(conf, res.getDisplayMetrics());
|
} catch (Throwable e) {
|
||||||
|
Log.e(TAG, "reload configuration", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParcelFileDescriptor getManagerApk() throws IOException {
|
static ParcelFileDescriptor getManagerApk() throws IOException {
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,6 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
||||||
public static final String CHANNEL_NAME = "LSPosed Manager";
|
public static final String CHANNEL_NAME = "LSPosed Manager";
|
||||||
public static final int CHANNEL_IMP = NotificationManager.IMPORTANCE_HIGH;
|
public static final int CHANNEL_IMP = NotificationManager.IMPORTANCE_HIGH;
|
||||||
|
|
||||||
private static Icon managerIcon = null;
|
|
||||||
private static Icon notificationIcon = null;
|
|
||||||
private static Intent managerIntent = null;
|
private static Intent managerIntent = null;
|
||||||
|
|
||||||
public class ManagerGuard implements IBinder.DeathRecipient {
|
public class ManagerGuard implements IBinder.DeathRecipient {
|
||||||
|
|
@ -153,21 +151,15 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Icon getManagerIcon() {
|
private static Icon getManagerIcon() {
|
||||||
if (managerIcon == null) {
|
try {
|
||||||
try {
|
return getIcon(org.lsposed.manager.R.mipmap.ic_launcher);
|
||||||
managerIcon = getIcon(org.lsposed.manager.R.mipmap.ic_launcher);
|
} catch (Throwable e) {
|
||||||
} catch (Throwable e) {
|
return getIcon(org.lsposed.manager.R.drawable.ic_launcher);
|
||||||
managerIcon = getIcon(org.lsposed.manager.R.drawable.ic_launcher);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return managerIcon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Icon getNotificationIcon() {
|
private static Icon getNotificationIcon() {
|
||||||
if (notificationIcon == null) {
|
return getIcon(org.lsposed.manager.R.drawable.ic_extension);
|
||||||
notificationIcon = getIcon(org.lsposed.manager.R.drawable.ic_extension);
|
|
||||||
}
|
|
||||||
return notificationIcon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Intent getManagerIntent() {
|
private static Intent getManagerIntent() {
|
||||||
|
|
@ -251,6 +243,10 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
||||||
|
|
||||||
public static void createOrUpdateShortcut() {
|
public static void createOrUpdateShortcut() {
|
||||||
try {
|
try {
|
||||||
|
while (!UserService.isUserUnlocked(0)) {
|
||||||
|
Log.d(TAG, "user is not yet unlocked, waiting for 1s...");
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}
|
||||||
var smCtor = ShortcutManager.class.getDeclaredConstructor(Context.class);
|
var smCtor = ShortcutManager.class.getDeclaredConstructor(Context.class);
|
||||||
smCtor.setAccessible(true);
|
smCtor.setAccessible(true);
|
||||||
var context = new FakeContext("com.android.settings");
|
var context = new FakeContext("com.android.settings");
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import android.net.Uri;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
@ -159,16 +160,21 @@ public class LSPosedService extends ILSPosedService.Stub {
|
||||||
|
|
||||||
synchronized public void dispatchUserUnlocked(Intent intent) {
|
synchronized public void dispatchUserUnlocked(Intent intent) {
|
||||||
try {
|
try {
|
||||||
while (!UserService.isUserUnlocked(0)) {
|
|
||||||
Log.d(TAG, "user is not yet unlocked, waiting for 1s...");
|
|
||||||
Thread.sleep(1000);
|
|
||||||
}
|
|
||||||
LSPManagerService.createOrUpdateShortcut();
|
LSPManagerService.createOrUpdateShortcut();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Log.e(TAG, "dispatch user unlocked", e);
|
Log.e(TAG, "dispatch user unlocked", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized public void dispatchConfigurationChanged(Intent intent) {
|
||||||
|
try {
|
||||||
|
ConfigFileManager.reloadConfiguration();
|
||||||
|
LSPManagerService.createOrUpdateShortcut();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Log.e(TAG, "dispatch configuration changed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void registerPackageReceiver() {
|
private void registerPackageReceiver() {
|
||||||
try {
|
try {
|
||||||
IntentFilter packageFilter = new IntentFilter();
|
IntentFilter packageFilter = new IntentFilter();
|
||||||
|
|
@ -222,12 +228,35 @@ public class LSPosedService extends ILSPosedService.Stub {
|
||||||
Log.d(TAG, "registered unlock receiver");
|
Log.d(TAG, "registered unlock receiver");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerConfigurationReceiver() {
|
||||||
|
try {
|
||||||
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
|
||||||
|
|
||||||
|
ActivityManagerService.registerReceiver("android", null, new IIntentReceiver.Stub() {
|
||||||
|
@Override
|
||||||
|
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
|
||||||
|
new Thread(() -> dispatchConfigurationChanged(intent)).start();
|
||||||
|
try {
|
||||||
|
ActivityManagerService.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Log.e(TAG, "finish receiver", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, intentFilter, null, 0, 0);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Log.e(TAG, "register configuration receiver", e);
|
||||||
|
}
|
||||||
|
Log.d(TAG, "registered configuration receiver");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispatchSystemServerContext(IBinder activityThread, IBinder activityToken) {
|
public void dispatchSystemServerContext(IBinder activityThread, IBinder activityToken) {
|
||||||
Log.d(TAG, "received system context");
|
Log.d(TAG, "received system context");
|
||||||
ActivityManagerService.onSystemServerContext(IApplicationThread.Stub.asInterface(activityThread), activityToken);
|
ActivityManagerService.onSystemServerContext(IApplicationThread.Stub.asInterface(activityThread), activityToken);
|
||||||
registerPackageReceiver();
|
registerPackageReceiver();
|
||||||
registerUnlockReceiver();
|
registerUnlockReceiver();
|
||||||
|
registerConfigurationReceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ public class ServiceManager {
|
||||||
waitSystemService(Context.USER_SERVICE);
|
waitSystemService(Context.USER_SERVICE);
|
||||||
waitSystemService(Context.APP_OPS_SERVICE);
|
waitSystemService(Context.APP_OPS_SERVICE);
|
||||||
|
|
||||||
ConfigFileManager.reloadLocale();
|
ConfigFileManager.reloadConfiguration();
|
||||||
|
|
||||||
BridgeService.send(mainService, new BridgeService.Listener() {
|
BridgeService.send(mainService, new BridgeService.Listener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import android.content.IIntentReceiver;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
|
@ -104,6 +105,8 @@ public interface IActivityManager extends IInterface {
|
||||||
ContentProviderHolder getContentProviderExternal(String name, int userId,
|
ContentProviderHolder getContentProviderExternal(String name, int userId,
|
||||||
IBinder token);
|
IBinder token);
|
||||||
|
|
||||||
|
Configuration getConfiguration() throws RemoteException;
|
||||||
|
|
||||||
abstract class Stub extends Binder implements IActivityManager {
|
abstract class Stub extends Binder implements IActivityManager {
|
||||||
public static int TRANSACTION_setActivityController;
|
public static int TRANSACTION_setActivityController;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue