Launcher Package变化监听机制(二)

上一篇介绍了当安装应用的时候在桌面和菜单中生成图标的流程,但还是没有找到源头.那么就在源码中继续寻找答案.

LauncherModel实现了LauncherAppsCompat.OnAppsChangedCallbackCompat

1
2
3
4
5
6
7
8
9
code path: android/packages/apps/Launcher3/src/com/android/launcher3/compat/LauncherAppsCompat.java

public interface OnAppsChangedCallbackCompat {
void onPackageRemoved(String packageName, UserHandleCompat user);
void onPackageAdded(String packageName, UserHandleCompat user);
void onPackageChanged(String packageName, UserHandleCompat user);
void onPackagesAvailable(String[] packageNames, UserHandleCompat user, boolean replacing);
void onPackagesUnavailable(String[] packageNames, UserHandleCompat user, boolean replacing);
}

该接口声明了对package变化的一系列操作,LauncherModler是其具体实现。查看LauncherAppsCompat.OnAppsChangedCallbackCompat的调用,发现在LauncherAppsCompatVL的静态内部类WrappedCallback中有使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
code path: android/packages/apps/Launcher3/src/com/android/launcher3/compat/LauncherAppsCompatVL.java

private static class WrappedCallback extends LauncherApps.Callback {
private LauncherAppsCompat.OnAppsChangedCallbackCompat mCallback;

public WrappedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
mCallback = callback;
}

public void onPackageRemoved(String packageName, UserHandle user) {
mCallback.onPackageRemoved(packageName, UserHandleCompat.fromUser(user));
}

public void onPackageAdded(String packageName, UserHandle user) {
mCallback.onPackageAdded(packageName, UserHandleCompat.fromUser(user));
}

public void onPackageChanged(String packageName, UserHandle user) {
mCallback.onPackageChanged(packageName, UserHandleCompat.fromUser(user));
}

public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
mCallback.onPackagesAvailable(packageNames, UserHandleCompat.fromUser(user), replacing);
}

public void onPackagesUnavailable(String[] packageNames, UserHandle user,
boolean replacing)
{

mCallback.onPackagesUnavailable(packageNames, UserHandleCompat.fromUser(user),
replacing);
}
}

在这里又看到了熟悉的方法,从方法名上可以知道也是对于package变化的一系列调用.层层回调…看到这里依然没有找到源头,继续追踪,WrappedCallback在LauncherAppsCompatVL.java的addOnAppsChangedCallback中有使用到:

1
2
3
4
5
6
7
public void addOnAppsChangedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
WrappedCallback wrappedCallback = new WrappedCallback(callback);
synchronized (mCallbacks) {
mCallbacks.put(callback, wrappedCallback);
}
mLauncherApps.registerCallback(wrappedCallback);
}

该方法中接收的callback就是LauncherModel,代码在LauncherAppState.java的构造函数中:

1
LauncherAppsCompat.getInstance(sContext).addOnAppsChangedCallback(mModel);

看到这里出现了一句比较重要的的代码,mLauncherApps.registerCallback(wrappedCallback);
这里的mLauncherApps是什么鬼?它在这里注册了监听回调;在LauncherAppsCompatVL.java的构造函数中对mLauncherApps进行了初始化,代码如下:

1
2
3
4
LauncherAppsCompatVL(Context context) {
super();
mLauncherApps = (LauncherApps) context.getSystemService("launcherapps");
}​

mLauncherApps貌似是个系统服务,继续查看源头:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
code path:frameworks/base/core/java/android/content/pm
public void registerCallback(Callback callback, Handler handler) {
synchronized (this) {
if (callback != null && findCallbackLocked(callback) < 0) {
boolean addedFirstCallback = mCallbacks.size() == 0;
addCallbackLocked(callback, handler);
if (addedFirstCallback) {
try {
mService.addOnAppsChangedListener(mAppsChangedListener);
} catch (RemoteException re) {
}
}
}
}
}

通过一个mService添加了一个Listener,之后就是传递到Launcher的层层回调。那这里的mService又是什么呢?在LauncherApps.java的构造函数中进行了初始化

1
2
3
4
5
public LauncherApps(Context context, ILauncherApps service) {
mContext = context;
mService = service;
mPm = context.getPackageManager();
}

这里的service是ILauncherApps

1
2
3
4
5
6
7
8
9
10
11
12
13
code path: frameworks/base/core/java/android/content/pm/ILauncherApps.aidl
interface ILauncherApps {
void addOnAppsChangedListener(in IOnAppsChangedListener listener);
void removeOnAppsChangedListener(in IOnAppsChangedListener listener);
List<ResolveInfo> getLauncherActivities(String packageName, in UserHandle user);
ResolveInfo resolveActivity(in Intent intent, in UserHandle user);
void startActivityAsUser(in ComponentName component, in Rect sourceBounds,
in Bundle opts, in UserHandle user)
;

void showAppDetailsAsUser(in ComponentName component, in Rect sourceBounds,
in Bundle opts, in UserHandle user)
;

boolean isPackageEnabled(String packageName, in UserHandle user);
boolean isActivityEnabled(in ComponentName component, in UserHandle user);
}

看到有addOnAppsChangedListener,removeOnAppsChangedListener(其他暂不关注),通过名字可以知道这两个方法就是package监听器,ILauncherApps.aidl的具体实现是在LauncherAppsService.java的内部类LauncherAppsImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
code path:frameworks/base/services/core/java/com/android/server/pm/LauncherAppsService.java
public void addOnAppsChangedListener(IOnAppsChangedListener listener) throws RemoteException {
synchronized (mListeners) {
if (DEBUG) {
Log.d(TAG, "Adding listener from " + Binder.getCallingUserHandle());
}
if (mListeners.getRegisteredCallbackCount() == 0) {
if (DEBUG) {
Log.d(TAG, "Starting package monitoring");
}
startWatchingPackageBroadcasts();
}
mListeners.unregister(listener);
mListeners.register(listener, Binder.getCallingUserHandle());
}
}

判断当前的callback==0时就会调用startWatchingPackageBroadcasts(),从方法上看像启动广播监听

1
2
3
private void startWatchingPackageBroadcasts() {
mPackageMonitor.register(mContext, null, UserHandle.ALL, true);
}

mPackageMonitor是LauncherAppsImpl的内部类,继承PackageMonitor,PackageMonitor又继承BroadcastReceiver,所以这鬼东西是个广播,mPackageMonitor调用父类的register方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
code path: frameworks/base/core/java/com/android/internal/content/PackageMonitor.java
static {
sPackageFilt.addAction(Intent.ACTION_PACKAGE_ADDED);
sPackageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED);
sPackageFilt.addAction(Intent.ACTION_PACKAGE_CHANGED);
sPackageFilt.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
sPackageFilt.addAction(Intent.ACTION_PACKAGE_RESTARTED);
sPackageFilt.addDataScheme("package");
sNonDataFilt.addAction(Intent.ACTION_UID_REMOVED);
sNonDataFilt.addAction(Intent.ACTION_USER_STOPPED);
sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
}

public void register(Context context, Looper thread, UserHandle user,
boolean externalStorage) {
if (mRegisteredContext != null) {
throw new IllegalStateException("Already registered");
}
mRegisteredContext = context;
if (thread == null) {
mRegisteredHandler = BackgroundThread.getHandler();
} else {
mRegisteredHandler = new Handler(thread);
}
if (user != null) {
context.registerReceiverAsUser(this, user, sPackageFilt, null, mRegisteredHandler);
context.registerReceiverAsUser(this, user, sNonDataFilt, null, mRegisteredHandler);
if (externalStorage) {
context.registerReceiverAsUser(this, user, sExternalFilt, null,
mRegisteredHandler);
}
} else {
context.registerReceiver(this, sPackageFilt, null, mRegisteredHandler);
context.registerReceiver(this, sNonDataFilt, null, mRegisteredHandler);
if (externalStorage) {
context.registerReceiver(this, sExternalFilt, null, mRegisteredHandler);
}
}
}

看到这里就水落石出了,这里定义了广播过滤器,并且监听不同的用户。
监听到广播后肯定要有对应的处理,我们回到LauncherAppsImpl的addOnAppsChangedListener方法,这里传入了一个IOnAppsChangedListener的listener,参数也是个AIDL的接口,代码路径

1
2
3
4
5
6
7
8
code path: frameworks/base/core/java/android/content/pm/IOnAppsChangedListener.aidl
oneway interface IOnAppsChangedListener {
void onPackageRemoved(in UserHandle user, String packageName);
void onPackageAdded(in UserHandle user, String packageName);
void onPackageChanged(in UserHandle user, String packageName);
void onPackagesAvailable(in UserHandle user, in String[] packageNames, boolean replacing);
void onPackagesUnavailable(in UserHandle user, in String[] packageNames, boolean replacing);
}

使用oneway关键字定义的接口,这就表明它的所有方法都采用非阻塞式方式。该接口的具体实现是在LauncherApps.java中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
private IOnAppsChangedListener.Stub mAppsChangedListener = new IOnAppsChangedListener.Stub() {

@Override
public void onPackageRemoved(UserHandle user, String packageName)
throws RemoteException {

if (DEBUG) {
Log.d(TAG, "onPackageRemoved " + user.getIdentifier() + "," + packageName);
}
synchronized (LauncherApps.this) {
for (CallbackMessageHandler callback : mCallbacks) {
callback.postOnPackageRemoved(packageName, user);
}
}
}

@Override
public void onPackageChanged(UserHandle user, String packageName) throws RemoteException {
if (DEBUG) {
Log.d(TAG, "onPackageChanged " + user.getIdentifier() + "," + packageName);
}
synchronized (LauncherApps.this) {
for (CallbackMessageHandler callback : mCallbacks) {
callback.postOnPackageChanged(packageName, user);
}
}
}

@Override
public void onPackageAdded(UserHandle user, String packageName) throws RemoteException {
if (DEBUG) {
Log.d(TAG, "onPackageAdded " + user.getIdentifier() + "," + packageName);
}
synchronized (LauncherApps.this) {
for (CallbackMessageHandler callback : mCallbacks) {
callback.postOnPackageAdded(packageName, user);
}
}
}

@Override
public void onPackagesAvailable(UserHandle user, String[] packageNames, boolean replacing)
throws RemoteException {

if (DEBUG) {
Log.d(TAG, "onPackagesAvailable " + user.getIdentifier() + "," + packageNames);
}
synchronized (LauncherApps.this) {
for (CallbackMessageHandler callback : mCallbacks) {
callback.postOnPackagesAvailable(packageNames, user, replacing);
}
}
}

@Override
public void onPackagesUnavailable(UserHandle user, String[] packageNames, boolean replacing)
throws RemoteException {

if (DEBUG) {
Log.d(TAG, "onPackagesUnavailable " + user.getIdentifier() + "," + packageNames);
}
synchronized (LauncherApps.this) {
for (CallbackMessageHandler callback : mCallbacks) {
callback.postOnPackagesUnavailable(packageNames, user, replacing);
}
}
}
};

这里就以接收到新增应用的广播,调用到onPackageAdded方法,可以看到循环遍历callback之后调用callback的postOnPackageAdded方法处理,callback是CallbackMessageHandler,继承Handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
private static class CallbackMessageHandler extends Handler {
private static final int MSG_ADDED = 1;
private static final int MSG_REMOVED = 2;
private static final int MSG_CHANGED = 3;
private static final int MSG_AVAILABLE = 4;
private static final int MSG_UNAVAILABLE = 5;

private LauncherApps.Callback mCallback;

private static class CallbackInfo {
String[] packageNames;
String packageName;
boolean replacing;
UserHandle user;
}

public CallbackMessageHandler(Looper looper, LauncherApps.Callback callback) {
super(looper, null, true);
mCallback = callback;
}

@Override
public void handleMessage(Message msg) {
if (mCallback == null || !(msg.obj instanceof CallbackInfo)) {
return;
}
CallbackInfo info = (CallbackInfo) msg.obj;
switch (msg.what) {
case MSG_ADDED:
Log.d("hu", "LauncherApps handleMessage: onPackageAdded run");
mCallback.onPackageAdded(info.packageName, info.user);
break;
case MSG_REMOVED:
mCallback.onPackageRemoved(info.packageName, info.user);
break;
case MSG_CHANGED:
mCallback.onPackageChanged(info.packageName, info.user);
break;
case MSG_AVAILABLE:
mCallback.onPackagesAvailable(info.packageNames, info.user, info.replacing);
break;
case MSG_UNAVAILABLE:
mCallback.onPackagesUnavailable(info.packageNames, info.user, info.replacing);
break;
}
}

public void postOnPackageAdded(String packageName, UserHandle user) {
CallbackInfo info = new CallbackInfo();
info.packageName = packageName;
info.user = user;
obtainMessage(MSG_ADDED, info).sendToTarget();
}

public void postOnPackageRemoved(String packageName, UserHandle user) {
CallbackInfo info = new CallbackInfo();
info.packageName = packageName;
info.user = user;
obtainMessage(MSG_REMOVED, info).sendToTarget();
}

public void postOnPackageChanged(String packageName, UserHandle user) {
CallbackInfo info = new CallbackInfo();
info.packageName = packageName;
info.user = user;
obtainMessage(MSG_CHANGED, info).sendToTarget();
}

public void postOnPackagesAvailable(String[] packageNames, UserHandle user,
boolean replacing)
{

CallbackInfo info = new CallbackInfo();
info.packageNames = packageNames;
info.replacing = replacing;
info.user = user;
obtainMessage(MSG_AVAILABLE, info).sendToTarget();
}

public void postOnPackagesUnavailable(String[] packageNames, UserHandle user,
boolean replacing)
{

CallbackInfo info = new CallbackInfo();
info.packageNames = packageNames;
info.replacing = replacing;
info.user = user;
obtainMessage(MSG_UNAVAILABLE, info).sendToTarget();
}
}

这就是处理具体操作的根源。查看哪里又调用了CallbackMessageHandler

1
2
3
4
5
6
7
8
9
private void addCallbackLocked(Callback callback, Handler handler) {
// Remove if already present.
removeCallbackLocked(callback);
if (handler == null) {
handler = new Handler();
}
CallbackMessageHandler toAdd = new CallbackMessageHandler(handler.getLooper(), callback);
mCallbacks.add(toAdd);
}

registerCallback又调用了addCallbackLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void registerCallback(Callback callback, Handler handler) {
synchronized (this) {
if (callback != null && findCallbackLocked(callback) < 0) {
boolean addedFirstCallback = mCallbacks.size() == 0;
addCallbackLocked(callback, handler);
if (addedFirstCallback) {
try {
mService.addOnAppsChangedListener(mAppsChangedListener);
} catch (RemoteException re) {
}
}
}
}
}

之后Launcher中LauncherAppsCompatVL又通过addOnAppsChangedCallback调用

1
2
3
4
5
6
7
public void addOnAppsChangedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
WrappedCallback wrappedCallback = new WrappedCallback(callback);
synchronized (mCallbacks) {
mCallbacks.put(callback, wrappedCallback);
}
mLauncherApps.registerCallback(wrappedCallback);
}

最后一切就都串起来了。

听说打赏的人运气都不会太差